# Using and Maintaining GNU Pascal

@emergencystretch 10em@hfuzz 5pt@vfuzz@hfuzz

Using and Maintaining GNU Pascal

Jan-Jaap van der Heijden,

Peter Gerwinski,

Frank Heckenbach

Last updated May 2000

for version 20000527 (GCC version 2.95.x) Copyright (C) 1988, 1996-2000 Free Software Foundation, Inc.

For GPC version 20000527 (GCC version 2.95.x)

Published by the Free Software Foundation
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled "GNU General Public License", "The GNU Manifesto" and "Funding for Free Software" are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the sections entitled "GNU General Public License", "The GNU Manifesto" and "Funding for Free Software" and this permission notice, may be included in translations approved by the Free Software Foundation instead of in the original English.

# Welcome to GNU Pascal...

... the free 32/64-bit Pascal compiler of the GNU compiler family, GNU CC or GCC. It combines a Pascal front-end with the proven GNU C back-end for code generation and optimization. Other compilers of the family currently include compilers for the Ada, C, C++, Objective C, and FORTRAN languages. Unlike utilities such as p2c, this is a true compiler, not just a converter.

This version of GPC corresponds to GCC version 2.95.x.

The purpose of the GNU Pascal project is to produce a Pascal compiler (called GNU Pascal or GPC) which

- combines the clarity of Pascal with powerful tools suitable for real-life programming,
- supports both the Pascal standard and the Extended Pascal standard as defined by ISO, ANSI and IEEE (ISO 7185:1990, ISO/IEC 10206:1991, ANSI/IEEE 770X3.160-1989),
- supports other Pascal standards (UCSD Pascal, Borland Pascal, Pascal-SC) in so far as this serves the goal of clarity and usability,
- may be distributed under GNU license conditions, and
- can generate code for and run on any computer for which the GNU C compiler can generate code and run on.

Pascal was originally designed for teaching. GNU Pascal provides a smooth way to proceed to challenging programming tasks without learning a completely different language.

The current release implements Standard Pascal (ISO 7185, level 1), a large subset of Extended Pascal (ISO 10206, aiming for full compliance), is highly compatible to Borland Pascal (version 7.0) with some Delphi extensions, and provides a lot of useful GNU extensions.

This documentation contains

- installation instructions, see section Installing GNU Pascal,
- a list of new features since the last release, see section New Features of GNU Pascal,
- information on how to report bugs in GNU Pascal and how to get support, see section Where to get support for GNU Pascal; how to report bugs,
- a list of contributors which tells you who devloped and is maintaining GNU Pascal, see section Contributors to GNU Pascal,
- the GNU General Public License which informs you about your rights and responsibilites when using, modifying and distributing GNU Pascal, see section GNU GENERAL PUBLIC LICENSE,
- other texts about Free Software and the GNU Project intended to answer questions like "what is GNU?" you might have in mind now, see section The GNU Manifesto, and section Funding Free Software,
- and the current version of a "GNU Pascal manual" intended to describe how to use the compiler.

If you are familiar with Standard Pascal (ISO 7185) programming, you can probably just go ahead and try to compile your programs. Also, most of the ISO Extended Pascal Standard (ISO 10206) is implemented into GNU Pascal. The Extended Pascal features still missing from GPC are `qualified` module import, `protected` module export variables, set types with variable bounds, structured value initializers and expressions as subrange lower bounds.

If you are a Borland Pascal programmer, you should probably start reading the QuickStart guide from BP to GNU Pascal, see section From Borland Pascal to GNU Pascal. If you are curious about the new features GPC offers, you can read about them in the Programmer's Guide to GPC (see section The Programmer's Guide to GPC) and in the alphabetical GPC Language Reference (see section The Alphabetical GPC Language Reference).

And, please, think about how you can contribute to the GNU Pascal project, too. Please support our work by contributing yours in form of example programs, bug reports, documentation, or even actual improvements of the compiler.

You can find the current To-Do list on the GPC home page in the WWW at

    @uref{http://agnes.dida.physik.uni-essen.de/~gnu-pascal/todo.html}.

# Installing GNU Pascal

This chapter covers:

- Compilation of the source distribution on a UNIX system
- Configuration dependent compilation notes
- Building and installing a cross-compiler
- Installation instructions for a GPC binary distribution

The preferred way to distribute GNU software is distribution of the source code. However, it can be a non-trivial exercise to build GNU Pascal on some non-UNIX systems, so we also provide ready-to-run binaries for a number of platforms. See section Installation instructions for a GPC binary distribution how to install a binary distribution.

GPC is based on GNU CC; you will need the GCC sources to build it. It must be the same version as the one GPC is implemented with. Although you need GCC to build the GNU Pascal compiler, you don't need GCC to compile Pascal programs once GNU Pascal is installed. Because GNU Pascal shares its backend with GNU CC, it should run on any system supported by GNU CC. A full list of platforms supported by GNU CC can be found in section `Installation' in "Using and Porting GNU CC".

Here is the generic procedure for installing GNU Pascal on a UNIX system. See section Configuration dependent compilation notes for extra information needed to install GPC on certain platforms.

1. Unpack the source distributions. From a directory of your choice (e.g. ``/usr/local/src'`), unpack the GNU CC and GNU Pascal source distributions. This will create separate subdirectories for GCC and GPC. ``cd'` to the GPC directory (``/usr/local/src/gpc'` in the example above) and move the contents (a subdirectory ``p'`) to the GCC directory (for instance ``usr/local/src/gcc-2.8.1'`). Next, go to the GCC source directory and apply the GCC patch required by GNU Pascal:

       % patch -s -p1 < p/diffs/gcc-2.8.1.diff

   Note 1: If you omit this step, ``configure'` (see below) will prompt you for doing this automatically. Note 2: In the example above, GCC version 2.8.1 is assumed. If your version of GCC is other than 2.8.1, you have to get and apply the appropriate patch. If you run the patch automatically from ``configure'`, it will detect and work with some versions of EGCS. Note 3: All changes to GCC are surrounded by ``#ifdef GPC .. #endif'`, so they should not interfere when you build a C compiler from this source tree. It is possible, though not required, to build the compiler in a directory other than the one containing the sources. (If you do that, you do not need to write into the GCC source directory and can build GPC for more than one platform from the same source tree.) In that case, you need a ``make'` that understands the VPATH variable. GNU make does, although at least GNU make version 3.71 has a bug in the way it treats VPATH. GNU make version 3.75 is known to work. If you have built GNU Pascal previously in the same directory for a different target machine, do ``make distclean'` to delete all files that might be invalid. One of the files this deletes is ``Makefile'`; if ``make distclean'` complains that ``Makefile'` does not exist, it probably means that the directory is already suitably clean.
2. Configuring and building GNU CC GNU Pascal is automatically configured with GNU CC. Configuration of GNU CC is treated in depth in section `Chapter 4' in "Using and Porting GNU CC". Chdir to the GCC object directory. (This can be a directory of your choice, including the GCC source directory.) From there, run the ``configure'` script in the GCC source directory. If both directories are the same, the command

       % ./configure

   is sufficient to configure GCC in most cases. If they are different, something like

       % ../gcc-2.8.1/configure

   will do the job. This creates all the necessary config files, links and Makefile in the GCC object directory.
3. The standard directory for installing GNU CC and GNU Pascal is ``/usr/local/lib'`. If you want to install its files somewhere else, specify ``--prefix=dir'` when you run ``configure'`. Here dir is a directory name to use instead of ``/usr/local'` for all purposes with one exception: the directory ``/usr/local/include'` is searched for header files no matter where you install the compiler. To override this name, use the ``--local-prefix'` option below.
4. Specify ``--local-prefix=dir'` if you want the compiler to search directory ``dir/include'` for locally installed header files instead of ``/usr/local/include'`. You should specify ``--local-prefix'` only if your site has a different convention (not ``/usr/local'`) for where to put site-specific files. Do not specify ``/usr'` as the ``--local-prefix'`! The directory you use for ``--local-prefix'` must not contain any of the system's standard header files. If it did contain them, certain programs would be miscompiled (including GNU Emacs, on certain targets), because this would override and nullify the header file corrections made by the `fixincludes` script.
5. Make sure the Bison parser generator is installed. (This is unnecessary if the Bison output files ``c-parse.c'`, ``cexp.c'`, ``p/parse.c'`, and ``p/parse.h'` are more recent than ``c-parse.y'`, ``cexp.y'`, and ``p/parse.y'` and you do not plan to change the ``.y'` files.) Bison versions older than Sept 8, 1988 will produce incorrect output for ``c-parse.c'`.
6. If you have chosen a configuration for GNU Pascal which requires other GNU tools (such as GAS or the GNU linker) instead of the standard system tools, install the required tools in the build directory under the names ``as'`, ``ld'` or whatever is appropriate. This will enable the compiler to find the proper tools for compilation of the program ``enquire'`. Alternatively, you can do subsequent compilation using a value of the `PATH` environment variable such that the necessary GNU tools come before the standard system tools.
7. Once you are satisfied with the configuration as determined by ``configure'`, you can build the Pascal compiler:

       % make LANGUAGES=pascal

   (Just ``make'` would also build the C++ and Objective C compilers). Notice that this procedure will build the C compiler too, because that is used to compile the GPC runtime library. Optionally, you may supply CFLAGS, LDFLAGS or RTSFLAGS. CFLAGS is used for compiler and RTS, RTSFLAGS are for RTS only, i.e.: ``make CFLAGS="-O2" RTSFLAGS=-Wall'`
8. When everything compiles, you can verify what the ``make -n pascal.install'` command does, and if you are satisfied run it without the ``-n'` option to install the compiler ``gpc1'`, front end ``gpc'`, run time system ``libgpc.a'` to the same place where ``gcc'` was installed. This installation process does not overwrite existing copies of ``libgcc.a'` or ``specs'`, should they exist. You can also install GPC as part of the complete GNU compiler suite using "make install" as described in the GCC installation docs.

## Configuration dependent compilation notes

### MS-DOS with DJGPP

You cannot build GNU CC (or GNU Pascal) by itself on MS-DOS or a compatible system; it will not compile under any MS-DOS compiler except itself. The official MS-DOS port of GCC is called DJGPP, and it is available from ``simtel.coast.net'` and it has mirrors all over the world. The ``configure'` script is replaced by an MS-DOS batch file called ``configure.bat'` wich does essentially the same. Detailed instructions are in the file ``config/msdos/README.dj'` of the GNU Pascal source distribution.

### MS-DOS or OS/2 with EMX

EMX is a free 32-bit DOS extender which adds some properties of UNIX to MS-compatible DOS and IBM's OS/2 operating systems. You can find it, for example, via anonymous ``ftp'` on the server ``ftp.uni-stuttgart.de'` in the directory ``pub/systems/os2/emx*'`.

Due to the limitation of the command line to 128 characters we don't know a way to compile GPC for EMX under DOS; you need OS/2 instead. If you succeed to compile GPC for EMX on a DOS system, please let us know. (However you can compile GPC for DJGPP on a DOS system.)

To compile under OS/2 you need EMX 0.9d and the patched source files for GCC 2.8.1. The sources assume that the system will be compiled on an HPFS filesystem although the Makefiles can be easily modified for FAT16. The GCC backend requires dmake 3.8 to compile whereas the GPC parts of the systems are compiled with GNU Make 3.7 or later.

1. Unzip the source for GCC from the root directory, and rename the resulting directory ``gcc-2.8'` to ``gpc'`.

         cd \
         unzip c:\gccsrc1
         unzip c:\gccsrc2
         unzip c:\gccsrc3
         ren \emx\gnu\gcc-2.8 gpc

2. Unpack the source for GPC from the ``emx\gnu'` directory, so it will go into the gpc subdirectory. Unlike other EMX sources, the GPC source must not be extracted from the root directory.

         cd \emx\gnu
         unzip c:\gpc-21s.zip

3. If you are working on a drive different from ``d:'` and/or if you want to compile the compiler with optimization and/or without debugging information (recommended), edit ``\emx\gnu\gpc\dostage1.cmd'` to refer to your drive and to have the ``CFLAGS'` you want, e.g. ``CFLAGS="-g -O2"'` instead of ``CFLAGS=-g'`.
4. You will also want to apply the patches for gcc. To do this you will need GNU Patch (also known as Larry Wall's Patch), which should be available from the normal OS/2 ``ftp'` archives, e.g. ``hobbes.nmsu.edu'` in the ``/pub/os2/unix/dev'` directory. Make sure you rename ``patch.exe'` to a filename that won't conflict with the built in OS/2 ``patch'` command. EM recommends using ``lwpatch.exe'` in his ``\emx\doc\build.doc'` file. Apply the diff:

         cd \emx\gnu\gpc
         set emxopt=-t
         lwpatch --prefix=~ < p\diffs\gcc-2.8.1.diff
         set emxopt=

5. Compile GPC using the ``compile.cmd'` script.

         cd \emx\gnu\gpc\p
         compile

6. To install, move the GPC files into place.

         cd \emx\gnu\gpc
         copy gpc*.exe \emx\bin
         copy gpc.a \emx\lib

### Windows NT and Windows 95 with cygwin32

cygwin32 is a project to make it easy to port UNIX applications to machines which run an OS which supports the Win32 API--i.e. Microsoft Windows 95 and Windows NT. Currently, cygwin32 is in beta stage; it is available from ``ftp://ftp.cygnus.com/pub/gnu-win32/'` Don't use gcc sources from the cygwin32 distribution. These are not just modified from FSF ``gcc-2.8.1'` to support the Windows 95/NT target, they are the "current development release", and too different from FSF GCC to be compatible with GNU Pascal, which is based on FSF sources.

Currently, cygwin32 is not self-hosting: the preferred way to build the cygwin32-gpc binary is to use a UNIX system with a cygwin32 targeting cross-compiler. See section Crossbuilding a compiler.

## Building and Installing a cross-compiler

GNU Pascal can function as a cross-compiler for many machines, but not all. Also, only a few combinations have been tested. If you need information about GNU tools in a cross-configuration, ``ftp://ftp.cygnus.com/pub/embedded/crossgcc/'` is the place to be.

- Cross-compilers for the Mips as target using the Mips assembler currently do not work, because the auxiliary programs ``mips-tdump.c'` and ``mips-tfile.c'` can't be compiled on anything but a Mips. It does work to cross compile for a Mips if you use the GNU assembler and linker.
- Cross-compilers between machines with different floating point formats have not all been made to work. GNU C now has a floating point emulator with which these can work, but each target machine description needs to be updated to take advantage of it.
- Cross-compilation between machines of different word sizes is somewhat problematic and sometimes does not work.

Since GNU Pascal generates assembler code, you probably need a cross-assembler that GNU Pascal can run, in order to produce object files. If you want to link on other than the target machine, you need a cross-linker as well. You also need header files and libraries suitable for the target machine that you can install on the host machine.

### Steps of Cross-Compilation

To compile and run a program using a cross-compiler involves several steps:

- Run the cross-compiler on the host machine to produce assembler files for the target machine. This requires header files for the target machine.
- Assemble the files produced by the cross-compiler. You can do this either with an assembler on the target machine, or with a cross-assembler on the host machine.
- Link those files to make an executable. You can do this either with a linker on the target machine, or with a cross-linker on the host machine. Whichever machine you use, you need libraries and certain startup files (typically ``crt....o'`) for the target machine.

It is most convenient to do all of these steps on the same host machine, since then you can do it all with a single invocation of GNU Pascal. This requires a suitable cross-assembler and cross-linker. For some targets, the GNU assembler and linker are available.

### Configuring GNU CC as a cross-compiler

No special actions have to be taken to configure GNU Pascal as a cross-compiler. Cross-compiler specific configuration is done only for GCC. Section 4.2 of "Using and Porting GNU CC" deals with cross-configurations in great detail. Once cross-binutils and a C library for the target machine are in place, GCC can be configured (from the GCC object directory). Suppose we are on a FreeBSD system and want a cross-compiler that produces code that runs on MS-DOS:

    % ../gcc-2.8.1/configure --prefix=/usr --target=i386-go32

This creates all the necessary config files, links and Makefile in the GCC object directory. Now, proceed with the compilation and installation process like in the case of the native configuration described before. Do not remove files from the GCC object directory; the cross-compiler is used to compile the GNU Pascal runtime system (RTS) for the target system.

### Building the Pascal cross-compiler

Once you have verified the C cross-compiler, the Pascal cross-compiler can be configured and built. Note that the ``configure'` script does not require any cross-compiler related switches because GPC inherits all of this from GNU CC.

Sample output for a FreeBSD->msdos cross configuration:

    --------------------------------------------------------------------------
    Configuration summary:
      Building a i386-go32 cross-compiler hosted by i386-unknown-freebsd2.1.0

      GPC sources in:         ../gpc-2.0
      GCC sources in:         ../gcc-2.8.1
      GCC object code in:     ../gcc
      GCC version:            2.8.1

      Compiler for GPC:       gcc
      Compiler for libgpc.a:  i386-go32-gcc
      Compiler flags:         -g -O

      Cross-ar utility:       i386-go32-ar
      Cross-ranlib utility:   i386-go32-ranlib

      Installation path:      /usr/bin, /usr/lib/gcc-lib/i386-go32/2.8.1
    --------------------------------------------------------------------------

    Now, type `make' to build the compiler and runtime system.

Building a cross-compiler requires cross-binutils for your target, i386-go32 in this examples. If ``configure'` is not able to find ``i386-go32-ar'` and/or ``i386-go32-ranlib'`, you may have to run it again with again with `--with-ar=your-cross-ar` or `--with-ranlib=your-cross-ranlib` switches.

Then, ``make'` and ``make install'` the cross-compiler like you would for a native configuration.

### Crossbuilding a compiler.

Yet another possibility is crossbuilding : Using a cross-compiler to build GNU Pascal results in a compiler binary that runs on the cross-target platform. A possible reason why anybody would want to do this, is when the platform on which you want to run the GNU Pascal compiler, is not self-hosting. An example is cygwin32.

To crossbuild GNU Pascal, you have to install a cross-compiler for your target first. This is covered in chapter 4 of "Using and Porting GNU CC". Assuming you want to build a native cygwin32 Pascal compiler on a FreeBSD system, configure GCC:

    % ../gcc-2.8.1/configure --prefix=/usr --build=i386-freebsd \
    	--host=i386-cygwin32 --target=i386-cygwin32

Build it:

    % make CFLAGS=-O2 LANGUAGES=c

Now, configure and build GPC. The output of ``configure'` should look like:

    --------------------------------------------------------------------------
    Configuration summary:
      Building a i386-cygwin32 cross-compiler hosted by i386-cygwin32

      GPC sources in:         ../gpc-2.0
      GCC sources in:         ../gcc-2.8.1
      GCC object code in:     ../gcc
      GCC version:            2.8.1

      Compiler for GPC:       i386-cygwin32-gcc
      Compiler for libgpc.a:  i386-cygwin32-gcc
      Compiler flags:         -g -O

      Cross-ar utility:       i386-cygwin32-ar
      Cross-ranlib utility:   i386-cygwin32-ranlib

      Installation path:      /usr/bin, /usr/lib/gcc-lib/i386-cygwin32/2.8.1
    --------------------------------------------------------------------------

    Now, type `make' to build the compiler and runtime system.

Again, ``configure'` should be able to detect and configure this setup without additional flags. If not, specify ``--with-ar'`, ``--with-ranlib'`, ``--with-gcc'` and/or ``--with-rtsgcc'` as appropriate.

A cross-built compiler must be installed by hand.

## Installation instructions for a GPC binary distribution

To install a binary distribution, cd to the main directory and unpack the archive while preserving the stored directory structure. In concrete, to install a ZIP archive under DOS with PKunzip, ``cd'` the the appropriate directory (usually ``\'` for EMX, ``\DJGPP'` for DJGPP), then type

      C:\> pkunzip -d archive

where archive is the name of the distribution file. To install a ``.tar.gz'` archive under a UNIX compatible system, become root, then extract the archive from the root of the filesystem:

      # tar xzf archive.tar.gz

If you are using a ``tar'` utility other than GNU tar, it might be necessary to do the above in two steps:

      # gzip -d archive.tar.gz
      # tar xf archive.tar

Binary distributions include ``libgcc.a'` and ``specs'`, files that are normally part of GCC. If you have GCC installed, they will be replaced unless you manually install the archive.

# New Features of GNU Pascal

## General Changes Since The Previous Beta Release

There's a large number of bug fixes, too many to mention here. They are listed in the ``Fixed Bugs'` section of the GPC To-Do list @uref{http://agnes.dida.physik.uni-essen.de/~gnu-pascal/todo.html}. The most important bugs fixed include the unit/module initialization in the wrong order, and not working at all on some systems, the global goto bug, some "two-unit bugs" and a number of BP compatibility issues.

There's a number of new or changed features which are listed in the following. Features without further description refer to new routines or options.

This release of GPC has been cleaned up substantially. Consequently, a few old and obsolete features have been dropped or replaced by clearer, more flexible or otherwise more useful ones. This might lead to minor problems with old programs, but we suppose they're very rare (many programmers might not even know about the old features) and easy to overcome. The most important ones are listed here, the rest of them is contained in the following sections and marked with ``(@)'`.

- ``asmname'` in variable and constant declarations must now come after the type (e.g. ``var foo : Integer = 42; asmname 'bar' '`). Furthermore, ``asmname'` doesn't imply ``external'` anymore.
- The internal file handling in the RTS was changed from using ``FILE *'` pointers to integer file handles, to make it more efficient and to get rid of some problems. Accordingly, the ``CFile'` field in ``BindingType'` was replaced by a ``Handle'` field, the ``AssignCFile'` procedure by an ``AssignHandle'` procedure, and the ``GetFile'` function was removed (a substitute is the function ``FileHandle'` which has already existed in previous releases).
- The option ``--no-nested-comments'` (to allow comments like ``{ *)'` as the standard requires) has been renamed to ``--mixed-comments'` (note the inverted value). Accordingly, the compiler directives ``{$N+}'` and ``{$N-}'` have been renamed to ``{$no-mixed-comments}'` and ``{$mixed-comments}'`. The default, when no dialect options are given, is still ``--no-mixed-comments'` (i.e., what used to be ``--nested-comments'`).
- A new option ``--nested-comments'` to allow real nested comments like ``{ { } }'` (also available as a compiler switch, like almost all command-line options). Note the new meaning of this switch, so if you used it before, you'll probably have to change it to ``--no-mixed-comments'` (see above). If nested comments are enabled, comments are also allowed within compiler directives and macros (but no compiler directives within other compiler directives).
- C style character escapes (``\n'`, ``\007'` etc.) are now the default for strings enclosed in double quotes, while single quoted strings do not allow them (according to the standard). Accordingly, a verbatim ``"'` in a double quoted string is now obtained with ``\"'` rather than ``""'` (but a verbatim ``''` in a single quoted string still with ``"'`, of course). Therefore, the option ``--[no-]char-escapes'` and the compiler directive ``{$E+}'`/``{$E-}'` have been dropped. If you used these features, please change to the appropriate kind of quotes.
- Macros are no more expanded in ``--borland-pascal'` and ``--delphi'` modes. Expanding them causes a few problems with strange sources written for BP which use the same name for a conditional define and an identifier. Macros can be turned on/off independently from the dialect with the new switches ``--[no-]macros'`. (B)
- Macros and conditionals defined with ``{$define}'` are now case-insensitive (B). Macros and conditionals defined with ``--define'` on the command line are still case-sensitive for compatibility to other GNU compilers. In addition, GPC provides ``{$csdefine}'` or ``--csdefine'` and ``{$cidefine}'` or ``--cidefine'` to define case sensitive or insensitive macros or conditionals, respectively. If you have defined macros or conditionals with ``{$define}'` and rely on them being case-sensitive, change it to ``{$csdefine}'` now.
- The mechanism for including GPC code into code written in other languages has changed and is now more robust. A header gpc-in-c.h is provided for inclusion of GPC code into C programs, and a demo program GPC_C_Pas (together with C code calling it) is supplied to demonstrate this. (Including C code into GPC programs works as before.)
- The preprocessor is now called ``gpcpp'` (it was ``gpc-cpp'` before). If you have installed an older GPC version, please remove gpc-cpp now. If you have any scripts that refer to gpc-cpp directly, change the reference to gpcpp. If you use DJGPP, and you added the GPC specific sections to djgpp.env as described in the FAQ, please change ``[gpc-cpp]'` to ``[gpcpp]'`.

  ## Command Line Options and Compiler Directives

- ``{$ifopt}'` works now, with short directives like in BP (``{$ifopt X+}'`) (B) and also with long directives (``{$ifopt extended-syntax}'`)
- Local compiler directives and defines can be specified with ``{$local}'` and ``{$endlocal}'`.
- Delphi (or C++) style ``//'` comments in default and ``--delphi'` modes, and a switch ``--[no-]delphi-comments'` to turn them on/off explicitly. (D)
- -W[no-]typed-const (warn about BP style misuse of typed constants)
- -W[no-]near-far (warn about use of the obsolete BP compatible ``near'` and ``far'` directives)
- -W[no-]mixed-comments (warn about use of mixed comments)
- -W[no-]nested-comments (warn about use of nested comments)
- -W[no-]field-name-problem (don't warn about a problem with field names)
- -W[no-]warnings (enable/disable warnings)
- All ``-Wfoo'` warning options also work as ``{$W foo}'` compiler directives. In contrast to the last alpha release, there must now be a space after the ``W'`. (@)
- --no-default-paths (disable standard unit etc. paths)
- --no-unit-path, --no-object-path (disable any unit/object paths given so far)
- --[no-]io-checking (same as ``{$I+}'`, ``{$I-}'`)
- --[no-]stack-checking, also as compiler directives ``{$[no-]stack-checking}'` or ``{$S+}'`/``{$S-}'` (B)
- --[no-]typed-address, also as compiler directives ``{$[no-]typed-address}'` or ``{$T+}'`/``{$T-}'` (B)
- --[no-]transparent-file-names (derive the external file names from the file variable names
- --[no-]progress-messages, --[no-]progress-bar (output information to give progress messages or display a progress bar while compiling, using suitable utilities)
- {$[no-]debug-statement[=foo]} (call a procedure automatically before each statement for debugging)
- The ``--[no-]c-numbers'` switch has been removed. If you really used C style octal or hex numbers (``0400'`, ``0xf00'`), you can easily convert them to the Extended Pascal notation (``8#400'`, ``16#f00'`) or (hex only) to the Borland Pascal notation (``$foo'`). (@)
- ``{$gnu-pascal}'` is now completely equivalent to ``--gnu-pascal'`; ``{$gnu-pascal}'` has been added to all units shipped with GPC, so they can also be compiled when ``--borland-pascal'` or other dialect options are given on the command line.
- ``{$if}'` directives now understand Pascal operators like ``and'`, ``or'`, ``not'` (C operators are also still understood).
- ``{$P+}'`/``{$P-}'` was replaced by ``{$[no-]pedantic}'` (or ``--[no-]pedantic'` on the command line)
- The single-letter compiler directives are now BP compatible. Those that are not meaningful or not necessary in GPC (e.g. ``{$F+}'`, ``{$O...}'`, or ``{$M}'` with only numbers following) are ignored in ``--borland-pascal'` mode and warned about otherwise. (B) Note: ``{$W+}'`/``{$W-}'` is now also ignored in ``--borland-pascal'` mode (it is the only single-letter directive left that has a different meaning in BP and in GPC, and besides, the BP meaning can be safely ignored in GPC). To enable/disable warnings in ``--borland-pascal'` mode, you can use ``{$W [no-]warnings}'` now. (@)
- The RTS command line options are now also available as long options; new RTS options ``--version'` (print RTS version and exit), ``--abort-on-error'` (abort with SIGABRT on runtime error), ``--error-file'`, ``--error-fd'` (dump runtime error messages and strack trace to given file name or FD).
- RTS command line options are now recognized after ``--gpc-rts'` instead of ``-Grts'`. (@)
- Files with ``.pp'` or ``.dpr'` extension are recognized as Pascal sources. (D)

## Compiler and RTS Built-in Declarations

Some of the following declarations are built into the compiler, others are declared in the ``GPC'` module.

- Types etc.:
  - ``nil'` is accepted as a value of any procedural/functional type (B)
  - ByteBool, ShortBool, WordBool, MedBool, LongBool, LongestBool, Boolean(42) (D?)
  - ``register'` directive
  - Directives with double underscores like ``__asmname__'` ``__inline__'` have been dropped. The same directives without underscores have been available for a long time. Furthermore, GPC now supports ``^const'` to create a pointer to a constant (which could be done in a C like fashion with the ``__const__'` directive before). (@)
  - Type qualifiers like ``__byte__'` or ``__unsigned__'` have been dropped. GPC has been supporting "real" type names like ``Byte'` or ``ByteWord'` for a long time, and it's easy to change to them. Similar for ``__cstring__'` and ``__void__'` where ``CString'` and ``Void'` are available. (@)
  - ``mod'` with negative right operand now works like in BP. (B)
  - Expressions like ``-2 * +3'` are now allowed without paretheses. (B)
- Files and I/O:
  - SeekEOF, SeekEOLn (B)
  - IOErrorFile
  - New parameter ``ElementSize'` to ReverseBytes, ConvertFromLittleEndian, ConvertFromBigEndian, ConvertToLittleEndian, ConvertToBigEndian, BlockReadLittleEndian, BlockReadBigEndian, BlockWriteLittleEndian, BlockWriteBigEndian (@)
  - ReadStringLittleEndian
  - ReadStringBigEndian
  - WriteStringLittleEndian
  - WriteStringBigEndian
  - PathExists
  - DataDirectoryName
  - AssignBinary
  - HasWildCardsOrBraces
  - BraceExpand
  - MultiFileNameMatch
  - GlobOn
  - MultiGlob
  - MultiGlobOn
  - QuoteFileName
  - UnQuoteFileName
  - FExpandQuoted
  - ForceAddDirSeparator
  - FindNonQuotedChar
  - FindNonQuotedStr
  - NameExtFromPath
  - GetMountPoint
  - ChMod
  - IOSelect
  - IOSelectRead
  - FileNameLoCase
  - FileNamesCaseSensitive (constant)
  - DirRoot (constant)
  - QuotingCharacter (constant)
  - EnvVarChars (constant)
  - EnvVarCharsFirst (constant)
  - WildCardChars (constant)
  - FileNameSpecialChars (constant)
  - ShellExecCommand (constant)
  - DataReady renamed to CanRead (@)
  - New parameter ``Quoted'` to RelativePath (@)
  - New parameter ``Prefix'` to ConfigFileName (@)
  - ExpandEnvironment recognizes ``~user'`
  - New fields ``User'`, ``Group'`, ``Mode'`, ``Device'`, ``INode'`, ``SymLink'`, ``TextBinary'` and ``Special'` in BindingType; field ``Size'` removed (@)
  - The variable ``TextFilesBinary'` has been dropped. Instead, you can now use the procedure ``AssignBinary'` or the field ``TextBinary'` in BindingType. (@)
  - File sizes can now be bigger than ``Integer'` (e.g. 64 bit files on 32 bit machines) if supported by the OS via llseek() (e.g. Linux, Solaris).
- Strings:
  - Integer2String
  - IsUpCase, IsLoCase, IsAlphaNum, IsAlphaNumUnderscore, IsPrintable
  - Renamed the CString routines in the RTS so they get a ``CString'` prefix, moved the BP compatibility identifiers for the same routines into the ``Strings'` unit (B) (@)
  - MemCompCase
  - StrEqualCase
  - PosCase, LastPosCase, PosFromCase, LastPosTillCase
  - IsPrefixCase, IsSuffixCase
  - LineBreak (constant)
  - SetEnv (obsoletes libc's PutEnv (@))
  - UnSetEnv
  - GetCEnvironment
  - The environment variable management is now implemented in Pascal, so it's independent of libc differences (e.g. the presence or not of ``environ'`). Access via ``GetEnv'` etc. works unchanged.
  - The ``Environment'` variable is now a schema which contains the environment variables as CStrings. (@)
  - Empty and case-sensitive environment variables are allowed within GPC programs even under Dos.
- Random:
  - SeedRandom
  - SeedRandomPtr (variable)
  - Randomize is called automatically when necessary (except when using the BP compatible random number generator in the System unit (B)).
- Memory:
  - ReAlloc; previous ReAlloc function (libc) renamed to CReAlloc (@)
  - ReAllocPtr (variable)
  - ReleaseCount
  - AllocateBigMem, DisposeBigMem, MoveToBigMem, MoveFromBigMem, MapBigMem for uniform access to big memory blocks for GPC and BP (B)
- Time:
  - Sleep
  - SleepMicroSeconds
  - GetCPUTime
  - GetMicroSecondTime
- Misc:
  - Include and Exclude for sets (B)
  - IsInfinity
  - IsNotANumber
  - SplitReal
  - ReturnAddress
  - FrameAddress
  - Runtime errors are now printed with their address to help debugging (using addr2line), and the address is stored in ErrorAddr. (B)
  - RegisterRestoreTerminal
  - UnregisterRestoreTerminal
  - RestoreTerminal
  - ExecuteNoTerminal
  - SetProcessGroup
  - SetTerminalProcessGroup
  - GetTerminalProcessGroup
  - GetShellPath
  - GetPasswordEntryByName
  - GetPasswordEntryByUID
  - GetPasswordEntries
  - StrSignal
  - Kill
  - WaitPID
  - InstallSignalHandler
  - Constants for the signals

  ## GPC Units

- CRT:
  - Works now under Cygwin and mingw.
  - DJGPP: support for 40 column modes (requires updated PDCurses library)
  - Renamed the the conditional to get an X11 version from XCURSES to X11. (@)
  - Renamed GetScreenSize to ScreenSize (WinCRT compatibility) (B) (@)
  - WindowOrg, WindowSize, Cursor, Origin, InactiveTitle, AutoTracking, WindowTitle, (variables), ScrollTo, TrackCursor (WinCRT compatibility) (B)
  - SimulateBlockCursor, SimulateBlockCursorOff
  - Curses is not initialized at the beginning of the program, but rather when the first CRT routine is called. (B)
  - CRTInit to explicitly initialize CRT and also set some defaults (PCCharSet and update level) to more natural (and less BP compatible) values.
  - CRTAutoInitProc (variable)
  - CRTNotInitialized
  - Any of the parameters to GetWindow may now be null.
  - Support for panels (overlapping windows): GetActivePanel, PanelNew, PanelDelete, PanelBindToBackground, PanelIsBoundToBackground, PanelActivate, PanelHide, PanelShow, PanelHidden, PanelTop, PanelBottom, PanelMoveAbove, PanelMoveBelow, PanelAbove, PanelBelow, IgnoreCursor
  - Replaced the variables PCCharSet and UseControlChars by routines SetPCCharSet, GetPCCharSet, SetControlChars, GetControlChars. (@)
  - CRTUpdate
  - CRTRedraw
  - SetScroll
  - CRTSetCursesMode
  - RestoreTerminalClearCRT
  - Catch some signals and return pseudo function keys for them if CheckBreak is False.
  - React to screen size changes by external events and return a pseudo function key.
  - Reduced the (already small) system-dependent code, and added an overview of the few problematic features in the comment at the beginning of crt.pas.
- WinCRT: New unit (identical to CRT) (B)
- RegEx:
  - RegExPosFrom
  - CharSet2RegEx
  - Support for converting subexpression or complete matching references to upper or lower case while replacing them with ``\u7'` or ``\l7'`.
- GMP:
  - mpf_exp
  - mpf_ln
  - mpf_pow
  - mpf_arctan
  - mpf_pi
- System:
  - SetTextBuf (B)
  - RealToBPReal, BPRealToReal to convert between binary BP compatible 6 byte reals and GPC's reals (useful, e.g., for binary file exchange with BP programs) (B)
  - Ofs, Seg, Ptr, CSeg, DSeg, SSeg, SPtr (mostly useless and only for BP compatibility) (B)
  - A number of variables like SelectorInc (mostly useless and only for BP compatibility) (B)
  - Renamed the ``__BP_INTEGERS__'` conditional to ``__BP_TYPE_SIZES__'`. (@)
- Dos, WinDos:
  - Renamed the ``_Borland_16_Bit_'` conditional to ``__BP_TYPE_SIZES__'`. (@)
  - Added a few unportable Dos-only routines under DJGPP if ``__BP_UNPORTABLE_ROUTINES__'` is defined. (B)
- Pipe:
  - New parameter ``Process'` to Pipe (@)
  - WaitPipeProcess
- PExecute:
  - Integrated into the RTS so you don't need a ``uses PExecute'` anymore. (@)
- GetOpt:
  - Integrated into the RTS so you don't need a ``uses GetOpt'` anymore. (@)
  - Renamed the variables and constants used (see gpc.pas under ``Command Line Option Parsing'`). (@)
- HeapMon: New unit for (simple) heap checking.
- Trap: New unit for runtime error trapping.
- MD5: New unit for computing MD5 message digests.
- FileUtils: New unit with some file and directory utilities.
- GPC-BP: A ``GPC'` unit for BP to provide some GPC compatibility to BP programs and make it easier to gradually convert them to GPC. (G)

A few of the units (in particular: CRT, GMP and RegEx) require libraries. The sources of the libraries, with small patches where necessary, as well as binaries for i586-pc-linux-gnu, i586-pc-linux-gnulibc1, m68k-linux, sparc-sun-solaris2, i386-pc-go32, i386-pc-cygwin32 and i386-pc-mingw32 are available from

    @uref{ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/}

## Demo Programs

There is a number of new demo programs to demonstrate some features of the compiler and the units. The demo programs are part of source and binary GPC distributions. After installation, they can be found in ``<prefix>/doc/gpc/demos/'`.

The demo programs contained in the GPC documentation are now installed in ``<prefix>/doc/gpc/docdemos/'`, ready to be compiled.

## Test Suite

The test suite is used to verify that all features of GPC work as expected and to reproduce bugs reported. Test programs for bugs found by users and for new features are constantly added. The test suite is part of source, not binary, GPC distributions.

- As usual, many new tests have been added to the test suite.
- The few system-dependent checks have been equipped with checks about the system properties, and are skipped on systems on which they are not applicable.
- The old dejagnu tests have been integrated in the test suite.
- ``make check'` now runs the current test suite (as ``make check2-gpc'` did before) rather than the (now removed) dejagnu tests.
- The README file (or ``BUGS'` in binary distributions) describes all features of the testing environment, to make it easier for users to construct even exotic new tests, and contains some generic instructions on reporting bugs.
- The test suite now produces a summary output by default. To get the long output format as before, run ``make check-gpc-long'` now.

## Legend

@multitable {xxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}

- ``(@)'`: @tab minor backward-incompatibility
- ``(B)'`: @tab BP compatibility
- ``(D)'`: @tab Delphi compatibility
- ``(G)'`: @tab GPC compatibility :-) Have fun, The GNU Pascal Development Team

  # GNU Pascal Command Line Options

  GPC is a command-line compiler, i.e., to compile a program you have to invoke ``gpc'` passing it the name of the file you want to compile, plus options.

  GPC supports all command-line options that GCC knows. For a complete reference and descriptions of all options, see section `GCC Command Options' in the GCC manual. Below, you will find a list of the additional options that GPC supports, and a list of GPC's most important options (including some of those supported by GCC as well).

  You can mix options and file names on the command line. For the most part, the order doesn't matter. Order does matter, e.g., when you use several options of the same kind; for example, if you specify ``-L'` more than once, the directories are searched in the order specified. Note: Since many options have multiletter names; multiple single-letter options may not be grouped as is possible with many other programs: ``-dr'` is very different from ``-d -r'`.

  Many options have long names starting with ``--'` or, completely equivalent ``-f'`. E.g., ``--mixed-comments'` is the same as ``-fmixed-comments'`. Some options tell GPC when to give warnings, i.e. diagnostic messages that report constructs which are not inherently erroneous but which are risky or suggest there may have been an error. Those options start with ``-W'`.

  Most GPC specific options can also be changed during one compilation by using compiler directives in the source, e.g. ``{$X+}'` or ``{$extended-syntax}'` for ``--extended-syntax'` (see section Compiler Directives And The Preprocessor).

  GPC understands the same environment variables GCC does (see section `Environment Variables Affecting GCC' in the GCC manual). In addition, GPC recognizes ``GPC_EXEC_PREFIX'` with the same meaning that ``GCC_EXEC_PREFIX'` has to GCC. GPC also recognizes ``GCC_EXEC_PREFIX'`, but ``GPC_EXEC_PREFIX'` takes precedence.

  ## GPC options besides those of GCC.

  The following table lists the command line options GPC understands in addition to those understood by GCC.

  `--standard-pascal-level-0`
    Reject conformant arrays and anything besides ISO-7185 Standard Pascal.
  `--standard-pascal`
    Reject anything besides ISO-7185 Standard Pascal.
  `--extended-pascal`
    Reject anything besides ISO-10206 Extended Pascal.
  `--object-pascal`
    Reject anything besides (the implemented parts of) ANSI draft Object Pascal.
  `--borland-pascal`
    Try to emulate Borland Pascal, version 7.0.
  `--delphi`
    Try to emulate Borland Pascal, version 7.0, with some Delphi extensions.
  `--pascal-sc`
    Be strict about the implemented Pascal-SC extensions.
  `--gnu-pascal`
    Undo the effect of a previous ``--foo-pascal'`, ``--delphi'` or ``--pascal-sc'` switch.
  `--lines`
    (Unimplemented switch for debugging).
  `--debug-tree`
    (Internal directive for debugging the compiler).
  `--debug-gpi`
    (Internal directive for debugging the compiler).
  `--debug-source`
    (Internal directive for debugging the compiler).
  `--progress-messages`
    Output source file names and line numbers while compiling.
  `--progress-bar`
    Output number of processed lines while compiling.
  `--autolink`
    Automatically link object files provided by Units/Modules or ``{$L ...}'` (default).
  `--no-autolink`
    Do not automatically link object files provided by Units/Modules/``{$L ...}'`.
  `--automake`
    Automatically compile changed Units/Modules/``{$L ...}'` files and link the object files provided.
  `--no-automake`
    Same as ``--no-autolink'`.
  `--autobuild`
    Automatically compile all Units/Modules/``{$L ...}'` files and link the object files provided.
  `--no-autobuild`
    Same as ``--no-autolink'`.
  `--amtmpfile`
    (Internal switch used for AutoMake).
  `--extended-syntax`
    Enable certain ``dangerous'` features such as ignoring function results, pointer arithmetics or using ``CString'`s as strings (same as ``{$X+}'`).
  `--no-extended-syntax`
    Disable the dangerous features enabled by ``--extended-syntax'` (default; same as ``{$X-}'`).
  `--signed-char`
    Let ``Char'` be a signed type.
  `--no-signed-char`
    Let ``Char'` be an unsigned type.
  `--unsigned-char`
    Let ``Char'` be an unsigned type.
  `--no-unsigned-char`
    Let ``Char'` be a signed type.
  `--short-circuit`
    Guarantee short-circuit Boolean evaluation (default; same as ``{$B-}'`).
  `--no-short-circuit`
    Do not guarantee short-circuit Boolean evaluation (same as ``{$B+}'`).
  `--mixed-comments`
    Allow comments like ``{ ... *)'` as required in ISO Pascal (default in Standard Pascal mode).
  `--no-mixed-comments`
    Ignore ``{'` and ``}'` within ``(* ... *)'` comments and vice versa (default).
  `--nested-comments`
    Allow nested comments like ``{ { } }'` and ``(* (* *) *)'`.
  `--no-nested-comments`
    Do not allow nested comments (default).
  `--delphi-comments`
    Allow Delphi style ``//'` comments (default).
  `--no-delphi-comments`
    Do not allow Delphi style ``//'` comments.
  `--macros`
    Expand macros (default).
  `--no-macros`
    Do not expand macros (default with ``--borland-pascal'` or ``--delphi'`).
  `--ignore-function-results`
    Do not complain when a function is called like a procedure.
  `--no-ignore-function-results`
    Complain when a function is called like a procedure (default).
  `--borland-char-constants`
    Allow for Borland-style character constants like ``#27'` or ``^L'` (default).
  `--no-borland-char-constants`
    Reject Borland-style character constants like ``#27'` or ``^L'` (default in Standard Pascal mode).
  `--truncate-strings`
    Truncate strings being assigned to other strings of too short capacity..
  `--no-truncate-strings`
    Treat string assignments to other strings of too short capacity as errors..
  `--exact-compare-strings`
    Do not blank-pad strings for comparisons.
  `--no-exact-compare-strings`
    Blank-pad strings for comparisons.
  `--io-checking`
    Do automatic run-time checks after I/O operations (same as ``{$I+}'`).
  `--no-io-checking`
    Do not check I/O operations automatically (same as ``{$I-}'`).
  `--write-clip-strings`
    In write statements, truncate strings exceeding their field width (``Write (SomeLongString : 3)'`).
  `--no-write-clip-strings`
    Do not truncate strings exceeding their field width.
  `--write-real-blank`
    Output a blank in front of positive reals in exponential form (default).
  `--no-write-real-blank`
    Do not output a blank in front of positive reals in exponential form.
  `--write-capital-exponent`
    Write real exponents with a capital ``E'`.
  `--no-write-capital-exponent`
    Write real exponents with a lowercase ``e'`.
  `--transparent-file-names`
    Derive external file names from variable names.
  `--no-transparent-file-names`
    Do not derive external file names from variable names (default).
  `--field-widths`
    Comma-separated list of default field widths for Integer, Real, Boolean, LongInt, LongReal.
  `--no-field-widths`
    Reset the default field widths.
  `--pedantic`
    Warn about everything rejected in some dialect, e.g. redefinition of its keywords.
  `--no-pedantic`
    Don't give pedantic warnings.
  `--stack-checking`
    Enable stack checking (same as ``{$S+}'`).
  `--no-stack-checking`
    Disable stack checking (same as ``{$S-}'`).
  `--typed-address (same as ``{$T+}'`)`
    Make the result of the address operator typed (default).
  `--no-typed-address (same as ``{$T-}'`)`
    Make the result of the address operator an untyped pointer.
  `--setlimit`
    Define the range for ``set of Integer'` etc..
  `--gpc-main`
    External name for the program's entry point (default: ``main'`).
  `--interface-only`
    Compile only the interface part of a Unit/Module and exit.
  `--implementation-only`
    Do not produce a GPI file; only compile the implementation part.
  `--executable-file-name`
    Name for the output file, if specified; otherwise derive from main source file name.
  `--unit-path`
    Directories where to look for Unit/Module sources.
  `--no-unit-path`
    Forget about directories where to look for Unit/Module sources.
  `--object-path`
    Directories where to look for additional object (and source) files.
  `--no-object-path`
    Forget about directories where to look for additional object (and source) files.
  `--executable-path`
    Path where to create the executable file.
  `--no-executable-path`
    Create the executable file in the directory where the main source is (default).
  `--unit-destination-path`
    Path where to create object and GPI files.
  `--no-unit-destination-path`
    Create object and GPI files in the current directory (default).
  `--object-destination-path`
    Path where to create additional object files.
  `--no-object-destination-path`
    Create additional object files in the current directory (default).
  `--no-default-paths`
    Do not add a default path to the unit and object path.
  `--gpi-destination-path`
    (Internal switch used for AutoMake).
  `--uses`
    Add an implicit ``uses'` clause.
  `--cidefine`
    Define a case-insensitive macro.
  `--csdefine`
    Define a case-sensitive macro.
  `-Wwarnings`
    Enable warnings (same as ``{$W+}'`).
  `-Wno-warnings`
    Disable warnings (same as ``{$W-}'`).
  `-Wfield-name-problem`
    Warn about ignored field names in initializers (default).
  `-Wno-field-name-problem`
    Do not warn about ignored field names in initializers.
  `-Wtyped-const`
    Warn about misused of typed constants as initialized variables (default).
  `-Wno-typed-const`
    Do not warn about misused of typed constants as initialized variables.
  `-Wnear-far`
    Warn about use of useless ``near'` or ``far'` directives (default).
  `-Wno-near-far`
    Do not warn about use of useless ``near'` or ``far'` directives.
  `-Wmixed-comments`
    Warn about mixed comments like ``{ ... *)'`.
  `-Wno-mixed-comments`
    Do not warn about mixed comments.
  `-Wnested-comments`
    Warn about nested comments like ``{ { } }'`.
  `-Wno-nested-comments`
    Do not warn about nested comments.

  ## The most commonly used options to GPC

  As the most simple example, calling

      gpc foo.pas

  tells GPC to compile the source file ``foo.pas'` and to produce an executable of the default name which is ``foo.exe'` on EMX, ``a.exe'` on DJGPP, and ``a.out'` on most other platforms.

  Users familiar with BP, please note that you have to give the file name extension ``.pas'`: GPC is a common interface for a Pascal compiler, a C, ObjC and C++ compiler, an assembler, a linker, and perhaps an Ada and a FORTRAN compiler. From the extension of your source file GPC figures out which compiler to run. GPC recognizes Pascal sources by the extension ``.pas'`, ``.p'`, ``.pp'` or ``.dpr'`. GPC also accepts source files in other languages (e.g., ``.c'` for C) and calls the appropriate compilers for them. Files with the extension ``.o'` or without any special recognized extension are considered to be object files or libraries to be linked.

  Another example:

      gpc -O2 -Wall --executable-file-name --automake --unit-path=units foo.pas

  This will compile the source file ``foo.pas'` to an executable named ``foo'` (``--executable-file-name'`) with fairly good optimization (``-O2'`), warning about possible problems (``-Wall'`). If the program uses units or imports modules, they will be searched for in a directory called ``units'` (``--unit-path'`) and automatically compiled and linked (``--automake'`).

  The following table lists the most commonly used options to GPC.

  `--automake`
    Check whether modules/units used must be recompiled and do the recompilation when necessary.
  `--unit-path=dir[:dir...]`
    Search the given directories for units and object files.
  `--object-path=dir[:dir...]`
    Search the given directories for object files.
  `--unit-destination-path=dir`
    Place units compiled into the directory dir. The default is the current directory.
  `--object-destination-path=dir`
    Place object files compiled into the directory dir. The default is the directory given with ``--unit-destination-path'`.
  `--executable-path=dir`
    Place the executable compiled into the directory dir. The default is the main source file's directory.
  `-o file`
    Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file, etc. Since only one output file can be specified, it does not make sense to use ``-o'` when compiling more than one input file, unless you are producing an executable file as output.
  `--executable-file-name[=name]`
    Derive the executable file name from the source file name, or use name as the executable file name. The difference to the ``-o'` option is that ``--executable-file-name'` considers the ``--executable-path'`, while ``-o'` does not and accepts a file name with directory. Furthermore, ``--executable-file-name'` only applies to executables, not to other output formats selected.
  `-Ldir`
    Search the directory dir for libraries. Can be given multiple times.
  `-Idir`
    Search the directory dir for include files. Can be given multiple times.
  `-llibrary`
    Search the library named library when linking. This option must be placed on the command line after all source or object files or other libraries that reference the library.
  `-O[n]`
    Select the optimization level. Without optimization (or ``-O0'` which is the default), the compiler's goal is to reduce the compilation time and to make debugging produce the expected results. Statements are independent: if you stop the program with a breakpoint between statements, you can then assign a new value to any variable or change the program counter to any other statement in the same routine and get exactly the results you would expect from the source code. With optimization, the compiler tries to reduce code size and execution time. The higher the value of n, the more optimizations will be done, but the longer the compilation will take. If you use multiple ``-O'` options, with or without n, the last such option is the one that is effective.
  `-g`
    Produce debugging information suitable for ``gdb'`. Unlike some other compilers, GNU Pascal allows you to use ``-g'` with ``-O'`. The shortcuts taken by optimized code may occasionally produce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not expect it; some statements may not be executed because they compute constant results or their values were already at hand; some statements may execute in different places because they were moved out of loops. Nevertheless it proves possible to debug optimized output. This makes it reasonable to use the optimizer for programs still in the testing phase.
  `-s`
    Remove all symbol table and relocation information from the executable. Note: this has no influence on the performance of the compiled executable.
  `-Wall`
    Give warnings for a number of constructs which are not inherently erroneous but which are risky or suggest there may have been an error. There are additional warning options not implied by ``-Wall'`, see the GCC warning options (see section `Options to Request or Suppress Warnings' in the GCC manual), while ``-Wall'` only warns about such constructs that should be easy to avoid in programs. Therefore, we suggest using ``-Wall'` on most sources.
  `-Werror`
    Turn all warnings into errors.
  `-S`
    Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each source file. By default, the assembler file name for a source file is made by replacing the extension with ``.s'`.
  `-c`
    Compile and assemble the source files, but do not link. The output is in the form of an object file for each source file. By default, the object file name for a source file is made by replacing the extension with ``.o'`.
  `-static`
    On systems that support dynamic linking, this prevents linking with the shared libraries, i.e. forces static linking. On other systems, this option has no effect.
  `-Dmacro[=defn]`
    Define the macro and conditional macro as defn (or as ``1'` if defn is omitted).
  `-b machine`
    The argument machine specifies the target machine for compilation. This is useful when you have installed GNU Pascal as a cross-compiler.
  `-v`
    Print (on standard error) the commands executed to run the stages of compilation. Also print the version number of the compiler driver program and of the preprocessor and the compiler proper.
  `--standard-pascal-level-0`
  `--standard-pascal`
  `--extended-pascal`
  `--object-pascal`
  `--borland-pascal`
  `--pascal-sc`
    GNU Pascal supports the features of several different Pascal standards and dialects. By default, they are all enabled. These switches tell GPC to restrict itself to the features of the specified standard. It does not enable any additional features. Warnings about constructs which would be legal in the specified dialect (e.g. assignment to a typed constant with ``--borland-pascal'`) are suppressed. By default, GNU Pascal allows redefinition of keywords. Each of these switches causes GNU Pascal to forbid the redefinition of keywords of the specified standard. Valid ISO Standard Pascal programs should compile properly with or without ``--standard-pascal'`. However, without this option, certain GNU extensions and Pascal features from other dialects are supported as well. With this option, they are rejected. These options are not intended to be useful; they exist only to satisfy pedants who would otherwise claim that GNU Pascal fails to support the ISO Standard or is not really compatible to Borland Pascal, or whatever. We recommend, rather, that users take advantage of the extensions of GNU Pascal and disregard the limitations of other compilers.
  `-pedantic-errors`
    Produce errors rather than warnings for portability violations. Unlike in C, this does not imply the ``-pedantic'` option, so you can, for instance, use ``-pedantic-errors'` without ``-pedantic'`, but with ``--extended-pascal'`.
  `--gpc-main=name`
    Name the entry point of the main program ``name'` instead of ``main'` on the linker level. This is useful, e.g., when working with some C libraries which define their own ``main'` function and require the program's main entry point to be named differently.

  # The Programmer's Guide to GPC

  This chapter is under development, so don't be too excited about the paragraph below!

  This chapter tells you how the source of a valid GNU Pascal program should look like. You can use it as tutorial about the GNU Pascal language, but since the main goal is to document all special GPC features, implementation-dependent stuff, etc., expect a steep learning curve.

  This chapter does not cover how to compile your programs and to produce an executable--this is discussed above in section GNU Pascal Command Line Options.

  ## Source Structures

  A source file accepted by GNU Pascal may contain up to one program, zero or more ISO style modules, and/or zero or more UCSD/BP style units. Units and modules can be mixed in one project.

  One trivial example for a valid GPC source file follows. Note that the code below may either be in one source file, or else the unit and the program may be in separate source files.

      unit DemoUnit;

      interface

      procedure Hello;

      implementation

      procedure Hello;
      begin
        Writeln ('Hello, world!')
      end;

      end.

      program UnitDemo;

      uses DemoUnit;

      begin
        Hello
      end.

  ### The Source Structure of Programs

  A generic GNU Pascal program looks like the following:

      Program name (Input, Output);

      import part

      declaration part

      begin
        statement part
      end.

  The `Program` headline may be omitted in GPC, but a warning will be given except in ``--borland-pascal'` mode.

  While the program parameters (usually ``Input, Output'`) are obligatory in ISO Pascal if you want to use ``Readln'` and ``Writeln'`, they are optional in GNU Pascal. GPC will warn about such missing parameters in ``--extended-pascal'` mode. However if you give parameters to the program headline, they work like ISO requires.

  The import part consists either of an ISO-style ``import'` specification or a UCSD/Borland-style ``uses'` clause. While ``import'` is intended to be used with interfaces exported by ISO-10206 Extended Pascal ``modules'` and ``uses'` is intended to be used with ``units'`, this is not enforced. (See also section uses, section import.)

  The declaration part consists of constant, type, variable, procedure, and function declarations in free order.

  As an extension, GPC supports a "declaring statement" which can be used in the statement part to declare variables (see section var).

  ### The Source Structure of UCSD/Borland Pascal Units

  A generic GNU Pascal Unit looks like the following:

      Unit name;

      Interface

      import part

      interface part

      Implementation

      implementation part

      initialization part

      end.

  The name of the unit should coincide with the name of the file with the extension stripped. (If not, you can tell GPC the file name with ``uses foo in 'bar.pas''`, see section uses.)

  The import part is either empty or contains a ``uses'` clause to import other units. It may also consist of an ISO-style ``import'` specification. Note that the implementation part is not preceeded by a second import part in GPC (see section import).

  The interface part consists of constant, type, and variable declarations, procedure and function headings which may be freely mixed.

  The implementation part is like the declaration part of a program, but the headers of procedures and functions may be abbreviated: Parameter lists and function return values may be omitted for procedures and functions already declared in the interface part.

  The initialization part may be missing, or it may be a ``begin'` followed by one or more statements, such that the Unit has a statement part between this ``begin'` and the final ``end'`. Alternatively, a Unit may have ISO-style Module initializers and finalizers, see section to begin do, section to end do.

  Note that GPC does not check whether all interface declarations are resolved in the same Unit. Procedures and functions which are in fact not used may be omitted, and/or procedures and functions may be implemented somewhere else, even in a different language.

  A unit exports everything declared in the interface section. The exported interface has the name of the unit and is compatible with Extended Pascal module interfaces since GPC uses the same code to handle both.

  ### The Source Structure of ISO-10206 Extended Pascal Modules

  @@ Description missing here

  A module can have one or more ``export'` clauses and the name of an ``export'` clause doesn't have to be equal to the name of the module.

  Sample module code with separate `interface` and `implementation` parts:

      module DemoModule interface;  { interface part }

      export DemoModule = (FooType, SetFoo, GetFoo);

      type
        FooType = Integer;

      procedure SetFoo (f : FooType);
      function  GetFoo : FooType;

      end.

      module DemoModule implementation;  { implementation part }

      import
        StandardInput;
        StandardOutput;

      var
        Foo : FooType;

      { Note: the effect is the same as a `forward' directive would have:
        parameter lists and return types are not allowed in the
        declaration of exported routines, according to EP. In GPC, they
        are allowed, but not required. }
      procedure SetFoo;
      begin
        Foo := f
      end;

      function GetFoo;
      begin
        GetFoo := Foo
      end;

      to begin do
        begin
          foo := 59;
          Writeln ('Just an example of a module initializer. See comment below')
        end;

      to end do
        begin
          Foo := 0;
          Writeln ('Goodbye')
        end;

      end.

  Alternatively the module interface and implementation may be combined as follows:

      module DemoMod2; { Alternative method }

      export Catch22 = (FooType, SetFoo, GetFoo);

      type
        FooType = Integer;

      procedure SetFoo (f : FooType);
      function  GetFoo : FooType;

      end; { note: this end is required here, even if the
             module-block below would be empty. }

      var
        Foo : FooType;

      procedure SetFoo;
      begin
        Foo := f
      end;

      function GetFoo;
      begin
        GetFoo := Foo
      end;

      end.

  Either one of the two methods may be used like this:

      program ModuleDemo (Output);

      import DemoModule;

      begin
        SetFoo (999);
        Writeln (GetFoo);
      end.

      program ModDemo2 (Output);

      import Catch22 in 'demomod2.pas';

      begin
        SetFoo (999);
        Writeln (GetFoo);
      end.

  Somewhat simpler GPC modules are also supported. Note: This is not supported in the Extended Pascal standard.

  This is a simpler module support that does not require exports, imports, module headers etc.

  These non-standard simple GPC modules look like (does not have an export part, does not have a separate module-block, does not use import/export features.)

      module DemoMod3;

      type
        FooType = Integer;

      var
        Foo : FooType;

      procedure SetFoo (f : FooType);
      begin
        Foo := f
      end;

      function GetFoo : FooType;
      begin
        GetFoo := Foo;
      end;

      end.

      program ModDemo3 (Output);

      { Manually do the "import" from DemoMod3 }
      type
        FooType = Integer;

      procedure SetFoo (f : FooType); external;
      function  GetFoo : FooType;     external;

      begin
        SetFoo (999);
        Writeln (GetFoo)
      end.

  Module initialization and finalization:

  The `to begin do` module initialization and `to end do` module finalization constructs now work on every target.

  By the way: The "GPC specific" module definition is almost identical to the PXSC standard. With an additional keyword `global' which puts a declaration into an export interface with the name of the module, it will be the same. @@This is planned.

  ## Data Types

  ### Integer Types

  Besides ``Integer'`, GNU Pascal supports a large zoo of integer types. Some of them you will find in other compilers, too, but most are GNU extensions, introduced for particular needs. Many of these types are synonyms for each other. In total, GPC provides 20 built-in integer types, plus seven families you can play with. (Four of these "families" are signed and unsigned, packed and unpacked Subrange types; the others are explained below.)

  See also: section Subrange Types.

  #### The Processor's Natural Integer Types

  For most purposes, you will always use ``Integer'`, a signed integer type which has the "natural" size of such types for the machine. On most machines GPC runs on, this is a size of 32 bits, so ``Integer'` usually has a range of ``-2147483648..2147483647'` (see section Integer).

  If you need an unsigned integer type, the "natural" choice is ``Cardinal'`, also called ``Word'`. Like ``Integer'`, it has 32 bits on most machines and thus a range of ``0..4294967295'` (see section Cardinal, section Word).

  These natural integer types should be your first choice for best performance. For instance on an Intel X86 processor operations with ``Integer'` usually work faster than operations with shorter integer types like ``ShortInt'` or ``ByteInt'` (see below).

  #### The main branch of Integer Types

  ``Integer'`, ``Cardinal'`, and ``Word'` define the three "main branches" of GPC's integer types. You won't always be able to deal with the natural size; sometimes something smaller or longer will be needed. Especially when interfacing with libraries written in other languages such as C, you will need equivalents for their integer types.

  The following variants of ``Integer'`, ``Cardinal'` and ``Word'` are guaranteed to be compatible to the integer types of GNU C. The sizes, however, are not guaranteed. They are just typical values currently used on most platforms, but they may be actually shorter or increase in the future.

      (signed)        (unsigned)         GNU C equivalent   typical size (bits)

      ByteInt    ByteCard    Byte        [un]signed char              8
      ShortInt   ShortCard   ShortWord   [unsigned] short int        16
      Integer    Cardinal    Word        [unsigned] int              32
      MedInt     MedCard     MedWord     [unsinged] long int         32
      LongInt    LongCard    LongWord    [unsinged] long long int    64

  Since we don't know whether ``LongInt'` will always remain the "longest" integer type available--maybe GNU C will get ``long long long int'`, one day, which we will support as ``LongLongInt'`---we have added the synonym ``LongestInt'` for the longest available singed integer type, and the same holds for ``LongestCard'` and ``LongestWord'`.

  #### Integer Types with Specified Size

  In some situations you will need an integer type of a well-defined size. For this purpose, GNU Pascal provides tree families of signed and unsinged integer types. The type

        Integer ( 42 )

  is guaranteed to have a precision of 42 bits. In a realistic context, you will most often give a power of two as the number of bits, and the machine you will need it on will support variables of that size. If this is the case, the specified precision will simultaneously be the amount of storage needed for variables of this type.

  In short: If you want to be sure that you have a signed integer with 32 bits width, write ``Integer ( 32 )'`, not just ``Integer'` which might be bigger. The same works with ``Cardinal'` and ``Word'` if you need unsigned integer types of well-known size.

  #### Compatibility to other Pascal compilers

  If you care about ISO compliance, only use ``Integer'` and subranges of ``Integer'`.

  Some of GPC's non-ISO integer types exist in Borland Pascal, too: ``Byte'`, ``ShortInt'`, ``Word'`, and ``LongInt'`. The sizes of these types, however, are not the same as in Borland Pascal. Even for ``Byte'` this is not guaranteed (while probable, though).

  When designing GNU Pascal, we thought about compatibility to Borland Pascal. Since GNU Pascal is (at least) a 32-bit compiler, ``Integer'` must have (at least) 32 bits. But what to do with ``Word'`? Same size as ``Integer'` (like in BP) or 16 bits (like in BP)? We decided to make ``Word'` the "natural-sized" unsigned integer type, thus making it (at least) 32 bits wide. Similarly, we decided to give ``LongInt'` twice the size of ``Integer'` (like in BP) rather than making it 32 bits wide (like in BP). So ``LongInt'` has 64 bits, and ``ShortInt'` has 16 bits on the Intel X86 platforms.

  On the other hand, to increase compatibility to Borland Pascal and Delphi, GPC provides the alias name ``Comp'` for ``LongInt'` (64 bits on Intel X86) and ``SmallInt'` for ``ShortInt'` (16 bits on Intel X86). Note that BP treads ``Comp'` as a "real" type and allows assignments like ``MyCompVar:= 42.0'`. Since we don't consider this a feature, GPC does not copy this behaviour.

  #### Summary of Integer Types

  Here is a summary of all integer types defined in GPC. The sizes and ranges are only typical values, valid on some, but not all platforms. Compatibility to GNU C however is guaranteed (to the extend of the GNU General Public License, of course ;-).

  section ByteInt
    signed 8-bit integer type, ``-128..128'`,
    compatible to ``signed char'` in GNU C.
  section ByteCard
    unsigned 8-bit integer type, ``0..255'`,
    compatible to ``unsigned char'` in GNU C.
  section ShortInt
    signed 16-bit integer type, ``-32768..32767'`,
    compatible to ``short int'` in GNU C.
  section ShortCard
    unsigned 16-bit integer type, ``0..65535'`,
    compatible to ``unsigned short int'` in GNU C.
  section Integer
    signed 32-bit integer type, ``-2147483648..2147483647'`,
    compatible to ``int'` in GNU C.
  section Cardinal
    unsigned 32-bit integer type, ``0..4294967295'`,
    compatible to ``unsigned int'` in GNU C.
  section MedInt
    signed 32-bit integer type, ``-2147483648..2147483647'`,
    compatible to ``long int'` in GNU C.
  section MedCard
    unsigned 32-bit integer type, ``0..4294967295'`,
    compatible to ``unsigned long int'` in GNU C.
  section LongInt
    signed 64-bit integer type, ``-9223372036854775808..9223372036854775807'`,
    compatible to ``long long int'` in GNU C.
  section LongCard
    unsigned 64-bit integer type, ``0..18446744073709551615'`,
    compatible to ``unsigned long long int'` in GNU C.
  section LongestInt
    signed 64-bit integer type, ``-9223372036854775808..9223372036854775807'`.
  section LongestCard
    unsigned 64-bit integer type, ``0..18446744073709551615'`.
  section Comp
    signed 64-bit integer type, ``-9223372036854775808..9223372036854775807'`.
  section SmallInt
    signed 16-bit integer type, ``-32768..32767'`.

  To specify the number of bits, use

  ``Integer ( n )'`
    signed n-bit integer type.
  ``Cardinal ( n )'`
    unsigned n-bit integer type.
  ``Word ( n )'`
    unsigned n-bit integer type.

      program IntegerTypesDemo (Output);

      var
        ByteVar : Byte;
        ShortIntVar : ShortInt;
        Foo : MedCard;
        Big : LongestInt;

      begin
        ShortIntVar := 1000;
        Big := MaxInt * ShortIntVar;
        ByteVar := 127;
        Foo := 16#deadbeef
      end.

  See also: section Subrange Types.

  ### Subrange Types

  GNU Pascal supports Standard Pascal's subrange types:

        Type
          MonthInt = 1..12;
          Capital = 'A'..'Z';
          ControlChar = ^A..^Z;  (* `^A' = `chr ( 1 )' is an extension *)

  To increase performance, variables of such a type are aligned in a way which makes them fastest to access by the CPU. As a result, ``1..12'` occupies 4 bytes of storage on an Intel X86 compatible processor.

  For if you want to save storage at the expense of speed, GPC provides a ``packed'` variant of these as an extension:

        Type
          MonthInt = packed 1..12;

  A variable of this type occupies the shortest possible (= addressable) space in memory -- one byte on an Intel X86 compatible processor.

  See also: section packed.

  ### Endianness

  Endianness means the order in which the bytes of a value larger than one byte are stored in memory. This affects, e.g., integer values and pointers while, e.g., arrays of single-byte characters are not affected. The GPC ``String'` schema, however, contains ``Capacity'` and ``Length'` fields before the character array. These fields are integer values larger than one byte, so the ``String'` schema is affected by endianness.

  Endianness depends on the hardware, especially the processor. The most common forms are:

  Little-endian
    Little-endian machines store the least significant byte on the lowest memory address (the word is stored little-end-first). E.g., if the 32 bit value $deadbeef is stored on memory address $1234 on a little-endian machine, the following bytes will occupy the memory positions:

        Address  Value
        --------------
        $1234    $ef
        $1235    $be
        $1236    $ad
        $1237    $de

    Examples for little-endian machines are Intel and compatible microprocessors and Alpha processors.
  Big-endian
    Big-endian machines store the most significant byte on the lowest memory address (the word is stored big-end-first). E.g., if the 32 bit value $deadbeef is stored on memory address $1234 on a big-endian machine, the following bytes will occupy the memory positions:

        Address  Value
        --------------
        $1234    $de
        $1235    $ad
        $1236    $be
        $1237    $ef

    Examples for big-endian machines are the Sparc and Motorola m68k processor families and most RISC processors. Big-endian byte order is also used in the Internet protocols.

  Note: There are processors which can run in both little-endian and big-endian mode, e.g. the MIPS processors. A single program, however, (unless it uses special machine code instructions) will always run in one endianness.

  Under normal circumstances, programs do not need to worry about endianness, the processor handles it by itself. Endianness becomes important when exchanging data between different machines, e.g. via binary files or over a network. To avoid problems, one has to choose the endianness to use for the data exchange. E.g., the Internet uses big-endian data, and most known data formats have a specified endianness (usually that of the processor on which the format was originally created). If you define your own binary data format, you're free to choose the endianness to use.

  To deal with endianness, GPC predefines the symbol ``__BYTES_LITTLE_ENDIAN__'` on little-endian machines and ``__BYTES_BIG_ENDIAN__'` on big-endian machines. Besides, the Run Time System defines the constant ``BytesBigEndian'` as False on little-endian machines and True on big-endian machines.

  There are also the symbols ``__BITS_LITTLE_ENDIAN__'`, ``__BITS_BIG_ENDIAN__'`, ``__WORDS_LITTLE_ENDIAN__'`, ``__WORDS_BIG_ENDIAN__'` and the constants ``BitsBigEndian'` and ``WordsBigEndian'` which concern the order of bits within a byte (e.g., in packed records) or of words within multiword-numbers, but these are usually less important.

  The Run Time System also contains a number of routines to convert endianness and to read or write data from/to binary files in a given endianness, independent of the processor's endianness. These routines are described in the RTS reference (see section Run Time Library--Pascal Declarations), under ``endianness'`. The demo program ``endiandemo.pas'` contains an example on how to use these routines.

  ### Alignment

  (Under construction.)

  ### Pointer Types

  (Under construction.)

  GPC also suports pointers to procedures or function and calls through them. This is a non-standard feature.

      program ProcPtrDemo (Output);

      type
        ProcPtr = ^procedure (Integer);

      var
        PVar : ProcPtr;

      procedure WriteInt (i : Integer);
      begin
        Writeln ('Integer: ', i : 1)
      end;

      begin
        { Let PVar point to function WriteInt }
        PVar := &WriteInt;

        { Call the function by dereferencing the function pointer }
        PVar^ (12345)
      end.

  ### Procedural and Functional Types

  (Under construction.)

  BP has procedural and functional types:

      type
        CompareFunction = function (Key1, Key2 : String) : Integer;

      function Sort (Compare : CompareFunction);
      begin
        ...
      end;

  Standard Pascal has procedural and functional parameters:

      function Sort (function Compare (Key1, Key2 : String) : Integer);
      begin
        ...
      end;

  Both ways have pros and cons, e.g. in BP you can save, compare, trade, etc. procedural values, or build arrays of them, while the SP way does not require a type declaration and prevents problems with uninitialized or invalid pointers (which in BP will usually crash the program).

  GPC supports both ways. An important feature of Standard Pascal (but not BP) that GPC also supports is the possibility to pass local routines as procedural or functional parameters, even if the called routine is declared far remote. The called routine can then call the passed local routine and it will have access to the original caller's local variables.

      program LocalProceduralParameterDemo;

      procedure CallProcedure (procedure Proc);
      begin
        Proc
      end;

      procedure MainProcedure;
      var LocalVariable : Integer;

        procedure LocalProcedure;
        begin
          Writeln (LocalVariable)
        end;

      begin
        LocalVariable := 42;
        CallProcedure (LocalProcedure)
      end;

      begin
        MainProcedure
      end.

  ### Variant Records

  GPC supports variant records like in EP and BP. The following construction is not allowed in Extended Pascal, but in BP and GPC:

      type
        PersonRec = record
          Age : Integer;
          case EyeColor : (Red, Green, Blue, Brown) of
            Red, Green  : (WearsGlasses : Boolean);
            Blue, Brown : (LengthOfLashes : Integer);
          end;
        end;

  In EP, the variant field needs a type identifier, which, of course, also works in GPC:

      type
        EyeColorType = (Red, Green, Blue, Brown);
        PersonRec = record
          Age : Integer;
          case EyeColor : EyeColorType of
            Red, Green  : (WearsGlasses : Boolean);
            Blue, Brown : (LengthOfLashes : Integer);
          end;
        end;

  ### Initial values to type denoters

  A type may be initialized to a value of expression when it is declared, like a variable, as in:

      program TypeVarInitDemo;
      type
        Int10   = Integer value 10;
        FooType = Real;
        MyType  = Char value Pred ('A');
        EType   = (a, b, c, d, e, f, g) value d;

      const
        Answer = 42;

      var
        ii  : Int10;                    { Value of ii set to 10 }
        ch  : MyType  value Pred ('z');
        aa  : Integer value Answer + 10;
        foo : FooType value Sqr (Answer);
        e1  : EType;                    { value set to d }
        e2  : EType value g;            { value set to g }
      begin
      end.

  Extended Pascal requires the type initializers to be constant expressions. GPC allows any valid expression.

  Note, however, that the expressions that affect the size of storage allocated for objects (e.g. the length of arrays) may contain variables only inside functions or procedures.

  GPC evaluates the initial values used for the type when an identifier is declared for that type. If a variable is declared with a type-denoter that uses a type-name which already has an initial value the latter initialization has precedence.

  @@ GPC does not know how to calculate constant values for math functions in the runtime library at compile time, e.g. ``Exp (Sin (2.4567))'`, so you should not use these kind of expressions in object size expressions. (Extended Pascal allows this.)

  ### Restricted types

  GPC supports ``restricted'` types, defined in Extended Pascal. A value of a restricted type may be passed as a value parameter to a formal parameter possessing its underlying type, or returned as the result of a function. A variable of a restricted type may be passed as a variable parameter to a formal parameter possessing the same type or its underlying type. No other operations, such as accessing a component of a restricted type value or performing arithmetic, are possible.

      program RestrictedDemo;

      type
        UnrestrictedRecord = record
          a : Integer;
        end;
        RestrictedRecord =  restricted UnrestrictedRecord;

      var
        r1 : UnrestrictedRecord;
        r2 : RestrictedRecord;
        i : restricted Integer;
        k : Integer;

        function AccessRestrictedRecord (p : UnrestrictedRecord) : RestrictedRecord;
        var URes : UnrestrictedRecord;
        begin
          { The parameter is treated as unrestricted, even though the actual
            parameter may be a restricted object }
          URes.a := p.a;
          { It is legal to assign a return value }
          AccessRestrictedRecord := URes;
        end;

      begin
         r1.a := 354;

         { Assigning a restricted return value to a restricted object }
         { @@ Verify if this should really be allowed????? }
         r2 := AccessRestrictedRecord (r1);

         { Passing a restricted object to unrestericted formal parameter is ok }
         r2 := AccessRestrictedRecord (r2);

         {$ifdef BUG}
         { *** The following are illegal *** }
         r2.a := 100;    { field access }
         r1 := r2;       { assignment source is restricted }
         r2 := r1;       { assignment target is restricted }
         r1 := AccessRestrictedRecord (r2); { assigning a restricted return
                                               value to an unrestricted object }
         i  := 16#ffff;  { assignment target is restricted }
         k  := i + 2;    { arithmetic with restricted value }
         {$endif}
      end.

  ## How to declare simple and structured constants

  @@ simple constants missing

  - BP does not know initialized variables, only typed constants. Even worse, it allows them to be misused as variables, without even warning. GPC supports this (unwillingly ;-), and warns unless in ``--borland-pascal'` mode. An example of a typed constant:

        const
          i : Integer = 0;

    If you want to use it as a constant only, that's perfectly fine. However, if you modify ``i'`, we suggest to translate the declaration to an initialized variable. The EP syntax is:

        var
          i : Integer value 0;

    GPC supports this as well as the following mixtureof dialects:

        var
          i : Integer = 0;

    Furthermore, you can also assign initialization values to types:

        type
          MyInteger = Integer value 0;

        var
          i : MyInteger;

    Here, all variables of type MyInteger are automatically initialized to 0 when created.
  - Arrays initializers look like this in BP:

        const
          MyStringsCount = 5;

        type
          Ident = String [20];

        const
          MyStrings : array [1 .. MyStringsCount] of Ident =
            ('export', 'implementation', 'import',
             'interface', 'module');

    And the following way in EP:

        const
          MyStringsCount = 5;

        type
          Ident = String (20);

        var
          MyStrings : array [1 .. MyStringsCount] of Ident value
            [1 : 'export'; 2 : 'implementation'; 3 : 'import';
             4 : 'interface'; 5 : 'module'];

    There seem to be pros and cons to each style. GPC supports both as well as just about any thinkable mixture of them. Some folks don't like having to specify an index since it requires renumbering if you want to add a new item to the middle. However, if you index by an enumerated type, you might be able to avoid major renumbering by hand.

  ## Operators

  GNU Pascal supports all operators of ISO Pascal and Borland Pascal. In addition, you can define your own operators according to the Pascal-SC (PXSC) syntax.

  ### Built-in Operators

  The following table lists all built-in GNU Pascal operators, ordered by precedence: ``:='` has lowest precedence, ``not'` highest. As usual, the precedence of operators can be superseeded with parentheses.

      :=
      <    =    >    in   <>   >=   <=
      +    -    or   +<   -<   +>   ->
      *    /    div  mod  and  shl  shr  xor  *<   /<   *>   />
      pow  **
      not  &    @

  The Pascal-SC (PXSC) operators ``+<'`, ``-<'`, ``+>'`, ``->'`, ``*<'`, ``/<'`, ``*>'`, and ``/>'` are not yet implemented into GNU Pascal but may be defined by the user (see below).

  ### User-defined Operators

  GNU Pascal allows the (re-)definition of operators according to the Pascal-SC (PXSC) standard. The following vector addition example illustrates how to do this:

      program OperatorDemo;

      type
        Vector3 = record
          x, y, z : Real;
        end;

      var
        a, b, c : Vector3;

      operator + (u, v : Vector3) w : Vector3;
      begin
        w.x := u.x + v.x;
        w.y := u.y + v.y;
        w.z := u.z + v.z;
      end;

      begin
        c := a + b
      end.

  Between the closing parenthesis of the argument list and the result variable (``w'` in the above example), GPC allows an optional equal sign. This is not allowed in PXSC, but it is consistent with Extended Pascal's function return variable definitions, where the equal sign is obligatory (but also optional in GPC).

  The argument types needn't be equal, and the name of the operator may be an identifier instead of a known symbol. You cannot define new symbols in GPC.

  The PXSC operators ``+>'`, ``+<'`, etc. for exact numerical calculations currently are not implemented in GPC, but you can define them. Also, the other real-type operators do not meet the requirements of PXSC; a module which fixes that would be a welcome contribution.

  (And if you know more about modules in Pascal-SC than just their existence, please contact us as well! We could probably easily implement them if we knew how they look like. Something quite close to Pascal-SC modules already is implemented as "GNU specific modules".)

  ## Procedure And Function Parameters

  ### Parameters declared as ``protected'` or ``const'`

  All the following works in GPC:

      procedure Foo (protected a, b, c : Integer);    { 3 arguments }
      procedure Foo (a, b, c, protected : Integer);   { 4 arguments }
      procedure Foo (a, b, protected, c : Integer);   { 4 arguments }
      procedure Foo (protected : Integer);            { 1 argument  }
      procedure Foo (var protected : Integer);        { 1 argument  }
      procedure Foo (protected protected : Integer);  { 1 argument  }

  Furthermore, GPC supports `const`, according to BP, which is equivalent to either `protected` or `protected var`, up to the compiler's discretion.

  ### The Standard way to pass arrays of variable size

  (Under construction.)

  A feature of Standard Pascal level 1.

  ### BP's alternative to Conformant Arrays

  Borland Pascal "open array" formal parameters are implemented into GPC. Within the function body, they have integer type index with lower bound 0.

  In constrast to conformant arrays (which are not supported by BP), open arrays allow any ordinal type as the index of the actual parameter (which is useful, e.g., if you want to be able to pass values of any enumeration type). However, they lose information about the lower bound (which is a problem, e.g., if you want to return information to the caller that relates to the actual array index, like the function ``IOSelect'` in the Run Time System does).

  ## EP's Schema Types including ``String'`

  Schemata are types that depend on one or more variables, called discriminants. They are an ISO-10206 Extended Pascal feature.

      type
        RealArray (n : Integer) = array [1 .. n] of Real;
        Matrix (n, m : PositiveInteger) = array [1 .. n, 1 .. m] of Integer;

  The type ``RealArray'` in this example is called a Schema with the discriminant ``n'`.

  To declare a variable of such a type, write:

      var
        Foo : RealArray (42);

  The discriminants of every global or local schema variable are initialized at the beginning of the procedure, function or program where the schema variable is declared.

  Schema-typed variables "know" about their discriminants. Discriminants can be accessed just like record fields:

        Writeln (Foo.n); { yields 42 }

  Schemata may be passed as parameters. While types of schema variables must always have specified discriminants (which may be other variables), formal parameters (by reference or by value) may be of a schema type without specified discriminant. In this, the actual parameter may posses any discriminant. The discriminants of the parameters get their values from the actual parameters.

  Also, pointers to schema variables may be declared without a discriminant:

      type
        RealArrayPtr = ^RealArray;

      var
        bar : RealArrayPtr;

  When applying ``New'` to such a pointer, you must specify the intended value of the discriminant as a parameter:

        New (bar, 137);

  As a GNU Pascal extension, the above can also be written as

        bar := New (RealArrayPtr, 137);

  The allocated variable behaves like any other schema variable:

      var
        i : Integer;

      begin
        for i := 1 to Bar^.n do
          Bar^[i] := 42;
      end;

  Since the schema variable "knows" its size, pointers to schemata can be disposed just like other pointers:

        Dispose (Bar);

  Schemata are not limited to arrays. They can be of any type that normally requires constant values in its definition, for instance subrange types, or records containing arrays etc. (Sets do not yet work.)

  References to the schema discriminants are allowed, and the `with` statement is also allowed, so one can say:

      program WithSchemaDemo;
      type
        RealArray (n : Integer) = array [1 .. n] of Real;
      var
        MyArray : RealArray (42);
      begin
        Writeln (MyArray.n);  { writes 42 }
        with MyArray do
          Writeln (n);        { writes 42 }
      end.

  Finally, here is a somewhat exotic example. Here, a ``ColoredInteger'` behaves just like an ordinary integer, but it has an additional property ``Color'` which can be accessed like a record field.

      program ExoticSchemaDemo;

      type
        ColorType = (Red, Green, Blue);
        ColoredInteger (Color : ColorType) = Integer;

      var
        Foo : ColoredInteger (Green);

      begin
        Foo := 7;
        if Foo.Color = red then
          Inc (Foo, 2)
        else
          Foo := Foo div 3
      end.

  An important schema is the predefined ``String'` schema (according to Extended Pascal). It has one predefined discriminant identifier `Capacity`. GPC implements the `String` schema as follows:

      type
        String (Capacity : Cardinal) = record
          Length : Cardinal;
          Chars  : packed array [1 .. Capacity + 1] of Char
        end;

  The `Capacity` field may be directly referenced by the user, the `Length` field is referenced by a predefined string function `Length (Str)` and contains the current string length. `Chars` contains the chars in the string. The `Chars` and `Length` fields cannot be directly referenced by a user program.

  If a formal value parameter is of type ``String'` (with or without discriminant), the actual parameter may be either a `String` schema, a fixed string (character array), a single character, a string literal or a string expression. If the actual parameter is a ``String'` schema, it is copied for the parameter in the usual way. If it is not a schema, a ``String'` schema is created automatically, the actual parameter is copied to the new variable and the `Capacity` field of the new variable is set to the length of the actual parameter.

  Actual parameters to ``var'` parameters of type ``String'` must be ``String'` schemata, not string literals or character arrays.

      program StringDemo (Output);

      type
        SType = String (10);
        SPtr  = ^String;

      var
        Str  : SType;
        Str2 : String (100000);
        Str3 : String (20) value 'string expression';
        DStr : ^String;
        ZStr : SPtr;
        Len  : Integer value 256;
        Ch   : Char value 'R';

      { `String' accepts any length of strings }
      procedure foo (z : String);
      begin
        Writeln ('Capacity : ', z.Capacity);
        Writeln ('Length   : ', Length (z));
        Writeln ('Contents : ', z);
      end;

      { Another way to use dynamic strings }
      procedure Bar (SLen : Integer);
      var
        LString : String (SLen);
        FooStr  : type of LString;
      begin
        LString := 'Hello world!';
        Foo (LString);
        FooStr := 'How are you?';
        Foo (FooStr);
      end;

      begin
        Str  := 'KUKKUU';
        Str2 := 'A longer string variable';
        New (DStr, 1000);  { Select the string Capacity with `New' }
        DStr^ := 'The maximum length of this is 1000 chars';
        New (ZStr, Len);
        ZStr^ := 'This should fit here';
        Foo (Str);
        Foo (Str2);
        Foo ('This is a constant string');
        Foo ('This is a ' + Str3);
        Foo (Ch);  { A char parameter to string routine }
        Foo (");  { An empty string }
        Foo (DStr^);
        Foo (ZStr^);
        Bar (10000);
      end.

  In the above example, the predefined procedure `New` was used to select the capacity of the strings. Procedure `Bar` also has a string whose size depends of the parameter passed to it and another string whose type will be the same as the type of the first string, using the `type of` construct.

  All string and character types are compatible as long as the destination string is long enough to hold the source in assignments. If the source string is shorter than the destination, the destination is automatically blank padded if the destination string is not of string schema type.

  ## Pointer Arithmetics

  Address operator: The address operator is `@` in BP. Implemented into GPC as an alternative to `&`.

  GPC allows to increment, decrement, compare, and subtract pointers or to use them in ``for'` loops just like the C language.

        Var
          A: array [ 1..7 ] of Char;
          p, q: ^Char;
          i: Integer;

        [...]

        for p:= @A [ 1 ] to @A [ 7 ] do
          p^:= 'x';

        p:= @A [ 7 ];
        q:= @A [ 3 ];
        while p > q do
          begin
            p^:= 'y';
            dec ( p );
          end (* while *);

        p:= @A [ 7 ];
        q:= @A [ 3 ];
        i:= q - p;      (* yields 4 *)

  Incrementing a pointer by one means to increment the address it contains by the size of the variable it is pointing to. For typeless pointers (``Pointer'`), the address is incremented by one instead.

  Similar things hold when decrementing a pointer.

  Subtracting two pointers yields the number of variables pointed to between both pointers, i.e. the difference of the addresses divided by the size of the variables pointed to. The pointers must be of the same type.

  ## Type Casts

  In some cases, especially when interfacing with other languages, Pascal's strong typing can be an obstacle. To temporarily circumvent this, GPC (and other Pascal compilers) defines explicit "type casts".

  There are two kinds of type casts, value type casts and variable type casts.

  Value type casts

  To convert a value of one data type into another type, you can use the target type like the name of a function that is called. The value to be converted can be a variable or an expression.

  An example:

        Var
          Ch: Char;
          i: Integer;

        [...]

        i := Integer (Ch);

  Another, more complicated, example:

        Type
          CharPtr = ^Char;
          CharArray = array [ 0..99 ] of Char;
          CharArrayPtr = ^CharArray;

        Var
          Foo1, Foo2: CharPtr;
          Bar: CharArrayPtr;

        [...]

        {$X+} { We need extended syntax in order to use "Succ" on a pointer }

        Foo1 := CharPtr ( Bar );
        Foo2 := CharPtr ( Succ ( Bar ) );

  However, because of risks involved with type casts, explained below, you should try to avoid type casts whenever possible -- and it should be possible in most cases. For instance, the first example above could use the built-in function "Ord" instead of the type cast:

        i := Ord (Ch);

  The assignments in the second example could be written in the following way without any type casts:

        Foo1 := @Bar^ [ 0 ];
        Foo2 := @Bar^ [ 1 ];

  Value type casting only works between certain types: either between different ordinal types (including integer types), or between different real types, or between different pointer types. In each case, the actual value, i.e. the ordinal or numeric value or the address pointed to, respectively, is preserved in the cast.

  Note: It is also possible to cast from an integer into a real type. This is a consequence of the fact that integer values are generally automatically converted to real values when needed.

  Note: In the case of pointers, a warning is issued if the dereferenced target type requires a bigger alignment than the dereferenced source type (see section Alignment).

  Variable type casts

  It is also possible to temporarily change the type of a variable, without converting its contents in any way. This is called variable type casting.

  The syntax is the same as for value type casting. This can be confusing, as the example below shows.

  The type-casted variable is still the same variable (memory location) as the original one, just with a different type. Outside of the type cast, the variable keeps its original type.

  There are some important differences between value and variable type casting:

  - Variable type casting only works on variables, not on expressions.
  - The result of a variable type casting is still a variable. Especially, it can be used on the left side of an assignment (as a so-called "lvalue"), or passed by reference to a procedure.
  - No values are converted. The contents of the variable, seen as a raw bit pattern, are just interpreted according to the new type. In many cases, this does not make a big difference, e.g. the same ordinal values of different ordinal types have the same bit pattern (provided, the types have the same size), and similarly for different pointer types. However, there are cases where it does make a difference, most notably the completely different internal representation of integer and real types. This is demonstrated in the following example, admittedly a very constructed example, by using an integer and a real type of the same size and trying to cast between them.
  - Because bit patterns are just interpreted differently, the source and target type must have the same size. If this is not the case, GPC will give a warning. (@error? see below)
  - Beware: Variable type casts might have unexpected effects on different platforms since you cannot rely on a specific way the data is stored (e.g. see section Endianness).

        program TypeCastingTraps;

        { Declare a real type and an integer type of the same size, and some
          variables of these types we will need. }

        Type
          RealType    = ShortReal;
          IntegerType = Integer ( BitSizeOf ( RealType ) );

        Var
          i, i1, i2, i3, i4, i5: IntegerType;
          r, r1, r2, r3, r4:     RealType;

        begin

          { First part: Casting integer into real types. }

          { Start with some integer value }
          i := 42;

          { First attempt to cast. Here, an lvalue is casted, so this must
            be a variable type cast. Therefore, the bit pattern of the value
            of i is transferred unchanged into r1 which results in a silly
            value of r1. }
          IntegerType (r1) := i;

          { Second try. Here we cast an expression -- though a trivial one --,
            rather than a variable. So this can only be a value type cast.
            Therefore, the numeric value is preserved, i.e. r2 = 42.0 . }
          r2 := RealType (i+0);

          { Third way. In this last example, a variable is casted, and the
            result is used as an expression, not as an lvalue. So this
            could be either a value or variable type cast. However, there
            is a rule that value type casting is preferred if possible.
            So r3 will contain the correct numeric value, too. }
          r3 := RealType (i);

          { Of course, you do not need any casts at all here. A simple
            assignment will work because of the automatic conversion from
            integer to real types. So r4 will also get the correct result. }
          r4 := i;

          { Now the more difficult part: Casting real into integer types. }

          { Start with some real value. }
          r := 41.9;

          { Like the first attempt above, this one does a variable type cast,
            preserving bit patterns, and leaving a silly value in i1. }
          RealType (i1) := r;

          { The second try from above does not work, because an expression of
            type real is to be casted into an integer which is not allowed. }
          { i2 := IntegerType (r+0); }

          { Third way. This looks just like the third way in the first part
            which was a value type cast.
            But -- surprise! Since value type casting is not possible from
            real into integer, this really does a variable type casting,
            and the value of i3 is silly again! This difference in behaviour
            shows some of the hidden traps in type casting. }
          i3 := IntegerType (r);

          { As often, it is possible to avoid type casts altogether and
            convert real types into integers easily by other means, i.e. by
            using the built-in functions "Round" or "Trunc", depending
            on the mode of rounding one wants. }
          i4 := Round (r); { 42 }
          i5 := Trunc (r); { 41 }

        end.

  When dealing with objects (see section Object-orientated Programming), it is often necessary--and safe--to cast a pointer to an object into a pointer to a more specialized (derived) object. In future releases, GPC will provide an operator ``as'` for a safer approach to this problem.

  See also: section absolute, section Alignment, section Endianness, section Object-orientated Programming, section ord, section chr, section round, section trunc.

  ## Object-orientated Programming

  GNU Pascal follows the object model of Borland Pascal 7.0. The BP object extensions are almost fully implemented into GPC. This includes inheritance, virtual and non-virtual methods, constructors, destructors, pointer compatibility, extended `New' syntax (with constructor call and/or as a Boolean function), extended `Dispose' syntax (with destructor call).

  The Borland object model is different from the ISO draft, but it will not be too difficult now to implement that too (plus the Borland Delphi Object Extensions which are quite similar to the ISO draft).

  The syntax for an object type declaration is as follows:

      program ObjectDemo;

      type
        Str100 = String (100);

        FooParentPtr = ^fooParent;
        FooPtr = ^foo;

        FooParent = object
          constructor Init;
          destructor Done; virtual;
          procedure Bar (c : Real); virtual;
          function Baz (b, a, z : Char) : Str100;  { not virtual }
        end;

        Foo = object (FooParent)
          x, y : Integer;
          constructor Init (a, b : Integer);
          destructor Done; virtual;
          procedure Bar (c : Real); virtual;  { overrides `FooParent.Bar' }
          z : Real;  { GPC extension: data fields after methods }
          function Baz : Boolean;  { new function }
        end;

      constructor FooParent.Init;
      begin
        Writeln ('FooParent.Init')
      end;

      destructor FooParent.Done;
      begin
        Writeln ('I"m also done.')
      end;

      procedure FooParent.Bar (c : Real);
      begin
        Writeln ('FooParent.Bar (', c, ')')
      end;

      function FooParent.Baz (b, a, z : Char) = s : Str100;
      begin
        WriteStr (s, 'FooParent.Baz (', b, ', ', a, ', ', z, ')')
      end;

      constructor Foo.Init (a, b : Integer);
      begin
        inherited Init;
        x := a;
        y := b;
        z := 3.4;
        FooParent.Bar (1.7)
      end;

      destructor Foo.Done;
      begin
        Writeln ('I"m done.');
        inherited Done
      end;

      procedure Foo.Bar (c : Real);
      begin
        Writeln ('Foo.Bar (', c, ')')
      end;

      function Foo.Baz : Boolean;
      begin
        Baz := True
      end;

      var
        Ptr : FooParentPtr;

      begin
        Ptr := New (FooPtr, Init (2, 3));
        Ptr^.Bar (3);
        Dispose (Ptr, Done);
        New (Ptr, Init);
        with Ptr^ do
          Writeln (Baz ('b', 'a', 'z'))
      end.

  Remarks:

  - Data fields and methods can be mixed.
  - GPC currently does not support ``private'` declarations and such. These directives are syntactically accepted but ignored.
  - Constructors and destructors are ordinary functions, internally. When a constructor is called, GPC creates some inline code to initialize the object; destructors do nothing special.
  - Currently, the compiler does not check whether all declared methods are really implemented. Unimplemented methods will produce linking errors when they are called or if they are virtual.

  A pointer to ``FooParent'` may be assigned the address of a ``Foo'` object. A ``FooParent'` formal ``var'` parameter may get a ``Foo'` object as the actual parameter. In such cases, a call to a ``virtual'` method calls the child's method, whereas a call to a non-``virtual'` method selects the parent's one:

        var
          MyFooParent: FooParentPtr;
          SomeFoo: foo;

        [...]

        SomeFoo.Init ( 4, 2 );
        MyFooParent:= @SomeFoo;
        MyFooParent^.bar ( 3.14 );  (* calls `foo.bar' *)
        MyFooParent^.baz ( 'b', 'a', 'z' );  (* calls `fooParent.baz' *)
        if SomeFoo.baz then  (* calls `foo.baz' *)
          writeln ( 'Baz!' );

  In a method, an overwritten method of a parent object can be called either prefixing it with the parent type name, or using the keyword ``inherited'`:

        Procedure foo.bar ( c: Real );

        begin (* foo.bar *)
          z:= c;
          inherited bar ( z );  (* Or: fooParent.bar ( z ) *)
        end (* foo.bar *);

  Use ``fooParent.bar ( z )'` if you want to be sure that this method is called, even if somebody decides not to derive ``foo'` directly from ``fooParent'` but to have some intermediate object. If you want to call the method ``bar'` of the immediate parent--whether it be ``fooParent'` or whatever--use ``inherited bar ( z )'`.

  To allocate an object on the heap, use ``New'` in one of the following manners:

        Var
          MyFoo: fooPtr;

        [...]

        New ( MyFoo, Init ( 4, 2 ) );

        MyFooParent:= New ( fooPtr, Init ( 4, 2 ) );

  The second possibility has the advantage that ``MyFoo'` needn't be a ``fooPtr'` but can also be a ``fooParentPtr'`, i.e. a pointer to an ancestor of ``foo'`.

  Destructors can and should be called within Dispose:

        Dispose ( MyFooParent, Fini );

  ## Compiler Directives And The Preprocessor

  GPC, like UCSD and BP, treats comments beginning with a ``$'` immediately following the opening ``{'` or ``(*'` as a compiler directive. As in Borland Pascal, `{$...}` and `(*$...*)` are equivalent. When a single character plus a ``+'` or ``-'` follows, this is also called a compiler switch. All these directives are case-insensitive (but some of them have case-sensitive arguments). Directives are local and can change during one compilation (except include files etc. where this makes no sense).

  In general, compiler directives are compiler-dependent. (E.g., only the include directive `{$I FileName}` is common to UCSD and BP.) Because of BP's popularity, GPC supports all of BP's compiler directives (and ignores those that are unnecessary on its platforms -- these are those not listed below), but it knows a lot more directives.

  Some BP directives are -- of course not by chance -- just an alternative notation for C preprocessor directives. But there are differences: BP's conditional definitions (``{$define Foo}'`) go into another name space than the program's definitions. Therefore you can define conditionals and check them via `{$ifdef Foo}`, but the program will not see them as an identifier ``Foo'`, so macros do not exist in Borland Pascal.

  GPC does support macros, but disables this feature when the ``--no-macros'` option or the dialect option ``--borland-pascal'` or ``--delphi'` is given, to mimic BP's behaviour. Therefore, the following program will react differently when compiled with GPC without special options and with, e.g., the ``--borland-pascal'` option (and in the latter case, it behaves the same as when compiled with BP).

      program MacroDemo;

      const Foo = 'Borland Pascal';

      {$define Foo 'Default'}

      begin
        Writeln (Foo)
      end.

  Of course, you should not rely on such constructs in your programs. To test if the program is compiled with GPC, you can test the ``__GPC__'` conditional, and to test the dialect used in GPC, you can test conditionals like ``__BORLAND_PASCAL__'`.

  In general, almost every GPC specific command line option (see section GPC options besides those of GCC.) can be turned into a compiler directive:

      --foo       {$foo}
      --no-foo    {$no-foo}
      -Wbar       {$W bar}     { note the space after the `W' }
      -Wno-bar    {$W no-bar}

  The following table lists some such examples as well as all those directives that do not correspond to command-line options or have syntactical alternatives (for convenience and/or BP compatibility).

      --[no-]short-circuit   $B+ $B- like in Borland Pascal:
                                     $B- means short-circuit Boolean
                                     operators; $B+ complete evaluation

      --[no-]io-checking     $I+ $I- like in Borland Pascal:
                                     enable/disable I/O checking

      --[no-]stack-checking  $S+ $S- like in Borland Pascal:
                                     enable/disable stack checking

      --[no-]typed-address   $T+ $T- like in Borland Pascal:
                                     make the result of the address
                                     operator and the Addr function a
                                     typed or untyped pointer

      -W[no-]warnings        $W+ $W- enable/disable warnings. Note: in
                                     `--borland-pascal' mode, the
                                     short version is disabled because
                                     $W+/$W- has a different meaning in
                                     Borland Pascal (which can safely be
                                     ignored in GPC), but the long version
                                     is still available.

      --[no-]extended-syntax $X+ $X- mostly like in Borland Pascal:
                                     enable/disable extended syntax
                                     (ignore function return values,
                                     operator definitions, `PChar',
                                     pointer arithmetics, ...)

      --borland-pascal               disable or warn about GPC features
      --extended-pascal              not supported by the standard or
      --pascal-sc                    dialect given, do not warn about its
      etc.                           "dangerous" features (especially BP).
                                     The dialect can be changed during one
                                     compilation via directives like,
                                     e.g., `{$borland-pascal}'.

      {$M Hello!}                    write message `Hello!' to
                                     standard error during compilation. In
                                     `--borland-pascal' mode, it is
                                     ignored it if only numbers follow
                                     (for compatibility to Borland
                                     Pascal's memory directive)

      {$define FOO}                  like in Borland Pascal:
      or                             define FOO (for conditional compilation)
      {$CIDefine FOO}                (case-insensitively)

      --cidefine=FOO                 the same on the command line

      {$CSDefine FOO}                define FOO case-sensitively

      -D FOO                         the same on the command line
      or                             Note: `--define' on the command
      --csdefine=FOO                 line is case-sensitive like in GCC,
      or                             but `{$define}' in the source code
      --define=FOO                   is case-insensitive like in BP

      {$define loop while True do}   define `loop' to be `while True do'
      or                             as a macro like in C. The name of the
      {$CIDefine loop ...}           macro is case-insensitive. Note:
                                     Macros are disabled in
                                     `--borland-pascal' mode because BP
                                     doesn't support macros.

      --cidefine="loop=..."          the same on the command line

      {$CSDefine loop ...}           define a case-sensitive macro

      --csdefine="loop=..."          the same on the command line
      or
      --define="loop=..."

      {$I FileName}                  like in Borland Pascal:
                                     include `filename.pas' or `filename.p'
                                     (the name is converted to lowercase)

      {$undef FOO}                   like in Borland Pascal: undefine FOO

      {$ifdef FOO}                   conditional compilation
        ...                          (like in Borland Pascal).
      {$else}                        Note: GPC predefines the symbol
        ...                          `__GPC__' (with two leading
      {$endif}                       and trailing underscores).

      {$include "filename.pas"}      include (case-sensitive)

      {$include <filename.pas>}      the same, but don't search in the
                                     current directory

  ...and all the other C preprocessor directives.

  You also can use C-style preprocessor directives, e.g. ``#include'`, but this is deprecated, e.g. because of possible conflicts with Borland Pascal style ``#42'` character constants. Besides, in the Pascal style, e.g. ``{$include "foo.bar"}'`, there may be more than one directive in the same line.

  ## Routines Built-in or in the Run Time System

  In this section we describe the routines and other declarations that are built into the compiler or part of the Run Time System, sorted by topics.

  ### File Routines

  Extended Pascal treats files quite differently from Borland Pascal. GPC supports both forms, even in mixed ways, and provides many extensions.

  @@ A lot missing here

  - I've not worked with binary files enough, so no advice yet on how to access them, but you access them much the same. As last an example of getting the size of a file (though a ``FileSize'` function is already built-in).

        function FileSize(filename : String) : LongInt;
        var
          f : bindable file [0..MaxInt] of char;
          b : BindingType;
        begin
          unbind(f);
          b := binding (f);
          b.Name := filename;
          bind(f, b);
          b := binding(f);
          SeekRead(f, 0);
          if empty(f)
            then  file_size := 0
            else  file_size := LastPosition(f) + 1;
          unbind(f);
        end(*file_size*);

    Prospero's Extended Pascal has a bug in this case. Replace the MaxInt in the type definition of f by a sufficiently large integer. GNU Pascal works correct in this case.
  - GPC implements lazy text file I/O, i.e. does a `Put` as soon as possible and a `Get` as late as possible. This should avoid most of the problems sometimes considered to be the most stupid feature of Pascal. When passing a file buffer as parameter the buffer is validated when the parameter is passed.
  - GPC supports direct access files. E.g., declaring a type for a file that contains 100 integers.

        program DirectAccessFileDemo;
        type
          DFile = file [1 .. 100] of Integer;
        var
          F : DFile;
          P, N : 1 .. 100;
        begin
          Rewrite (F);
          P := 42;
          N := 17;
          SeekWrite (F, P);
          Write (F, N)
        end.

    The following direct access routines may be applied to a direct access file:
    `SeekRead (F, N); { Open file in inspection mode, seek to record N }`
    `SeekWrite (F, N); { Open file in generation mode, seek to record N }`
    `SeekUpdate (F, N); { Open file in update mode, seek to record N }`
    `Update (F); { Writes F^, position not changed. F^ kept. }`
    `p := Position (F); { Return current record number }`
    `p := LastPosition (F); { Return the last record number in file }`
    If the file is open for inspection or update, `Get` may be applied. If the file is open for generation or update, `Put` may be applied.
  - In BP, you can associate file variables with files using the ``Assign'` procedure which GPC supports.

        program AssignTextDemo;
        var
          t : Text;
          Line : String (4096);
        begin
          Assign (t, 'mytext.txt');
          Reset (t);
          while not EOF (t) do
            begin
              Readln (t, Line);
              Writeln (Line)
            end
        end.

  - In Extended Pascal, files are considered entities external to your program. External entities, which don't need to be files, need to be bound to a variable your program. Any variable to which external entities can be bound needs to be declared ``bindable'`. Extended Pascal has the ``Bind'` function that binds a variable to an external entity as well as ``Unbind'` to undo a binding and the function ``Binding'` to return the current binding of a variable. GPC supports these routines when applied to files. The compiler will reject binding of other object types. Only the fields ``Bound'` and ``Name'` of the predefined record type ``BindingType'` are required by Extended Pascal. Additionally, GPC implements some extensions. For the full definition of ``BindingType'`, see section BindingType. The following is an example of binding:

        program BindingDemo (Input, Output, f);

        var
          f : bindable Text;
          b : BindingType;

        procedure BindFile (var f : Text);
        var
          b : BindingType;
        begin
          Unbind (f);
          b := Binding (f);
          repeat
            Write ('Enter a file name: ');
            Readln (b.Name);
            Bind (f, b);
            b := Binding (f);
            if not b.Bound then
              Writeln ('File not bound -- try again.')
          until b.Bound
        end;

        begin
          BindFile (f);
          { Now the file f is bound to an external file. We can use the
            implementation defined fields of BindingType to check if the
            file exists and is readable, writable or executable. }
          b := Binding (f);
          Write ('The file ');
          if b.Existing then
            Writeln ('exists.')
          else
            Writeln ('does not exist.');
          Write ('It is ');
          if not b.Readable then Write ('not ');
          Write ('readable, ');
          if not b.Writable then Write ('not ');
          Write ('writable and ');
          if not b.Executable then Write ('not ');
          Writeln ('executable.')
        end.

  Note that Prospero's Pascal defaults to creating the file if it does not exists! You need to use Prospero's local addition of setting `b.Existing` to `True` to work-around this. GPC does not behave like this.

  ### String Operations

  In the following description, `s1` and `s2` may be arbitrary string expressions, `s` is a variable of string type.

  `WriteStr (s, write-parameter-list)`
  `ReadStr (s1, read-parameter-list)`
    Write to a string and read from a string. The parameter lists are identical to ``Write'`/``Read'` from `Text` files. The semantics is closely modeled after file I/O.
  `Index (s1, s2)`
    If `s2` is empty, return 1 else if `s1` is empty return 0 else returns the position of `s2` in `s1` (an integer).
  `Length (s1)`
    Return the length of `s1` (an integer from `0 .. s1.Capacity`).
  `Trim (s1)`
    Returns a new string with spaces stripped of the end of `s`.
  `SubStr (s1, i)`
  `SubStr (s1, i, j)`
    Return a new substring of `s1` that contains `j` characters starting from `i`. If `j` is missing, return all the characters starting from `i`.
  `EQ (s1, s2)`
  `NE (s1, s2)`
  `LT (s1, s2)`
  `LE (s1, s2)`
  `GT (s1, s2)`
  `GE (s1, s2)`
    Lexicographic comparisons of `s1` and `s2`. Returns a boolean result. Strings are not padded with spaces.
  `s1 = s2`
  `s1 <> s2`
  `s1 < s2`
  `s1 <= s2`
  `s1 > s2`
  `s1 >= s2`
    Lexicographic comparisons of `s1` and `s2`. Returns a boolean result. The shorter string is blank padded to length of the longer one, but only in ``--extended-pascal'` mode.

  GPC supports string catenation with the `+` operator or the ``Concat'` function. All string-types are compatible, so you may catenate any chars, fixed length strings and variable length strings.

      program ConcatDemo (Input, Output);

      var
        Ch   : Char;
        Str  : String (100);
        Str2 : String (50);
        FStr : packed array [1 .. 20] of Char;

      begin
         Ch := '$';
         FStr := 'demo';  { padded with blanks }
         Write ('Give me some chars to play with: ');
         Readln (Str);
         Str := '^' + 'prefix:' + Str + ':suffix:' + FStr + Ch;
         Writeln (Concat ('Le', 'ng', 'th'), ' = ', Length (Str));
         Writeln (Str)
      end.

  Note: The length of strings in GPC is limited only by the range of ``Integer'` (at least 32 bits, i.e., 2 GB), or the available memory, whichever is smaller. :-)

  When trying to write programs portable to other EP compilers, it is however save to assume a limit of about 32 KB. At least Prospero's Extended Pascal compiler limits strings to 32760 bytes. DEC Pascal limits strings to 65535 bytes.

  ### Accessing Command Line Arguments

  GPC supports access to the command line arguments with the BP compatible `ParamStr` and `ParamCount` functions.

  - `ParamStr [0]` is the program name,
  - `ParamStr [1] .. ParamStr [ParamCount]` are the arguments.

  The program below accesses the command line arguments.

      program CommandLineArgumentsDemo (Output);

      var
        Counter : Integer;

      begin
        Writeln ('This program displays command line arguments one per line.');
        for Counter := 0 to ParamCount do
          Writeln ('Command line arg ', Counter, ' is `', ParamStr (Counter), "")
      end.

  ### Memory Management Routines

  Besides the standard ``New'` and ``Dispose'` routines, GPC also allows BP style dynamic memory management with `GetMem` and `FreeMem`:

        GetMem (MyPtr, 1024);
        FreeMem (MyPtr, 1024);

  GPC also supports function style call to `GetMem`:

        MyPtr := GetMem (1024);

  (see also: `New` in context of Object Orientated Programming)

  One somehow strange feature of Borland is not supported: You cannot free parts of a variable with `FreeMem`, while the rest is still used and can be free later by another `FreeMem` call:

      type
        Vector = array [0 .. 1023] of Integer;
        VecPtr = ^Vector;

      var
        p, q : VecPtr;

        ...

        GetMem (p, 1024 * SizeOf (Integer));
        q := @p^[512];
        ...
        FreeMem (p, 512 * SizeOf (Integer));
        ...
        FreeMem (q, 512 * SizeOf (Integer));

  ### Operations for Integer and Ordinal Types

  - Bit manipulations: The BP style bit shift operators `shl` and `shr` exist in GPC as well as bitwise `and`, `or`, `xor` and `not` for integer values.

        2#100101 and (1 shl 5) = 2#100000

    GPC also supports `and`, `or`, `xor` and `not` as procedures:

        program BitOperatorProcedureDemo;
        var x : Integer;
        begin
          x := 7;
          and (x, 14);  { sets x to 6 }
          xor (x, 3);   { sets x to 5 }
        end.

  - Succ, Pred: The standard functions ``Succ'` and ``Pred'` exist in GPC and accept a second parameter.
  - Increment, decrement: The BP built-in Procedures `Inc` and `Dec` exist in GPC.

        program IncDecDemo;
        var
          i : Integer;
          c : Char;
        begin
          Inc (i);     { i := i + 1; }
          Dec (i, 7);  { i := i - 7; }
          Inc (c, 3);  { c := Succ (c, 3); }
        end.

  - `Min`, `Max`: These are a GNU extension and work for reals as well as for ordinal types. Mixing reals and integers is okay, the result is real then.

  ### Complex Number Operations

  @@ A lot missing here

  - binary operators `+, -, *, /` and unary `-, +`
  - exponentiation operators (`pow` and `**`)
  - functions (`Sqr, ArcTan, Sqrt, Exp, Ln, Sin, Cos`)
  - number info with `Re, Im` and `Arg` functions
  - numbers constructed by `Cmplx` or `Polar`

  The following sample programs illustrates most of the `Complex` type operations.

      program ComplexDemo (Output);

      var
        z1, z2 : Complex;
        Len, Angle : Real;

      begin
        z1 := Cmplx (2, 1);
        Writeln;
        Writeln ('Complex number z1 is: (', Re (z1) : 1, ',', Im (z1) : 1, ')');
        Writeln;
        z2 := Conjugate(z1); { GPC extension }
        Writeln ('Conjugate of z1 is: (', Re (z2) : 1, ',', Im (z2) : 1, ')');
        Writeln;
        Len   := Abs (z1);
        Angle := Arg (z1);
        Writeln ('The polar representation of z1 is: Length=', Len : 1,
                 ', Angle=', Angle : 1);
        Writeln;
        z2 := Polar (Len, Angle);
        Writeln ('Converting (Length, Angle) back to (x, y) gives: (',
                 Re (z2) : 1, ',', Im (z2) : 1, ')');
        Writeln;
        Writeln ('The following operations operate on the complex number z1');
        Writeln;
        z2 := ArcTan (z1);
        Writeln ('arctan (z1) = (', Re (z2), ', ', Im (z2), ')');
        Writeln;
        z2 := z1 ** 3.141;
        Writeln ('z1 ** 3.141 =', Re (z2), ', ', Im (z2), ')');
        Writeln;
        z2 := Sin (z1);
        Writeln ('sin (z1) = (', Re (z2), ', ', Im (z2), ')');
        Writeln ('(cos, ln, exp, sqrt and sqr exist also.)');
        Writeln;
        z2 := z1 pow 8;
        Writeln ('z1 pow 8 = (', Re (z2), ', ', Im (z2), ')');
        Writeln;
        z2 := z1 pow (-8);
        Writeln ('z1 pow (-8) = (', Re (z2), ', ', Im (z2), ')');
      end.

  ### Set Operations

  @@ A lot missing here

  GPC supports Standard Pascal set operations. In addition it supports the Extended Pascal set operation symmetric difference

  (`set1 >< set2`) operation whose result consists of those elements which are in exactly one of the operannds.

  It also has a function that counts the elements in the set: ``a := Card (set1)'`.

  ### Date And Time Routines

  `procedure GetTimeStamp (var t : TimeStamp);`
  `function Date (t : TimeStamp) : packed array [1 .. DateLength] of Char;`
  `function Time (t : TimeStamp) : packed array [1 .. TimeLength] of Char;`

  `DateLength` and `TimeLength` are implementation dependent constants.

  `GetTimeStamp (t)` fills the record ``t'` with values. If they are valid, the Boolean flags are set to True.

  `TimeStamp` is a predefined type in the Extended Pascal standard. It may be extended in an implementation, and is indeed extended in GPC. For the full definition of ``TimeStamp'`, see section TimeStamp.

  ## Interfacing with Other Languages

  The standardized GNU compiler back-end makes it relatively easy to share libraries between GNU Pascal and other GNU compilers. On UNIX-like platforms (not on Dos-like platforms), the GNU compiler back-end usually complies to the standards defined for that system, so communication with other compilers should be easy, too.

  In this chapter we discuss how to import libraries written in other languages, and how to import libraries written in GNU Pascal from other languages. While the examples will specialize to compatibility to GNU C, generalization is straightforward if you are familiar with the other language in question.

  ### Importing Libraries from Other Languages

  To use a function written in another language, you need to provide an external declaration for it--either in the program, or in the interface part of a Unit, or an Interface Module.

  Let's say you want to use the following C library from Pascal:

      File `callc.c':

      #include <unistd.h>
      #include "callc.h"

      int foo = 1;

      void bar (void)
      {
        sleep (foo);
      }

      File `callc.h':

      /* Actually, we wouldn't need this header file, and could instead
         put these prototypes into callc.c, unless we want to use callc.c
         also from other C source files. */

      extern int foo;
      extern void bar (void);

  Then your program can look like this:

      program CallCDemo;

      {$L callc.c}  { Or: `callc.o' if you don't have the source }

      var
        foo : Integer; asmname 'foo'; external;

      procedure Bar; asmname 'bar';

      begin
        foo := 42;
        Bar
      end.

  Or, if you want to provide a ``CallCUnit'` unit:

      unit CallCUnit;

      interface

      var
        foo : Integer; asmname 'foo'; external;

      procedure Bar; asmname 'bar';

      implementation

      {$L callc.c}  { Or: `callc.o' if you don't have the source }

      end.

      program CallCUDemo;

      uses CallCUnit;

      begin
        foo := 42;
        Bar
      end.

  You can either link your program manually with ``callc.o'` or put a compiler directive ``{$L callc.o}'` into your program or unit, and then GPC takes care of correct linking. If you have the source of the C library (you always have it if it is Free Software), you can even write ``{$L callc.c}'` in the program (like above). Then GPC will also link with ``callc.o'`, but in addition GPC will run the C compiler whenever ``callc.c'` has changed if ``--automake'` is given, too.

  While it is convenient for most applications, there is no must to give the C function ``bar'` the name ``Bar'` in Pascal; you can name it as you like.

  For external functions completely written in lowercase there is the shortcut ``C'` or ``C_language'` for ``asmname 'bar''`. For external functions written with one uppercase letter and the others in lowercase, you can use ``external'` or ``extern'` instead of ``asmname 'Bar''`. Since GPC internally converts all identifiers to this notation, ``external'` is the natural choice when importing other Pascal functions.

  Caution: This syntax (``C'`, ``asmname'` and such) is subject to change.

  It is important that data types of both languages are mapped correctly onto each other. C's ``int'`, for instance, translates to GPC's ``Integer'`, and C's ``unsigned long'` to ``MedCard'`. For a complete list of integer types with their C counterparts, see section Integer Types.

  In some cases it can be reasonable to translate a C pointer parameter to a Pascal ``var'` parameter. Since const parameters in GPC can be passed by value or by reference internally, possibly depending on the system, ``const foo *'` parameters to C functions cannot reliably declared as ``const'` in Pascal. However, Extended Pascal's ``protected var'` can be used since this guarantees passing by reference.

  Some libraries provide a ``main'` function and require your program's "main" to be named differently. To achive this with GPC, invoke it with an option ``--gpc-main="GPCmain"'` (where "GPCmain" is an example how you might want to name the program). You can also write it into your source as a directive ``{$pascal-main="GPCmain"}'`.

  ### Exporting GPC Libraries to Other Languages

  The ``.o'` files produced by GPC are in the same format as those of all other GNU compilers, so there is no problem in writing libraries for other languages in Pascal. To use them, you will need to write kind of interface--a header file in C. However there are some things to take into account, especially if your Pascal Unit exports objects:

  - By default, GPC capitalizes the first letter of each identifier, so ``Procedure FooBAR'` must be imported as ``extern void Foobar()'` from C.
  - If you want to specify the external name separately, use ``asmname'`:

          Procedure FooBAR; asmname 'FooBAR';
          (* Works like a `forward' declaration *)

          Procedure FooBAR;

          begin (* FooBAR *)
            writeln ( 'FooBAR' );
          end (* FooBAR *);

    This one can be imported from C with ``extern void FooBar()'`.
  - Objects are "records" internally. They have an implicit ``vmt'` field which contains a pointer to the "virtual method table". This table is another record of the following structure:

          Type
            SizeInt = Integer ( BitSizeOf ( Pointer ) );

            VMT = record
              ObjectSize: SizeInt;  (* Size of object in bytes. *)
              NegObjectSize: SizeInt;  (* Its negative. *)
              Fun: array [ 1..n ] of Procedure;
                (* Pointers to the virtual functions. *)
            end (* VMT *);

    You can call a virtual method of an object from C if you explicitly declare this ``struct'` and explicitly dereference the ``Fun'` array. The VMT of an object ``FooBAR'` is an external (in C sense) variable ``vmt_Foobar'` internally.
  - Methods of objects are named ``Myobject_Mymethod'` (with exactly two capital letters) internally.
  - The main program is just another procedure; ``Program FooBAR'` produces ``Procedure FooBAR; asmname 'program_Foobar''` (without parameters) internally. There is a separate function ``main'` which stores the command-line arguments in global variables and then calls this "main procedure".
  - If you want to put a program in a library for some reason, and you want to give the ``main'` program an internal name different from ``main'`, call GPC with the option ``--pascal-main="GPCmain"'` (see previous subsection).

  ## Notes for debugging

  - The GNU debugger, ``gdb'`, does not yet understand Pascal sets, files or subranges. Now ``gdb'` allows you to debug these things, even though it does not yet understand some stabs.
  - Forward referencing pointers generate debug info that appears as generic pointers.
  - No information of ``with'` statements is currently given to the debugger.
  - When debugging, please note that the Initial Letter In Each Identifier Is In Upper Case And The Rest Are In Lower Case, unless explicitly overriden with ``asmname'` (see section asmname) or a similar directive. This is to reduce name clashes with ``libc.a'` and other possible libraries.
  - All visible GPC runtime system library routines have linker names starting with ``_p_'`.
  - The main program name is preceeded by ``program_'`. For example, ``program foo'` yields the external name ``program_Foo'` for the main program. This is done because ISO Standard wants to have the program name in a separate name space.

  ## Run Time Library--Pascal Declarations

  Below is a Pascal source of the declarations in GPC's run time library. A file ``gpc.pas'` with the same contents is included in the GPC distribution in a ``units'` subdirectory of the directory containing ``libgcc.a'`. (To find out the correct directory for your installation, type ``gpc --print-file-name=units'` on the command line.)

      {
      Pascal declarations of the GPC RTS that are visible to each program.

      This unit contains Pascal declarations of many RTS routines which
      are not built into the compiler and can be called from programs.
      Don't copy the declarations from this unit into your programs, but
      rather include this unit with a `uses' statement. The reason is that
      the internal declarations, e.g. the `asmnames', may change, and this
      unit will be changed accordingly. @@In the future, this unit might
      be included into every program automatically, so there will be no
      need for a `uses' statement to make the declarations here available.

      Note about `protected var' parameters:
      Since const parameters in GPC may be passed by value *or* by
      reference internally, possibly depending on the system, `const foo*'
      parameters to C functions *cannot* reliably declared as `const' in
      Pascal. However, Extended Pascal's `protected var' can be used since
      this guarantees passing by reference.

      Copyright (C) 1998-2000 Free Software Foundation, Inc.

      Author: Frank Heckenbach <frank@pascal.gnu.de>

      This file is part of GNU Pascal.

      GNU Pascal is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2, or (at your option)
      any later version.

      GNU Pascal is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
      along with GNU Pascal; see the file COPYING.  If not, write to the
      Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
      02111-1307, USA.

      As a special exception, if you link this file with files compiled
      with a GNU compiler to produce an executable, this does not cause
      the resulting executable to be covered by the GNU General Public
      License. This exception does not however invalidate any other
      reasons why the executable file might be covered by the GNU General
      Public License.
      }

      {$gnu-pascal}

      module GPC interface;

      export
        GPC = all;
        GPC_SP = (eread (*@@not really, but an empty export doesn't
        work*));
        GPC_EP = (eread (*@@not really, but an empty export doesn't
        work*));
        GPC_BP = (MaxLongInt, ExitCode, ErrorAddr, Pos);
        GPC_Delphi = (MaxLongInt, Int64, ExitCode, ErrorAddr, Pos,
                      SetString, StringOfChar, TextFile, AssignFile,
                      CloseFile);

      const
        MaxLongInt = High (LongInt);

        { Maximum size of a variable }
        MaxVarSize = MaxInt;

      type
        Int64 = Integer (64);

      { ====================== MEMORY MANAGEMENT ======================= }

      { Heap manipulation, from heap.c }

      { GPC implements both Mark/Release and Dispose. Both can be mixed
        freely
        in the same program. Dispose should be preferred, since it's
        faster. }

      { C heap management routines. NOTE: if Release is used anywhere in
        the program, CFreeMem and CReAllocMem may not be used for pointers
        that were not allocated with CGetMem. }
      function  CGetMem     (Size : SizeType) : Pointer; asmname 'malloc';
      procedure CFreeMem    (aPointer : Pointer); asmname 'free';
      function  CReAllocMem (aPointer : Pointer; NewSize : SizeType) :
        Pointer; asmname 'realloc';

      type
        GetMemType     = ^function (Size : SizeType) : Pointer;
        FreeMemType    = ^procedure (aPointer : Pointer);
        ReAllocMemType = ^function (aPointer : Pointer; NewSize :
        SizeType) : Pointer;

      { These variables can be set to user-defined routines for memory
        allocation/deallocation. GetMemPtr may return nil when
        insufficient memory is available. GetMem/New will produce a
        runtime error then. }
      var
        GetMemPtr     : GetMemType; asmname '_p_getmem_ptr'; external;
        FreeMemPtr    : FreeMemType; asmname '_p_freemem_ptr'; external;
        ReAllocMemPtr : ReAllocMemType; asmname '_p_reallocmem_ptr';
        external;

        { Points to the lowest byte of heap used }
        HeapBegin : Pointer; asmname '_p_heap_begin'; external;

        { Points to the highest byte of heap used }
        HeapHigh  : Pointer; asmname '_p_heap_high'; external;

      const
        UndocumentedReturnNil = Pointer (- 1);

      procedure ReAllocMem (var aPointer : Pointer; NewSize : SizeType);
        asmname '_p_reallocmem';

      { Returns the number of pointers that would be released. aPointer
        must
        have been marked with Mark. For an example of its usage, see the
        HeapMon unit. }
      function  ReleaseCount (aPointer : Pointer) : Integer;
        asmname '_p_releasecount';

      { Routines to handle endianness, from endian.pas }

      { Boolean constants about endianness and alignment }

      const
        BitsBigEndian  = {$ifdef __BITS_LITTLE_ENDIAN__} False
                         {$else}{$ifdef __BITS_BIG_ENDIAN__} True
                         {$else}{$error Bit endianness is not defined!}
                         {$endif}{$endif};

        BytesBigEndian = {$ifdef __BYTES_LITTLE_ENDIAN__} False
                         {$else}{$ifdef __BYTES_BIG_ENDIAN__} True
                         {$else}{$error Byte endianness is not defined!}
                         {$endif}{$endif};

        WordsBigEndian = {$ifdef __WORDS_LITTLE_ENDIAN__} False
                         {$else}{$ifdef __WORDS_BIG_ENDIAN__} True
                         {$else}{$error Word endianness is not defined!}
                         {$endif}{$endif};

        NeedAlignment  = {$ifdef __NEED_ALIGNMENT__} True
                         {$else} False {$endif};

      { Convert single variables from or to little or big endian format.
        This only works for a single variable or a plain array of a simple
        type. For more complicated structures, this has to be done for
        each component separately! Currently, ConvertFromFooEndian and
        ConvertToFooEndian are the same, but this might not be the case on
        middle-endian machines. Therefore, we provide different names. }
      procedure ReverseBytes            (var Buf; ElementSize, Count :
        SizeType); asmname '_p_reversebytes';
      procedure ConvertFromLittleEndian (var Buf; ElementSize, Count :
        SizeType); asmname '_p_convertlittleendian';
      procedure ConvertFromBigEndian    (var Buf; ElementSize, Count :
        SizeType); asmname '_p_convertbigendian';
      procedure ConvertToLittleEndian   (var Buf; ElementSize, Count :
        SizeType); asmname '_p_convertlittleendian';
      procedure ConvertToBigEndian      (var Buf; ElementSize, Count :
        SizeType); asmname '_p_convertbigendian';

      { Read a block from a file and convert it from little or
        big endian format. This only works for a single variable or a
        plain array of a simple type, note the comment for
        `ConvertFromLittleEndian' and `ConvertFromBigEndian'. }
      (*@@iocritical*)procedure BlockReadLittleEndian   (var aFile : File;
        var   Buf; ElementSize, Count : SizeType);
        asmname '_p_blockread_littleendian';
      (*@@iocritical*)procedure BlockReadBigEndian      (var aFile : File;
        var   Buf; ElementSize, Count : SizeType);
        asmname '_p_blockread_bigendian';

      { Write a block variable to a file and convert it to little or big
        endian format before. This only works for a single variable or a
        plain array of a simple type. Apart from this, note the comment
        for `ConvertToLittleEndian' and `ConvertToBigEndian'. }
      (*@@iocritical*)procedure BlockWriteLittleEndian  (var aFile : File;
        const Buf; ElementSize, Count : SizeType);
        asmname '_p_blockwrite_littleendian';
      (*@@iocritical*)procedure BlockWriteBigEndian     (var aFile : File;
        const Buf; ElementSize, Count : SizeType);
        asmname '_p_blockwrite_bigendian';

      { Read and write strings from/to binary files, where the length is
        stored in the given endianness and with a fixed size (64 bits),
        and therefore is independent of the system. }
      (*@@iocritical*)procedure ReadStringLittleEndian  (var f : File; var
        s : String); asmname '_p_ReadStringLittleEndian';
      (*@@iocritical*)procedure ReadStringBigEndian     (var f : File; var
        s : String); asmname '_p_ReadStringBigEndian';
      (*@@iocritical*)procedure WriteStringLittleEndian (var f : File;
        const s : String); asmname '_p_WriteStringLittleEndian';
      (*@@iocritical*)procedure WriteStringBigEndian    (var f : File;
        const s : String); asmname '_p_WriteStringBigEndian';

      { =================== STRING HANDLING ROUTINES =================== }

      { String handling routines, from string.pas }

      type
        AnyFile = Text; (*@@ create `AnyFile' parameters*)
        PAnyFile = ^AnyFile;

      { TString is a string type that is used for function results and
        local variables, as long as undiscriminated strings are not
        allowed there. The default size of 2048 characters should be
        enough for file names on any system, but can be changed when
        necessary. It should be at least as big as MAXPATHLEN. }

      const
        TStringSize = 2048;
        SpaceCharacters = [' ', #9];
        NewLine = "\n"; { the separator of lines within a string }
        LineBreak = {$ifdef __OS_DOS__} "\r\n" {$else} "\n" {$endif};
        { the separator of lines within a file }

      type
        TString    = String (TStringSize);
        TStringBuf = packed array [0 .. TStringSize] of Char;
        PString    = ^String;
        CharSet    = set of Char;
        PCStrings  = ^TCStrings;
        TCStrings  = array [0 .. MaxVarSize div SizeOf (CString)] of
        CString;

      var
        CParamCount : Integer; asmname '_p_argc'; external;
        CParameters : PCStrings; asmname '_p_argv'; external;

      function  MemCmp      (const s1, s2; Size : SizeType) : Integer;
        asmname 'memcmp';
      function  MemComp     (const s1, s2; Size : SizeType) : Integer;
        asmname 'memcmp';
      function  MemCompCase (const s1, s2; Size : SizeType) : Boolean;
        asmname '_p_memcmpcase';

      procedure UpCaseString    (var s : String);
        asmname '_p_upcase_string';
      procedure LoCaseString    (var s : String);
        asmname '_p_locase_string';
      function  UpCaseStr       (const s : String) : TString;
        asmname '_p_upcase_str';
      function  LoCaseStr       (const s : String) : TString;
        asmname '_p_locase_str';

      function  IsUpCase        (ch : Char) : Boolean;
        attribute (const); asmname '_p_isupcase';
      function  IsLoCase        (ch : Char) : Boolean;
        attribute (const); asmname '_p_islocase';
      function  IsAlphaNum      (ch : Char) : Boolean;
        attribute (const); asmname '_p_isalphanum';
      function  IsAlphaNumUnderscore (ch : Char) : Boolean;
        attribute (const); asmname '_p_isalphanumunderscore';
      function  IsPrintable     (ch : Char) : Boolean;
        attribute (const); asmname '_p_isprintable';

      function  StrEqualCase    (const s1, s2 : String) : Boolean;
        asmname '_p_strequalcase';

      function  Pos             (const SubString, aString : String) :
        Integer; asmname '_p_pos';
      function  LastPos         (const SubString, aString : String) :
        Integer; asmname '_p_lastpos';
      function  PosCase         (const SubString, aString : String) :
        Integer; asmname '_p_poscase';
      function  LastPosCase     (const SubString, aString : String) :
        Integer; asmname '_p_lastposcase';
      function  CharPos         (const Chars : CharSet; const aString :
        String) : Integer; asmname '_p_charpos';
      function  LastCharPos     (const Chars : CharSet; const aString :
        String) : Integer; asmname '_p_lastcharpos';

      function  PosFrom         (const SubString, aString : String; From :
        Integer) : Integer; asmname '_p_posfrom';
      function  LastPosTill     (const SubString, aString : String; Till :
        Integer) : Integer; asmname '_p_lastpostill';
      function  PosFromCase     (const SubString, aString : String; From :
        Integer) : Integer; asmname '_p_posfromcase';
      function  LastPosTillCase (const SubString, aString : String; Till :
        Integer) : Integer; asmname '_p_lastpostillcase';
      function  CharPosFrom     (const Chars : CharSet; const aString :
        String; From : Integer) : Integer; asmname '_p_charposfrom';
      function  LastCharPosTill (const Chars : CharSet; const aString :
        String; Till : Integer) : Integer; asmname '_p_lastcharpostill';

      function  IsPrefix        (const Prefix, s : String) : Boolean;
        asmname '_p_isprefix';
      function  IsSuffix        (const Suffix, s : String) : Boolean;
        asmname '_p_issuffix';
      function  IsPrefixCase    (const Prefix, s : String) : Boolean;
        asmname '_p_isprefixcase';
      function  IsSuffixCase    (const Suffix, s : String) : Boolean;
        asmname '_p_issuffixcase';

      function  CStringLength      (Src : CString) : SizeType;
        asmname '_p_strlen';
      function  CStringEnd         (Src : CString) : CString;
        asmname '_p_strend';
      function  CStringNew         (Src : CString) : CString;
        asmname '_p_strdup';
      function  CStringComp        (s1, s2 : CString) : Integer;
        asmname '_p_strcmp';
      function  CStringCaseComp    (s1, s2 : CString) : Integer;
        asmname '_p_strcasecmp';
      function  CStringLComp       (s1, s2 : CString; MaxLen : SizeType) :
        Integer; asmname '_p_strlcmp';
      function  CStringLCaseComp   (s1, s2 : CString; MaxLen : SizeType) :
        Integer; asmname '_p_strlcasecmp';
      function  CStringCopy        (Dest, Source : CString) : CString;
        asmname '_p_strcpy';
      function  CStringCopyEnd     (Dest, Source : CString) : CString;
        asmname '_p_strecpy';
      function  CStringLCopy       (Dest, Source : CString; MaxLen :
        SizeType) : CString; asmname '_p_strlcpy';
      function  CStringMove        (Dest, Source : CString; Count :
        SizeType) : CString; asmname '_p_strmove';
      function  CStringCat         (Dest, Source : CString) : CString;
        asmname '_p_strcat';
      function  CStringLCat        (Dest, Source : CString; MaxLen :
        SizeType) : CString; asmname '_p_strlcat';
      function  CStringCharPos     (Src : CString; Ch : Char) : CString;
        asmname '_p_strscan';
      function  CStringLastCharPos (Src : CString; Ch : Char) : CString;
        asmname '_p_strrscan';
      function  CStringPos         (aString, SubString : CString) :
        CString; asmname '_p_strpos';
      function  CStringLastPos     (aString, SubString : CString) :
        CString; asmname '_p_strrpos';
      function  CStringCasePos     (aString, SubString : CString) :
        CString; asmname '_p_strcasepos';
      function  CStringLastCasePos (aString, SubString : CString) :
        CString; asmname '_p_strrcasepos';
      function  CStringUpCase      (s : CString) : CString;
        asmname '_p_strupper';
      function  CStringLoCase      (s : CString) : CString;
        asmname '_p_strlower';
      function  CStringIsEmpty     (s : CString) : Boolean;
        asmname '_p_strempty';
      function  NewCString         (const Source : String) : CString;
        asmname '_p_newcstring';
      function  CStringCopyString  (Dest : CString; const Source :
        String) : CString; asmname '_p_cstringcopystring';
      procedure CopyCString        (Source : CString; var Dest : String);
        asmname '_p_copycstring';

      function  NewString       (const s : String) : PString;
        asmname '_p_newstring';
      procedure DisposeString   (p : PString); asmname '_p_dispose';

      procedure SetString       (var s : String; Buffer : PChar; Count :
        Integer); asmname '_p_set_string';
      function  StringOfChar    (Ch : Char; Count : Integer) = s :
        TString; asmname '_p_string_of_char';

      procedure TrimLeft        (var s : String); asmname '_p_trimleft';
      procedure TrimRight       (var s : String); asmname '_p_trimright';
      procedure TrimBoth        (var s : String); asmname '_p_trimboth';
      function  TrimLeftStr     (const s : String) : TString;
        asmname '_p_trimleft_str';
      function  TrimRightStr    (const s : String) : TString;
        asmname '_p_trimright_str';
      function  TrimBothStr     (const s : String) : TString;
        asmname '_p_trimboth_str';

      function  GetStringCapacity (const s : String) : Integer;
        asmname '_p_get_string_capacity';

      { A short cut for a common use of WriteStr as a function }
      function  Integer2String (i : Integer) : TString;
        asmname '_p_Integer2String';

      type
        TChars = packed array [1 .. 1] of Char;
        PChars = ^TChars;

        { Under development. Interface subject to change. Use with
        caution. }
        { When a const or var AnyString parameter is passed, internally
          these records are passed as const parameters. Value AnyString
          parameters are passed like value string parameters. }
        ConstAnyString = record
          Length : Integer;
          Chars  : PChars
        end;

        { Capacity is the allocated space (used internally). Count is the
          actual number of environment strings. The CStrings array
          contains the environment strings, terminated by a nil pointer,
          which is not counted in Count. @CStrings can be passed to libc
          routines like execve which expect an environment (see
          GetCEnvironment). }
        PEnvironment = ^TEnvironment;
        TEnvironment (Capacity : Integer) = record
          Count : Integer;
          CStrings : array [1 .. Capacity + 1] of CString
        end;

      var
        Environment : PEnvironment; asmname '_p_environment'; external;

      { Get an environment variable. If it does not exist, GetEnv returns
        the empty string, which can't be distinguished from a variable
        with an empty value, while CStringGetEnv returns nil then. Note,
        Dos doesn't know empty environment variables, but treats them as
        non-existing, and does not distinguish case in the names of
        environment variables. However, even under Dos, empty environment
        variables and variable names with different case can now be set
        and used within GPC programs. }
      function  GetEnv (const EnvVar : String) : TString;
        asmname '_p_getenv';
      function  CStringGetEnv (EnvVar : CString) : CString;
        asmname '_p_cstringgetenv';

      { Sets an environment variable with the name given in VarName to the
        value
        Value. A previous value, if any, is overwritten. }
      procedure SetEnv (const VarName, Value : String);
        asmname '_p_setenv';

      { Un-sets an environment variable with the name given in VarName. }
      procedure UnSetEnv (const VarName : String); asmname '_p_unsetenv';

      { Returns @Environment^.CStrings, converted to PCStrings, to be
        passed to
        libc routines like execve which expect an environment. }
      function  GetCEnvironment : PCStrings; asmname '_p_getcenvironment';

      { ================= RUNTIME ERROR HANDLING ETC. ================== }

      { Error handling functions, from error.pas }

      const
        ERead = 413;
        EWrite = 414;
        EWriteReadOnly = 422;

      var
        { Error number (after runtime error) or exit status (after Halt)
        or
          0 (during program run and after succesful termination). }
        ExitCode : Integer; asmname '_p_exitcode'; external;

        { Contains the address of the code where a runtime occurred, nil
          if no runtime error occurred. }
        ErrorAddr : Pointer; asmname '_p_erroraddr'; external;

        { Error message }
        ErrorMessageString : TString; asmname '_p_errormessagestring';
        external;

      function  GetErrorMessage                 (n : Integer) : CString;
        asmname '_p_errmsg';
      procedure RuntimeError                    (n : Integer);
        attribute (noreturn); asmname '_p_error';
      procedure RuntimeErrorInteger             (n : Integer; i : MedInt);
        attribute (noreturn); asmname '_p_error_integer';
      procedure RuntimeErrorCString             (n : Integer; s :
        CString);                attribute (noreturn);
        asmname '_p_error_string';
      procedure InternalError                   (n : Integer);
        attribute (noreturn); asmname '_p_internal_error';
      procedure InternalErrorInteger            (n : Integer; i : MedInt);
        attribute (noreturn); asmname '_p_internal_error_integer';
      procedure RuntimeWarning                  (Message : CString);
        asmname '_p_warning';
      procedure RuntimeWarningInteger           (Message : CString; i :
        MedInt); asmname '_p_warning_integer';
      procedure RuntimeWarningCString           (Message : CString; s :
        CString); asmname '_p_warning_string';
      procedure DebugStatement                  (const FileName : String;
        Line : Integer); asmname '_p_debug_statement';

      (*iocritical*)procedure IOError                         (n :
        Integer); asmname '_p_io_error';
      (*iocritical*)procedure IOErrorInteger                  (n :
        Integer; i : MedInt); asmname '_p_io_error_integer';
      (*iocritical*)procedure IOErrorCString                  (n :
        Integer; s : CString); asmname '_p_io_error_string';
      (*iocritical*)procedure IOErrorFile                     (n :
        Integer; protected var f : AnyFile); asmname '_p_io_error_file';
      function  GetIOErrorMessage : CString;
        asmname '_p_get_io_error_message';
      procedure CheckInOutRes; asmname '_p_check_inoutres';

      { Registers a procedure to be called to restore the terminal for
        another process that accesses the terminal, or back for the
        program itself. Used e.g. by the CRT unit. The procedures must
        allow for being called multiple times in any order, even at the
        end of the program (see the comment for RestoreTerminal). }
      procedure RegisterRestoreTerminal (ForAnotherProcess : Boolean;
        procedure Proc); asmname '_p_RegisterRestoreTerminal';

      { Unregisters a procedure registered with RegisterRestoreTerminal.
        Returns False if the procedure had not been registered, and True
        if it had been registered and was unregistered successfully. }
      function UnregisterRestoreTerminal (ForAnotherProcess : Boolean;
        procedure Proc) : Boolean; asmname '_p_UnregisterRestoreTerminal';

      { Calls the procedures registered by RegisterRestoreTerminal. When
        restoring the terminal for another process, the procedures are
        called in the opposite order of registration. When restoring back
        for the program, they are called in the order of registration.

        `RestoreTerminal (True)' will also be called at the end of the
        program, before outputting any runtime error message. It can also
        be used if you want to write an error message and exit the program
        (especially when using e.g. the CRT unit). For this purpose, to
        avoid side effects, call RestoreTerminal immediately before
        writing the error message (to StdErr, not to Output!), and then
        exit the program (e.g. with Halt). }
      procedure RestoreTerminal (ForAnotherProcess : Boolean);
        asmname '_p_RestoreTerminal';

      { Executes a command line. Reports execution errors via the IOResult
        mechanism and returns the exit status of the executed program.
        Execute calls RestoreTerminal with the argument True before and
        False after executing the process, ExecuteNoTerminal does not. }
      (*@@IO critical*)function  Execute (const CmdLine : String) :
        Integer; asmname '_p_execute';
      (*@@IO critical*)function  ExecuteNoTerminal (const CmdLine :
        String) : Integer; asmname '_p_executenoterminal';

      procedure AtExit (procedure Proc); asmname '_p_atexit';

      procedure SetReturnAddress (Address : Pointer);
        asmname '_p_SetReturnAddress';
      procedure RestoreReturnAddress; asmname '_p_RestoreReturnAddress';

      { ==================== SIGNALS AND PROCESSES ===================== }

      function ProcessID : Integer; asmname '_p_pid';

      { Extract information from the status returned by PWait }
      function StatusExited     (Status : Integer) : Boolean; attribute
        (const); asmname '_p_WIfExited';
      function StatusExitCode   (Status : Integer) : Integer; attribute
        (const); asmname '_p_WExitStatus';
      function StatusSignaled   (Status : Integer) : Boolean; attribute
        (const); asmname '_p_WIfSignaled';
      function StatusTermSignal (Status : Integer) : Integer; attribute
        (const); asmname '_p_WTermSig';
      function StatusStopped    (Status : Integer) : Boolean; attribute
        (const); asmname '_p_WIfStopped';
      function StatusStopSignal (Status : Integer) : Integer; attribute
        (const); asmname '_p_WStopSig';

      type
        TSignalHandler = procedure (Signal : Integer);

      { OldHandler and OldRestart may be null }
      function InstallSignalHandler (Signal : Integer; Handler :
        TSignalHandler;
                                     Restart, UnlessIgnored : Boolean;
                                     var OldHandler : TSignalHandler; var
        OldRestart : Boolean) : Boolean; asmname '_p_sigaction';

      var
        { Signal actions }
        SignalDefault : TSignalHandler; asmname '_p_SIG_DFL'; external;
        SignalIgnore  : TSignalHandler; asmname '_p_SIG_IGN'; external;
        SignalError   : TSignalHandler; asmname '_p_SIG_ERR'; external;

        { Signals. The constants are set to the signal numbers, and
          are 0 for signals not defined. }
        { POSIX signals }
        SigHUp    : Integer; asmname '_p_SIGHUP'; external;
        SigInt    : Integer; asmname '_p_SIGINT'; external;
        SigQuit   : Integer; asmname '_p_SIGQUIT'; external;
        SigIll    : Integer; asmname '_p_SIGILL'; external;
        SigAbrt   : Integer; asmname '_p_SIGABRT'; external;
        SigFPE    : Integer; asmname '_p_SIGFPE'; external;
        SigKill   : Integer; asmname '_p_SIGKILL'; external;
        SigSegV   : Integer; asmname '_p_SIGSEGV'; external;
        SigPipe   : Integer; asmname '_p_SIGPIPE'; external;
        SigAlrm   : Integer; asmname '_p_SIGALRM'; external;
        SigTerm   : Integer; asmname '_p_SIGTERM'; external;
        SigUsr1   : Integer; asmname '_p_SIGUSR1'; external;
        SigUsr2   : Integer; asmname '_p_SIGUSR2'; external;
        SigChld   : Integer; asmname '_p_SIGCHLD'; external;
        SigCont   : Integer; asmname '_p_SIGCONT'; external;
        SigStop   : Integer; asmname '_p_SIGSTOP'; external;
        SigTStp   : Integer; asmname '_p_SIGTSTP'; external;
        SigTTIn   : Integer; asmname '_p_SIGTTIN'; external;
        SigTTOu   : Integer; asmname '_p_SIGTTOU'; external;

        { Non-POSIX signals }
        SigTrap   : Integer; asmname '_p_SIGTRAP'; external;
        SigIOT    : Integer; asmname '_p_SIGIOT'; external;
        SigEMT    : Integer; asmname '_p_SIGEMT'; external;
        SigBus    : Integer; asmname '_p_SIGBUS'; external;
        SigSys    : Integer; asmname '_p_SIGSYS'; external;
        SigStkFlt : Integer; asmname '_p_SIGSTKFLT'; external;
        SigUrg    : Integer; asmname '_p_SIGURG'; external;
        SigIO     : Integer; asmname '_p_SIGIO'; external;
        SigPoll   : Integer; asmname '_p_SIGPOLL'; external;
        SigXCPU   : Integer; asmname '_p_SIGXCPU'; external;
        SigXFSz   : Integer; asmname '_p_SIGXFSZ'; external;
        SigVTAlrm : Integer; asmname '_p_SIGVTALRM'; external;
        SigProf   : Integer; asmname '_p_SIGPROF'; external;
        SigPwr    : Integer; asmname '_p_SIGPWR'; external;
        SigInfo   : Integer; asmname '_p_SIGINFO'; external;
        SigLost   : Integer; asmname '_p_SIGLOST'; external;
        SigWinCh  : Integer; asmname '_p_SIGWINCH'; external;

        { Signal subcodes (only used on some systems, -1 if not used) }
        IllReservedAddress        : Integer; asmname '_p_ILL_RESAD_FAULT';
        external;
        IllPriviledgedInstruction : Integer;
        asmname '_p_ILL_PRIVIN_FAULT'; external;
        IllReservedOp             : Integer; asmname '_p_ILL_RESOP_FAULT';
        external;
        FPEIntegerOverflow        : Integer; asmname '_p_FPE_INTOVF_TRAP';
        external;
        FPEIntegerDivisionByZero  : Integer; asmname '_p_FPE_INTDIV_TRAP';
        external;
        FPESubscriptRange         : Integer; asmname '_p_FPE_SUBRNG_TRAP';
        external;
        FPERealOverflow           : Integer; asmname '_p_FPE_FLTOVF_TRAP';
        external;
        FPERealDivisionByZero     : Integer; asmname '_p_FPE_FLTDIV_TRAP';
        external;
        FPERealUnderflow          : Integer; asmname '_p_FPE_FLTUND_TRAP';
        external;
        FPEDecimalOverflow        : Integer; asmname '_p_FPE_DECOVF_TRAP';
        external;

      { Returns a description for a signal }
      function StrSignal (Signal : Integer) : TString;
        asmname '_p_strsignal';

      { Sends a signal to a process. Returns True if successful. If Signal
        is 0, it doesn't send a signal, but still checks whether it would
        be possible to send a signal to the given process. }
      function Kill (PID, Signal : Integer) : Boolean; asmname '_p_kill';

      const
        AnyChild = - 1;

      { Waits for a child process with the given PID (or any child process
        if PID = AnyChild) to terminate or be stopped. Returns the PID of
        the process. WStatus will contain the status and can be evaluated
        with StatusExited etc.. If nothing happened, and Block is False,
        the function will return 0, and WStatus will be 0. If an error
        occurred (especially on single tasking systems where WaitPID is
        not possible), the function will return a negative value, and
        WStatus will be 0. }
      function WaitPID (PID : Integer; var WStatus : Integer; Block :
        Boolean) : Integer; asmname '_p_waitpid';

      { Sets the process group of Process (or the current one if Process
        is 0) to ProcessGroup (or its PID if ProcessGroup is 0). Returns
        True if successful. }
      function SetProcessGroup (Process, ProcessGroup : Integer) :
        Boolean; asmname '_p_setpgid';

      { Sets the process group of a terminal given by Terminal (as a file
        handle) to ProcessGroup. ProcessGroup must be the ID of a process
        group in the same session. Returns True if successful. }
      function SetTerminalProcessGroup (Terminal, ProcessGroup :
        Integer) : Boolean; asmname '_p_tcsetpgrp';

      { Returns the process group of a terminal given by Terminal (as a
        file handle), or -1 on error. }
      function GetTerminalProcessGroup (Terminal : Integer) : Integer;
        asmname '_p_tcgetpgrp';

      { ================= COMMAND LINE OPTION PARSING ================== }

      const
        EndOfOptions      = #255;
        NoOption          = #1;
        UnknownOption     = '?';
        LongOption        = #0;
        UnknownLongOption = '?';

      var
        FirstNonOption         : Integer; asmname '_p_first_non_option';
        external;
        HasOptionArgument      : Boolean;
        asmname '_p_has_option_argument'; external;
        OptionArgument         : TString; asmname '_p_option_argument';
        external;
        UnknownOptionCharacter : Char;
        asmname '_p_unknown_option_character'; external;
        GetOptErrorFlag        : Boolean; asmname '_p_getopt_error_flag';
        external;

      {
        Parses command line arguments for options and returns the next
        one.

        If a command line argument starts with `-', and is not exactly `-'
        or `--', then it is an option element.  The characters of this
        element (aside from the initial `-') are option characters.  If
        `GetOpt' is called repeatedly, it returns successively each of the
        option characters from each of the option elements.

        If `GetOpt' finds another option character, it returns that
        character, updating `FirstNonOption' and internal variables so
        that the next call to `GetOpt' can resume the scan with the
        following option character or command line argument.

        If there are no more option characters, `GetOpt' returns
        EndOfOptions. Then `FirstNonOption' is the index of the first
        command line argument that is not an option. (The command line
        arguments have been permuted so that those that are not options
        now come last.)

        OptString must be of the form `[+|-]abcd:e:f:g::h::i::'.

        a, b, c are options without arguments
        d, e, f are options with required arguments
        g, h, i are options with optional arguments

        Arguments are text following the option character in the same
        command line argument, or the text of the following command line
        argument. They are returned in OptionArgument. If an option has no
        argument, OptionArgument is empty. The variable HasOptionArgument
        tells whether an option has an argument. This is mostly useful for
        options with optional arguments, if one wants to distinguish an
        empty argument from no argument.

        If the first character of OptString is `+', GetOpt stops at the
        first non-option argument.

        If it is `-', GetOpt treats non-option arguments as options and
        return NoOption for them.

        Otherwise, GetOpt permutes arguments and handles all options,
        leaving all non-options at the end. However, if the environment
        variable POSIXLY_CORRECT is set, the default behaviour is to stop
        at the first non-option argument, as with `+'.

        The special argument `--' forces an end of option-scanning
        regardless of the first character of OptString. In the case of
        `-', only `--' can cause GetOpt to return EndOfOptions with
        FirstNonOption <= ParamCount.

        If an option character is seen that is not listed in OptString,
        UnknownOption is returned. The unrecognized option character is
        stored in UnknownOptionCharacter. If you set GetOptErrorFlag to
        True, an error message is printed to StdErr automatically.
      }
      function GetOpt (OptString : CString) : Char; asmname '_p_getopt';

      type
        OptArgType = (NoArgument, RequiredArgument, OptionalArgument);

        OptionType = record
          Name     : CString;
          Argument : OptArgType;
          Flag     : ^Char;      { If nil, V is returned. Otherwise, Flag^
        is }
          V        : Char        { set to V, and Ord (LongOption) is
        returned. }
        end;

      {
        Recognize short options, described by OptString as above, and long
        options, described by LongOptions.

        Long-named options begin with `--' instead of `-'. Their names may
        be
        abbreviated as long as the abbreviation is unique or is an exact
        match
        for some defined option. If they have an argument, it follows the
        option name in the same argument, separated from the option name
        by
        a `=', or else the in next argument. When GetOpt finds a
        long-named
        option, it returns LongOption if that option's `Flag' field is
        non-nil,
        and the value of the option's `V' field if the `Flag' field is
        nil.

        LongIndex, if not null, returns the index in LongOptions of the
        long-named option found. It is only valid when a long-named option
        has
        been found by the most recent call.

        If LongOnly is set, `-' as well as `--' can indicate a long
        option.
        If an option that starts with `-' (not `--') doesn't match a long
        option,
        but does match a short option, it is parsed as a short option
        instead.
        If an argument has the form `-f', where f is a valid short option,
        don't
        consider it an abbreviated form of a long option that starts with
        `f'.
        Otherwise there would be no way to give the `-f' short option. On
        the
        other hand, if there's a long option `fubar' and the argument is
        `-fu',
        do consider that an abbreviation of the long option, just like
        `--fu',
        and not `-f' with argument `u'. This distinction seems to be the
        most
        useful approach.
      }
      function GetOptLong (OptString : CString; var LongOptions : array [m
        .. n : Integer] of OptionType { can be null };
                           var LongIndex : Integer { can be null };
        LongOnly : Boolean) : Char; asmname '_p_getopt_long';

      { =========================== PEXECUTE =========================== }

      const
        PExecute_First   = 1;
        PExecute_Last    = 2;
        PExecute_One     = PExecute_First or PExecute_Last;
        PExecute_Search  = 4;
        PExecute_Verbose = 8;

      {
        PExecute: execute a program.

        Program and Arguments are the arguments to execv/execvp.

        Flags and PExecute_Search is non-zero if $PATH should be searched
        (It's not clear that GCC passes this flag correctly). Flags and
        PExecute_First is nonzero for the first process in chain. Flags
        and PExecute_Last is nonzero for the last process in chain.

        The result is the pid on systems like Unix where we fork/exec and
        on systems like MS-Windows and OS2 where we use spawn. It is up to
        the caller to wait for the child.

        The result is the exit code on systems like MSDOS where we spawn
        and wait for the child here.

        Upon failure, ErrMsg is set to the text of the error message,
        and -1 is returned. `errno' is available to the caller to use.

        PWait: cover function for wait.

        PID is the process id of the task to wait for. Status is the
        `status' argument to wait. Flags is currently unused (allows
        future enhancement without breaking upward compatibility). Pass 0
        for now.

        The result is the process ID of the child reaped, or -1 for
        failure.

        On systems that don't support waiting for a particular child, PID
        is ignored. On systems like MSDOS that don't really multitask
        PWait is just a mechanism to provide a consistent interface for
        the caller.
      }
      function PExecute (ProgramName : CString; Arguments : PCStrings; var
        ErrMsg : String; Flags : Integer) : Integer;
        asmname '_p_pexecute';
      function PWait (PID : Integer; var Status : Integer; Flags :
        Integer) : Integer; C;

      { ==================== TIME HANDLING ROUTINES ==================== }

      { Time and date routines for Extended Pascal, from time.pas }

      const { from types.h }
        DateLength = 11;
        TimeLength = 8;

      type
        UnixTimeType = LongInt; { This is hard-coded in the compiler. Do
        not change here. }
        MicroSecondTimeType = LongInt;

        DateString = packed array [1 .. DateLength] of Char;
        TimeString = packed array [1 .. TimeLength] of Char;

      var
        MonthName : array [1 .. 12] of String [9]; asmname '_p_monthname';
        external;
        MonthLength : array [1 .. 12] of Integer;
        asmname '_p_monthlength'; external;

      function  GetDayOfWeek (Day, Month, Year : Integer) : Integer;
        asmname '_p_dayofweek';
      procedure UnixTimeToTimeStamp (UnixTime : UnixTimeType; var
        aTimeStamp : TimeStamp); asmname '_p_unix_time_to_time_stamp';
      function  TimeStampToUnixTime (protected var aTimeStamp :
        TimeStamp) : UnixTimeType; asmname '_p_time_stamp_to_unix_time';
      function  GetMicroSecondTime : MicroSecondTimeType;
        asmname '_p_get_micro_second_time';

      { Is the year a leap year? }
      function  IsLeapYear (Year : Integer) : Boolean;
        asmname '_p_is_leap_year';

      procedure Sleep (Seconds : Integer); asmname '_p_sleep';
      procedure SleepMicroSeconds (MicroSeconds : Integer);
        asmname '_p_sleep_microseconds';
      procedure UnixTimeToTime (UnixTime : UnixTimeType; var Year, Month,
        Day, Hour, Minute, Second : Integer);
        asmname '_p_unix_time_to_time';
      function  TimeToUnixTime (Year, Month, Day, Hour, Minute, Second :
        Integer) : UnixTimeType; asmname '_p_time_to_unix_time';

      { Get the real time. MicroSecond can be null and is ignored then. }
      function  GetUnixTime (var MicroSecond : Integer) : UnixTimeType;
        asmname '_p_get_unix_time';

      { Get the CPU time used. MicroSecond can be null and is ignored
        then.
        Now, GetCPUTime can measure long CPU times reliably on most
        systems
        (e.g. Solaris where it didn't work before). }
      function  GetCPUTime (var MicroSecond : Integer) : Integer;
        asmname '_p_get_cpu_time';

      { ==================== FILE HANDLING ROUTINES ==================== }

      { file routines, from files.pas }

      type
        FileSizeType = LongInt;

      { bind.c }

      procedure GetBinding   (protected var aFile : AnyFile; var
        aBinding : BindingType); asmname '_p_binding';
      procedure ClearBinding (var aBinding : BindingType);
        asmname '_p_clearbinding';

      { TFDD interface @@ Subject to change! Use with caution! }

      type
        TOpenMode   = (foNone, foReset, foRewrite, foAppend, foSeekRead,
        foSeekWrite, foSeekUpdate);
        TOpenProc   = procedure (var PrivateData; Mode : TOpenMode);
        TSelectFunc = function  (var PrivateData; Writing : Boolean) :
        Integer; { called before select(), must return a handle }
        TSelectProc = procedure (var PrivateData; var ReadSelect,
        WriteSelect, ExceptSelect : Boolean); { called before and after
        select() }
        TReadFunc   = function  (var PrivateData; var   Buffer; Size :
        SizeType) : SizeType;
        TWriteFunc  = function  (var PrivateData; const Buffer; Size :
        SizeType) : SizeType;
        TFileProc   = procedure (var PrivateData);
        TFlushProc  = TFileProc;
        TCloseProc  = TFileProc;
        TDoneProc   = TFileProc;

      procedure AssignTFDD (var f : AnyFile;
                            OpenProc    : TOpenProc;
                            SelectFunc  : TSelectFunc;
                            SelectProc  : TSelectProc;
                            ReadFunc    : TReadFunc;
                            WriteFunc   : TWriteFunc;
                            FlushProc   : TFlushProc;
                            CloseProc   : TCloseProc;
                            DoneProc    : TDoneProc;
                            PrivateData : Pointer);
        asmname '_p_assign_tfdd';

      procedure SetTFDD    (var f : AnyFile;
                            OpenProc    : TOpenProc;
                            SelectFunc  : TSelectFunc;
                            SelectProc  : TSelectProc;
                            ReadFunc    : TReadFunc;
                            WriteFunc   : TWriteFunc;
                            FlushProc   : TFlushProc;
                            CloseProc   : TCloseProc;
                            DoneProc    : TDoneProc;
                            PrivateData : Pointer); asmname '_p_set_tfdd';

      { Any parameter except f may be null }
      procedure GetTFDD    (var f : AnyFile;
                            var OpenProc    : TOpenProc;
                            var SelectFunc  : TSelectFunc;
                            var SelectProc  : TSelectProc;
                            var ReadFunc    : TReadFunc;
                            var WriteFunc   : TWriteFunc;
                            var FlushProc   : TFlushProc;
                            var CloseProc   : TCloseProc;
                            var DoneProc    : TDoneProc;
                            var PrivateData : Pointer);
        asmname '_p_get_tfdd';

      type
        Natural = 1 .. MaxInt;
        IOSelectEvents = (SelectReadOrEOF, SelectRead, SelectEOF,
        SelectWrite, SelectException, SelectAlways);

      const
        IOSelectEventMin = (*Low (IOSelectEvents);*)SelectReadOrEOF;
        IOSelectEventMax = Pred (SelectAlways);

      type
        IOSelectType = record
          f : PAnyFile;
          Wanted : set of IOSelectEvents;
          Occurred : set of IOSelectEventMin .. IOSelectEventMax
        end;

      { Waits for one of several events to happen. Returns when one or
        more of the wanted events for one of the files occur. If they have
        already occurred before calling the function, it returns
        immediately. MicroSeconds can specify a timeout. If it is 0, the
        function will return immediately, whether or not an event has
        occurred. If it is negative, the function will wait forever until
        an event occurs. The Events parameter can be null, in which case
        the function only waits for the timeout. If any of the file
        pointers (f) in Events are nil or the files pointed to are closed,
        they are simply ignored for convenience.

        It returns the index of one of the files for which any event has
        occurred. If events have occurred for several files, is it
        undefined which of these file's index is returned. If no event
        occurs until the timeout, 0 is returned. If an error occurs or the
        target system does not have a select() system call and Events is
        not null, a negative value is returned. In the Occurred field of
        the elements of Events, events that have occurred are set. The
        state of events not wanted is undefined.

        The possible events are:
        SelectReadOrEOF: the file is at EOF or data can be read now.
        SelectRead:      data can be read now.
        SelectEOF:       the file is at EOF.
        SelectWrite:     data can be written now.
        SelectException: an exception occurred on the file.
        SelectAlways:    if this is set, *all* requested events will be
                         checked for this file in any case. Otherwise,
                         checks may be skipped if already another event
                         for this or another file was found.

        Notes:
        Checking for EOF requires some reading ahead internally (just like
        the EOF function) which can be avoided by setting SelectReadOrEOF
        instead of SelectRead and SelectEOF. If this is followed by, e.g.,
        a BlockRead with 4 parameters, the last parameter will be 0 if and
        only the file is at EOF, and otherwise, data will be read directly
        from the file without reading ahead and buffering.

        SelectAlways should be set for files for which events are
        considered to be of higher priority than others. Otherwise, if one
        is interested in just any event, not setting SelectAlways may be a
        little faster. }
      function IOSelect (var Events : array [m .. n : Natural] of
        IOSelectType; MicroSeconds : MicroSecondTimeType) : Integer;
        asmname '_p_ioselect';

      { A simpler interface to SelectIO for the most common use. Waits for
        SelectReadOrEOF on all files and returns an index. }
      function IOSelectRead (const Files : array [m .. n : Natural] of
        PAnyFile; MicroSeconds : MicroSecondTimeType) : Integer;
        asmname '_p_ioselectread';

      procedure AssignFile   (var T : AnyFile; const Name : String);
        asmname '_p_assign';
      procedure AssignBinary (var T : Text; const Name : String);
        asmname '_p_assign_binary';
      procedure AssignHandle (var T : AnyFile; Handle : Integer);
        asmname '_p_assign_handle';

      { BP compatible seeking routines }
      function  SeekEOF  (var f : Text) : Boolean; asmname '_p_seekeof';
      function  SeekEOLn (var f : Text) : Boolean; asmname '_p_seekeoln';

      { Under development }
      procedure AnyStringTFDD_Reset (var f : AnyFile; var Buf :
        ConstAnyString); asmname '_p_anystring_tfdd_reset';
      (*procedure AnyStringTFDD_Rewrite (var f : AnyFile; var Buf :
        VarAnyString); asmname '_p_anystring_tfdd_rewrite';*)
      procedure StringTFDD_Reset (var f : AnyFile; var Buf :
        ConstAnyString; const s : String); asmname '_p_string_tfdd_reset';
      (*procedure StringTFDD_Rewrite (var f : AnyFile; var Buf :
        VarAnyString; var s : String); asmname '_p_string_tfdd_rewrite';*)

      { Generic file handling routines and their support, from file.c }

      { Flags that can be ORed into FileMode. The default value of
        FileMode is FileMode_Reset_ReadWrite. The somewhat confusing
        values are meant to be compatible to BP (as far as BP supports
        them). }
      const
        { Allow writing to files opened with Reset }
        FileMode_Reset_ReadWrite   = 2;

        { Do not allow reading from files opened with Rewrite }
        FileMode_Rewrite_WriteOnly = 4;

        { Do not allow reading from files opened with Extend }
        FileMode_Extend_WriteOnly  = 8;

      { File mode constants that are ORed for BindingType.Mode and ChMod.
        The values below are valid for all OSs (as far as supported). If
        the OS uses different values, they're converted internally. }
      const
        fmSetUID           = 8#4000;
        fmSetGID           = 8#2000;
        fmSticky           = 8#1000;
        fmUserReadable     = 8#400;
        fmUserWritable     = 8#200;
        fmUserExecutable   = 8#100;
        fmGroupReadable    = 8#40;
        fmGroupWritable    = 8#20;
        fmGroupExecutable  = 8#10;
        fmOthersReadable   = 8#4;
        fmOthersWritable   = 8#2;
        fmOthersExecutable = 8#1;

      type
        TextFile = Text;

        StatFSBuffer = record
          BlockSize, BlocksTotal, BlocksFree : LongestInt;
          FilesTotal, FilesFree : Integer
        end;

      procedure CloseFile    (          var aFile : (*@@Any*)File);
        asmname '_p_close';
      (*@@IO critical*) procedure ChMod        (          var aFile :
        AnyFile; Mode : Integer); asmname '_p_chmod';
      (*@@IO critical*) procedure StatFS       (Path : CString; var Buf :
        StatFSBuffer); asmname '_p_statfs';

      { Checks if data are available to be read from aFile. This is
        similar to
        `not EOF (aFile)', but does not block on "files" that can grow,
        like TTYs
        or pipes. }
      function  CanRead      (var aFile : AnyFile) : Boolean;
        asmname '_p_canread';

      { Get the file handle. }
      function  FileHandle   (protected var aFile : AnyFile) : Integer;
        asmname '_p_filehandle';

      { The following routine is meant *only* as a work-around for a
        problem under IRIX where writing reals with Write/Writeln/WriteStr
        does not work. This function will disappear after the problem has
        been solved. Width and Prec are the formatting parameters
        specified after `:'s in Write. If not wanted, NoWidth and
        NoPrecision can be passed. }
      const
        NoWidth = Low (Integer);
        NoPrecision = Low (Integer);
      function LongReal2Str (Num : LongReal; Width, Prec : Integer) :
        TString; asmname '_p_longreal2str';

      { File name routines, from filename.pas }

      {
        Define constants for different systems:

        OSDosFlag:         flag to indicate whether the target system is
                           Dos

        QuotingCharacter:  the character used to quote wild cards and
                           other special characters (#0 if not available)

        PathSeparator:     the separator of multiple paths, e.g. in the
                           PATH environment variable

        DirSeparator:      the separator of the directories within a full
                           file name

        DirSeparators:     a set of all possible directory and drive name
                           separators

        ExtSeparator:      the separator of a file name extension

        DirRoot:           the name of the root directory

        DirSelf:           the name of a directory in itself

        DirParent:         the name of the parent directory

        NullDeviceName:    the full file name of the null device

        TTYDeviceName:     the full file name of the current TTY

        ConsoleDeviceName: the full file name of the system console. On
                           Dos systems, this is the same as the TTY, but
                           on systems that allow remote login, this is a
                           different thing and may reach a completely
                           different user than the one running the
                           program, so use with care.

        EnvVarCharsFirst:  the characters accepted at the beginning of the
                           name of an environment variable without quoting

        EnvVarChars:       the characters accepted in the name of an
                           environment variable without quoting

        PathEnvVar:        the name of the environment variable which
                           (usually) contains the executable search path

        ShellEnvVar:       the name of the environment variable which
                           (usually) contains the path of the shell
                           executable (see GetShellPath)

        ShellExecCommand:  the option to the (default) shell to execute
                           the command specified in the following argument
                           (see GetShellPath)

        ConfigFileMask:    a mask for the option file name as returned by
                           ConfigFileName

        FileNamesCaseSensitive:
                           flag to indicate whether file names are case
                           sensitive
      }

      const
        UnixShellEnvVar        = 'SHELL';
        UnixShellExecCommand   = '-c';

      {$ifdef __OS_DOS__}

      const
        OSDosFlag              = True;
        QuotingCharacter       = #0;
        PathSeparator          = {$ifdef __CYGWIN32__} ':' {$else} ';'
        {$endif};
        DirSeparator           = '\';
        DirSeparators          = [':', '\', '/'];
        ExtSeparator           = '.';
        DirRoot                = '\';
        DirSelf                = '.';
        DirParent              = '..';
        NullDeviceName         = 'nul';
        TTYDeviceName          = 'con';
        ConsoleDeviceName      = 'con';
        EnvVarCharsFirst       = ['A' .. 'Z', 'a' .. 'z', '_'];
        EnvVarChars            = EnvVarCharsFirst + ['0' .. '9'];
        PathEnvVar             = 'PATH';
        ShellEnvVar            = 'COMSPEC';
        ShellExecCommand       = '/c';
        ConfigFileMask         = '*.cfg';
        FileNamesCaseSensitive = False;

      {$else}

      const
        OSDosFlag              = False;
        QuotingCharacter       = '\';
        PathSeparator          = ':';
        DirSeparator           = '/';
        DirSeparators          = ['/'];
        ExtSeparator           = '.';
        DirRoot                = '/';
        DirSelf                = '.';
        DirParent              = '..';
        NullDeviceName         = '/dev/null';
        TTYDeviceName          = '/dev/tty';
        ConsoleDeviceName      = '/dev/console';
        EnvVarCharsFirst       = ['A' .. 'Z', 'a' .. 'z', '_'];
        EnvVarChars            = EnvVarCharsFirst + ['0' .. '9'];
        PathEnvVar             = 'PATH';
        ShellEnvVar            = UnixShellEnvVar;
        ShellExecCommand       = UnixShellExecCommand;
        ConfigFileMask         = '.*';
        FileNamesCaseSensitive = True;

      {$endif}

      const
        WildCardChars = ['*', '?', '[', ']'];
        FileNameSpecialChars = (WildCardChars + SpaceCharacters +
        ['{', '}', '$', QuotingCharacter]) - DirSeparators;

      type
        DirPtr = Pointer;

        PPStrings = ^TPStrings;
        TPStrings (Count : Cardinal) = array [1 .. Count] of ^String;

        GlobBuffer = record
          Count    : Integer;
          Result   : PCStrings;
          Internal : Pointer
        end;

      { Convert ch to lower case if FileNamesCaseSensitive is False, leave
        it unchanged otherwise. }
      function  FileNameLoCase (ch : Char) : Char;
        asmname '_p_filenamelocase';

      { Change a file name to use the OS dependent directory separator }
      function  Slash2OSDirSeparator (const s : String) : TString;
        asmname '_p_slash2osdirseparator';

      { Change a file name to use '/' as directory separator }
      function  OSDirSeparator2Slash (const s : String) : TString;
        asmname '_p_osdirseparator2slash';

      { Like Slash2OSDirSeparator for CStrings -- NOTE: overwrites the
        CString }
      function  Slash2OSDirSeparator_CString (s : CString) : CString;
        asmname '_p_slash2osdirseparator_cstring';

      { Like OSDirSeparator2Slash for CStrings -- NOTE: overwrites the
        CString }
      function  OSDirSeparator2Slash_CString (s : CString) : CString;
        asmname '_p_osdirseparator2slash_cstring';

      { Add a DirSeparator to the end of s, if there is not already one
        and s denotes an existing directory }
      function  AddDirSeparator (const s : String) : TString;
        asmname '_p_adddirseparator';

      { Like AddDirSeparator, but also if the directory does not exist }
      function  ForceAddDirSeparator (const s : String) : TString;
        asmname '_p_forceadddirseparator';

      { Remove all trailing DirSeparators from s, if there are any, as
        long as removing them doesn't change the meaning (i.e., they don't
        denote the root directory. }
      function  RemoveDirSeparator (const s : String) : TString;
        asmname '_p_removedirseparator';

      { Returns the current directory using OS dependent directory
        separators }
      function  GetCurrentDirectory     : TString;
        asmname '_p_get_current_directory';

      { Returns a directory suitable for storing temporary files using OS
        dependent directory separators. If found, the result always ends
        in DirSeparator. If no suitable directory is found, an empty
        string is returned. }
      function  GetTempDirectory        : TString;
        asmname '_p_get_temp_directory';

      { Returns a non-existing file name in GetTempDirectory. If no temp
        directory is found, i.e. GetTempDirectory returns the empty
        string, a runtime error is raised. }
      (*@@iocritical*)function  GetTempFileName         : TString;
        asmname '_p_get_temp_file_name';

      { The same as GetTempFileName, but returns a CString allocated from
        the heap. }
      (*@@iocritical*)function  GetTempFileName_CString : CString;
        asmname '_p_get_temp_file_name_cstring';

      { Get the external name of a file }
      function  FileName (var f : AnyFile) : TString;
        asmname '_p_file_name';

      { Returns true if the given file name is an existing plain file }
      function  FileExists      (const aFileName : String) : Boolean;
        asmname '_p_file_exists';

      { Returns true if the given file name is an existing directory }
      function  DirectoryExists (const aFileName : String) : Boolean;
        asmname '_p_directory_exists';

      { Returns true if the given file name is an existing file, directory
        or special file (device, pipe, socket, etc.) }
      function  PathExists      (const aFileName : String) : Boolean;
        asmname '_p_path_exists';

      { If a file of the given name exists in one of the directories given
        in DirList (separated by PathSeparator), returns the full path,
        otherwise returns an empty string. If aFileName already contains
        an element of DirSeparators, returns Slash2OSDirSeparator
        (aFileName) if it exists. }
      function  FSearch (const aFileName, DirList : String) : TString;
        asmname '_p_fsearch';

      { Like FSearch, but only find executable files. Under Dos, if not
        found, the function tries appending '.com', '.exe' and '.bat', so
        you don't have to specify these extensions in aFileName (and with
        respect to portability, it might be preferable not to do so). }
      function  FSearchExecutable (const aFileName, DirList : String) :
        TString; asmname '_p_fsearch_executable';

      { Replaces all occurrences of `$FOO' and `~' in s by the value of
        the environment variables FOO or HOME, respectively. If a variable
        is not defined, the function returns False, and s contains the
        name of the undefined variable (or the empty string if the
        variable name is invalid, i.e., doesn't start with a character
        from EnvVarCharsFirst). Otherwise, if all variables are found, s
        contains the replaced string, and True is returned. }
      function  ExpandEnvironment (var s : String) : Boolean;
        asmname '_p_expand_environment';

      { Expands the given path name to a full path name. Relative paths
        are expanded using the current directory, and occurrences of
        DirSelf and DirParent are resolved. Under Dos, the result is
        converted to lower case and a trailing ExtSeparator (except in a
        trailing DirSelf or DirParent) is removed, like Dos does. If the
        directory, i.e. the path without the file name, is invalid, the
        empty string is returned. }
      function  FExpand       (const Path : String) : TString;
        asmname '_p_fexpand';

      { Like FExpand, but unquotes the directory before expanding it, and
        quotes WildCardChars again afterwards. Does not check if the
        directory is valid (because it may contain wild card characters).
        Symlinks are expanded only in the directory part, not the file
        name. }
      function  FExpandQuoted (const Path : String) : TString;
        asmname '_p_fexpandquoted';

      { FExpands Path, and then removes the current directory from it, if
        it is a prefix of it. If OnlyCurDir is set, the current directory
        will be removed only if Path denotes a file in, not below, it. }
      function  RelativePath (const Path : String; OnlyCurDir, Quoted :
        Boolean) : TString; asmname '_p_relative_path';

      { Is aFileName a UNC filename? (Always returns False on non-Dos
        systems.) }
      function  IsUNC (const aFileName : String) : Boolean;
        asmname '_p_IsUNC';

      { Splits a file name into directory, name and extension }
      procedure FSplit (const Path : String; var Dir, Name, Ext : String);
        asmname '_p_fsplit';

      { Functions that extract one or two of the parts from FSplit.
        DirFromPath returns DirSelf + DirSeparator if the path contains no
        directory. }
      function  DirFromPath     (const Path : String) : TString;
        asmname '_p_dir_from_path';
      function  NameFromPath    (const Path : String) : TString;
        asmname '_p_name_from_path';
      function  ExtFromPath     (const Path : String) : TString;
        asmname '_p_ext_from_path';
      function  NameExtFromPath (const Path : String) : TString;
        asmname '_p_name_ext_from_path';

      { Start reading a directory. If successful, a pointer is returned
        that can be used for subsequent calls to ReadDir and finally
        CloseDir. On failure, an I/O error is raised and (in case it is
        ignored) nil is returned. }
      (*@@iocritical*)function  OpenDir  (const Name : String) : DirPtr;
        asmname '_p_opendir';

      { Reads one entry from the directory Dir, and returns the file name.
        On errors or end of directory, the empty string is returned. }
      function  ReadDir  (Dir : DirPtr) : TString; asmname '_p_readdir';

      { Closes a directory opened with OpenDir. }
      (*@@iocritical*)procedure CloseDir (Dir : DirPtr);
        asmname '_p_closedir';

      { Returns the first position of a non-quoted character of CharSet in
        s, or 0 if no such character exists. }
      function  FindNonQuotedChar (Chars : CharSet; const s : String;
        From : Integer) : Integer; asmname '_p_findnonquotedchar';

      { Returns the first occurence of SubString in s that is not quoted
        at the beginning, or 0 if no such occurence exists. }
      function  FindNonQuotedStr (const SubString, s : String; From :
        Integer) : Integer; asmname '_p_findnonquotedstr';

      { Does a string contain non-quoted wildcard characters? }
      function  HasWildCards (const s : String) : Boolean;
        asmname '_p_haswildcards';

      { Does a string contain non-quoted wildcard characters, braces or
        spaces? }
      function  HasWildCardsOrBraces (const s : String) : Boolean;
        asmname '_p_haswildcardsorbraces';

      { Insert quoting QuotingCharacter into s before any special
        characters }
      function  QuoteFileName (const s : String; const SpecialCharacters :
        CharSet) : TString; asmname '_p_quote_filename';

      { Remove quoting QuotingCharacter from s }
      function  UnQuoteFileName (const s : String) : TString;
        asmname '_p_unquote_filename';

      { Splits s at non-quoted spaces and expands non-quoted braces like
        bash does. The result and its entries should be Disposed after
        usage. }
      function  BraceExpand (const s : String) : PPStrings;
        asmname '_p_braceexpand';

      { Tests if a file name matches a shell wildcard pattern (?, *, []) }
      function  FileNameMatch (const Pattern, Name : String) : Boolean;
        asmname '_p_filenamematch';

      { FileNameMatch with BraceExpand }
      function  MultiFileNameMatch (const Pattern, Name : String) :
        Boolean; asmname '_p_multifilenamematch';

      { File name globbing }
      { GlobInit is implied by Glob and MultiGlob, not by GlobOn and
        MultiGlobOn. GlobOn and MultiGlobOn must be called after GlobInit,
        Glob or MultiGlob. MultiGlob and MultiGlobOn do brace expansion,
        Glob and GlobOn do not. GlobFree frees the memory allocated by the
        globbing functions and invalidates the results in Buf. It should
        be called after globbing. }
      procedure GlobInit    (var Buf : GlobBuffer); asmname '_p_globinit';
      procedure Glob        (var Buf : GlobBuffer; Pattern : CString);
        asmname '_p_glob';
      procedure GlobOn      (var Buf : GlobBuffer; Pattern : CString);
        asmname '_p_globon';
      procedure MultiGlob   (var Buf : GlobBuffer; Pattern : String);
        asmname '_p_multiglob';
      procedure MultiGlobOn (var Buf : GlobBuffer; Pattern : String);
        asmname '_p_multiglobon';
      procedure GlobFree    (var Buf : GlobBuffer); asmname '_p_globfree';

      type
        TPasswordEntry = record
          UserName, RealName, Password, HomeDirectory, Shell : TString;
          UID, GID : Integer
        end;

        PPasswordEntries = ^TPasswordEntries;
        TPasswordEntries (Count : Integer) = array [1 .. Count] of
        TPasswordEntry;

      { Finds a password entry by user name. Returns True if found, False
        otherwise. }
      function  GetPasswordEntryByName (const UserName : String; var
        Entry : TPasswordEntry) : Boolean;
        asmname '_p_getpasswordentrybyname';

      { Finds a password entry by UID. Returns True if found, False
        otherwise. }
      function  GetPasswordEntryByUID  (UID : Integer; var Entry :
        TPasswordEntry) : Boolean; asmname '_p_getpasswordentrybyuid';

      { Returns all password entries, or nil if none found. }
      function  GetPasswordEntries : PPasswordEntries;
        asmname '_p_getpasswordentries';

      { Returns the mount point (Unix) or drive (Dos) which is part of the
        given path. If the path does not contain any (i.e., is a relative
        path), an empty string is returned. Therefore, if you want to get
        the mount point or drive in any case, apply `FExpand' or
        `RealPath' to the argument. }
      function  GetMountPoint (const Path : String) = Result : TString;
        asmname '_p_GetMountPoint';

      { Returns the path to the shell (as the return value) and the option
        that makes it execute the command specified in the following
        argument (in `Option'). Usually these are the environment value of
        ShellEnvVar, and ShellExecCommand, but on Dos systems, the
        function will first try UnixShellEnvVar, and UnixShellExecCommand
        because ShellEnvVar will usually point to command.com, but
        UnixShellEnvVar can point to bash which is usually a better choice
        when present. If UnixShellEnvVar is not set, or the shell given
        does not exist, it will use ShellEnvVar, and ShellExecCommand.
        Option may be null (in case you want to invoke the shell
        interactively). }
      function  GetShellPath (var Option : String) : TString;
        asmname '_p_GetShellPath';

      { Returns the path of the running executable. NOTE: On most systems,
        this is *not* guaranteed to be the full path, but often just the
        same as `ParamStr (0)' which usually is the name given on the
        command line. Only on some systems with special support, it
        returns the full path when `ParamStr (0)' doesn't. }
      function  ExecutablePath : TString; asmname '_p_executable_path';

      { Returns a file name suitable for a global (system-wide) or local
        (user-specific) configuration file, depending on the Global
        parameter. The function does not guarantee that the file name
        returned exists or is readable or writable.

        In the following table, the base name `<base>' is given with the
        Name parameter. If it is empty, the base name is the name of the
        running program (as returned by ExecutablePath, without directory
        and extension. `<prefix>' (Unix only) stands for the value of the
        Prefix parameter (usual values include ", '/usr' and
        '/usr/local'). `<dir>' (Dos only) stands for the directory where
        the running program resides. `$foo' stands for the value of the
        environment variable `foo'.

               Global                    Local
        Unix:  <prefix>/etc/<base>.conf  $HOME/.<base>

        Dos:   $DJDIR\etc\<base>.ini     $HOME\<base>.cfg
               <dir>\<base>.ini          <dir>\<base>.cfg

        As you see, there are two possibilities under Dos. If the first
        file exists, it is returned. Otherwise, if the second file exists,
        that is returned. If none of them exists (but the program might
        want to create a file), if the environment variable (DJDIR or
        HOME, respectively) is set, the first file name is returned,
        otherwise the second one. This rather complicated scheme should
        give the most reasonable results for systems with or without DJGPP
        installed, and with or without already existing config files. Note
        that DJDIR is always set on systems with DJGPP installed, while
        HOME is not. However, it is easy for users to set it if they want
        their config files in a certain directory rather than with the
        executables. }
      function  ConfigFileName (const Prefix, Name : String; Global :
        Boolean) : TString; asmname '_p_config_file_name';

      { Returns a directory name suitable for global, machine-independent
        data. The function garantees that the name returned ends with a
        DirSeparator, but does not guarantee that it exists or is
        readable or writable.

        Note: If the prefix is empty, it is assumed to be '/usr'. (If you
        really want /share, you could pass '/' as the prefix, but that's
        very uncommon.)

        Unix: <prefix>/share/<base>/

        Dos:  $DJDIR\share\<base>\
              <dir>\

        About the symbols used above, and the two possibilities under Dos,
        see the comments for ConfigFileName. }
      function  DataDirectoryName (const Prefix, Name : String) : TString;
        asmname '_p_data_directory_name';

      { ==================== MATHEMATICAL ROUTINES ===================== }

      function  IsInfinity   (x : Extended) : Boolean; attribute (const);
        asmname '_p_isinf';
      function  IsNotANumber (x : Extended) : Boolean; attribute (const);
        asmname '_p_isnan';
      procedure SplitReal    (x : Extended; var Exponent : Integer; var
        Mantissa : Extended); asmname '_p_frexp';
      function  SinH         (x : Double)    : Double; asmname '_p_sinh';
      function  CosH         (x : Double)    : Double; asmname '_p_cosh';
      function  Arctan2      (y, x : Double) : Double;
        asmname '_p_arctan2';

      type
        RandomSeedType = Cardinal (32);
        RandomizeType  = ^procedure;
        SeedRandomType = ^procedure (Seed : RandomSeedType);
        RandRealType   = ^function : LongestReal;
        RandIntType    = ^function (MaxValue : LongestCard) : LongestCard;

      var
        RandomizePtr  : RandomizeType; asmname '_p_randomize_ptr';
        external;
        SeedRandomPtr : SeedRandomType; asmname '_p_seedrandom_ptr';
        external;
        RandRealPtr   : RandRealType; asmname '_p_randreal_ptr'; external;
        RandIntPtr    : RandIntType; asmname '_p_randint_ptr'; external;

      procedure SeedRandom (Seed : RandomSeedType);
        asmname '_p_seedrandom';

      end.

  # From Borland Pascal to GNU Pascal

  This chapter is intended to be a QuickStart guide for programmers who are familiar with Borland Pascal, version 7 for Dos protected mode. Other versions don't differ too much but this one was the very last Dos version Borland has published.

  Throughout the documentation, we talk of "Borland Pascal" or "BP" for short. In most if not all cases, you can safely substitute "Turbo Pascal" if you like.

  ## BP Compatibility

  GNU Pascal (GPC) is compatible to version 7 of Borland Pascal (BP) to a large extent and comes with portable replacements of the Borland standard units.

  However, BP is a 16-bit compiler while GPC is a 32/64-bit compiler, so the size of the ``Integer'` type, for instance, is 16 bits in BP, but at least 32 bits in GPC. If a BP program has been designed with portability in mind from the ground up, it may work with GPC without any change. Programs which rely on byte order, on the internals or sizes of data types or which use unportable things like interrupts and assembler code, will need to be changed. The following section lists the possible problems with solutions.

  The GPC Run Time System (RTS) is fairly complete, and you can use all libraries written for GNU C from GNU Pascal, so there is much less need to use unportable constructs than there was in BP. (For example, BP's Turbo Vision library uses assembler to call a local procedure through a pointer. With GPC you can do this in Pascal just as with global procedures.) Please do not throw away the advantage of full portability by sticking to those workarounds.

  We have successfully ported real-world projects (with several 10000s of lines) from BP to GPC, so this is possible for you, too.

  ## BP Incompatibilities

  This sections lists the remaining incompatibilities of GPC to BP, and the problems you might encounter when porting BP programs from 16-bit Dos to other platforms, and gives solutions for them.

  By incompatibilites we mean problems that can arise when trying to compile a valid BP program with GPC. Of course, there are many features in GPC that BP doesn't know, but we call them extensions unless they can break valid BP programs, so they are not mentioned here. The subsequent sections of this chapter mention a number of useful extensions that you might want to know about but which will not break your BP code.

  - GPC's internal string format (Extended Pascal string schema) is different from BP's. BP compatible short strings will be implemented in GPC soon, but in the meantime, you'll have to live with the difference. In general, GPC's format has many advantages (no length limit of 255 characters, constant and reference parameters always know about their capacity, etc.), but you will see differences if you:
    - declare a variable as ``String'` without a capacity. However, GPC will assume 255 then (like BP) and only warn about it (and not even this when using ``--borland-pascal'`, see below), so that's not a real problem. The "clean" way, however, is to declare ``String [255]'` when you mean so (but perhaps you'll prefer ``String (2000)'`? :-).
    - access "character 0" which happens to hold the length in BP. This does not work with string schemata. Use ``Length'` to get the length, and ``SetLength'` to modify it.
    - try to read or write strings from/to binary files (``Text'` files are no problem). You will have to rewrite the code. If you also want to get rid of the 255 character limit and handle endianness issues (see below) in one go, you can use the ``ReadStringLittleEndian'` etc. routines (see section Run Time Library--Pascal Declarations), but if you need BP compatible strings (i.e., with a one-byte length field) in data files, you cannot use them (but you can easily modify them for this purpose).
  - GPC does not yet support qualified identifiers. They will be implemented soon. In the meantime, just don't use them, sorry. (In general, using the same identifier in different units can easily be confusing, so it's not bad practice to avoid this, anyway.)
  - GPC's inline assembler is not compatible to BP's. It uses AT&T syntax, supports a large variety of processors and works together with GPC's optimizer. So, either convert your inline assembly to AT&T syntax, or (usually better) to Pascal, or put it into an external file which you can assembler with your favourite (32 bit) assembler. A tutorial for using the GPC inline assembler is available from the same place where you got GPC itself in a subdirectory ``contrib'`, file ``gpcasm.zip'`. Since many things you usually do with assembler in BP are provided by GPC's Run Time System (RTS), you will not need the inline assembler as often as in BP. (See section Portability hints.) The same applies to BP's ``inline'` directive for hand-written machine code. GPC's ``inline'` directive works for Pascal routines (see section Miscellaneous), so you'll have to convert any hand-written machine code to Pascal (and thereby make it more readable, portable and easier to maintain while still getting the performance of inline code).
  - GPC does not support BP's 6-byte ``Real'` type. It supports ``Single'`, ``Double'` and ``Extended'` which, at least on the x86 and some other processors, are compatible to BP. For BP's 6-byte ``Real'` type, GPC's ``System'` unit provides an emulation, called ``BPReal'`, as well as conversion routines to GPC's ``Real'` type (which is the same as ``Double'`), called ``RealToBPReal'` and ``BPRealToReal'`. You'll probably only need them when reading or writing binary files containing values of the BP 6-byte real type. There are no operators (e.g., ``+'`) available for ``BPReal'`, but since GPC supports operator overloading, you could define them yourself (e.g., convert to ``Real'`, do the operation, and convert back). Needless to say that this is very inefficient and should not be done for any serious computations. Better convert your data after reading them from the file and before writing them back, or simply convert your data files once (the other types are more efficient even with BP on any non-prehistoric processor, anyway).
  - A BP compatible Graph unit exists but is distributed separately due to its license. It is known to work under DJGPP and Linux/x86, under development under Mingw, and should work under any Unix system with X11 (but only tested on a few systems).
  - The OOP stuff (Turbo Vision etc.) is not yet completed, but work on several projects is underway. If you want information about the current status or access to devlopment source, please contact the GPC mailing list.
  - A few routines in the Dos unit, namely ``Keep'`, ``GetIntVec'` and ``SetIntVec'`, do not even make sense on DJGPP (32 bit Dos extender). If your program uses these, it is either a low-level Dos utility for which porting to a 32 bit environment might cause bigger problems (because the internal issues of DPMI become relevant which are usually hidden by DJGPP), or it installs interrupt handlers which will have to be thought about more carefully because of things like locking memory, knowing about and handling the differences between real and protected mode interrupts etc. For this kind of things, we refer you to the DJGPP FAQ (see section `DJGPP FAQ' in the DJGPP FAQ).
  - Those few routines in the ``System'` unit that deal with segmented pointers (e.g., ``Ptr'`) are emulated in such a way that such ugly BP constructs like

        PInteger (Ptr (Seg (a), Ofs (a) + 6 * SizeOf (Integer)))^ = 42

    work in GPC, but they do not provide access to absolute memory addresses. Neither do ``absolute'` variables (which take a simple address in the program's address space in GPC, rather than a segmented address), and the ``Mem'` and ``Port'` arrays don't exist in GPC. As a replacement for ``Port'` on x86 processors, you can use the routines provided in the ``Ports'` unit. If you want to access absolute memory addresses in the first megabyte under DJGPP, you can't do this with normal pointers because DJGPP programs run in a protected memory environment, unless you use a dirty trick called near pointer hack. Please see the DJGPP FAQ for this and for other ways. For similar reasons, the variable ``PrefixSeg'` in the ``System'` unit is not supported. Apart from TSRs, its only meaningful use in BP might be the setting of environment variables. GPC provides the ``SetEnv'` and ``UnSetEnv'` procedures for this purpose which you can use instead of any BP equivalents based on ``PrefixSeg'`. (However note that they will set the program's own and its childs' environment, not its parent's environment. This is a property -- most people call it a feature -- of the environments, including DJGPP, that GPC compiled programs run in.)
  - GPC also runs on big-endian systems (see section Endianness). This is, of course, a feature of GPC, but might affect your programs when running on a big-endian system if they make assumptions about endianness, e.g., by using type casts (or ``absolute'` declarations or variant records misused as type casts) in certain ways. Please see the demo program ``absdemo.pas'` for an example and how to solve it. Endianness is also relevant (the more common case) when exchanging data between different machines, e.g. via binary files or over a network. Since the latter is not easily possible in BP, and the techniques to solve the problems are mostly the same as for files, we concentrate on files here. First, you have to choose the endianness to use for the file. Most known data formats have a specified endianness (usually that of the processor on which the format was originally created). If you define your own binary data format, you're free to choose the endianness to use. Then, when reading or writing values larger than one byte from/to the file, you have to convert them. GPC's Run Time System supports this by some routines. E.g., you can read an array from a little-endian file with the procedure ``BlockReadLittleEndian'`, or write one to a big-endian file with ``BlockWriteBigEndian'`. Note: The endianness in the procedure names refers to the file, not the system -- the routines know about the endianness of the system they run on, but you have to tell them the endianness of the file to use. This means you do not have to (and must not) use an ``ifdef'` to use the version matching the system's endianness. When reading or writing records or other more complicated structures, either read/write them field by field using ``BlockReadBigEndian'` etc., or read/write them with the regular ``BlockRead'` and ``BlockWrite'` procedures and convert each field after reading or before writing using procedures like ``ConvertFromBigEndian'` or ``ConvertToLittleEndian'` (but remember, when writing, to undo the conversion afterwards, if you want to keep using the data -- this is not necessary with ``BlockWriteLittleEndian'` etc.). Especially for strings, there are ready-made procedures like ``ReadStringBigEndian'` or ``WriteStringLittleEndian'` which will read/write the length as a 64 bit value (much space for really long strings :-) in the given endianness, followed by the characters (which have no endianness problem). All these routines are described in detail in the RTS reference (see section Run Time Library--Pascal Declarations), under ``endianness'`. The demo program ``endiandemo.pas'` contains an example on how to use these routines.

  The following differences can be "overcome" by command-line switches. As a summary:

      --borland-pascal -w --uses=System -D__BP_TYPE_SIZES__ --pack-struct
      -D__BP_RANDOM__ -D__BP_UNPORTABLE_ROUTINES__

  But please read the following items, and don't use these switches indiscriminately unless necessary. There are reasons why they are not GPC's defaults.

  - GPC warns about some BP contructs which are especially "dirty", like misusing typed constants as initialized variables. GPC also supports some features that may conflict with BP code, like macros. The command line option ``--borland-pascal'` disables both, so you might want to use it for a first attempt to compile your BP code under GPC. However, we suggest you try compiling without this switch and fixing any resulting problems as soon as you've become acquainted with GPC.
  - Even in ``--borland-pascal'` mode, GPC may warn about some dangerous things. To disable all warnings, you can use the ``-w'` option (note: lower-case ``w'`!). This is not recommended at all, but you may consider it more BP compatible...
  - A few exotic BP routines and declarations (e.g., ``Swap'` and ``HeapError'`) are contained in a ``System'` which GPC (unlike BP) does not automatically use in each program. To use it, you can add a `uses System;` statement to your code. If you don't want to change your code, the command line option ``--uses=System'` will do the same.
  - Since GPC runs on 32 and 64 bit platforms, integer types have larger sizes than in BP. However, if you use the ``System'` unit (see above) and define the symbol ``__BP_TYPE_SIZES__'` (by giving ``-D__BP_TYPE_SIZES__'` on the command line), it will redeclare the types to the sizes used by BP. This is less efficient and more limiting, but might be necessary if your program relies on the exact type sizes.
  - GPC by default aligns fields of records and arrays suitably for higher performance, while BP doesn't. If you don't want the alignment (e.g., because the program relies on the internal format of your structures), either declare the relevant structures as ``packed'` (which BP also accepts, but ignores), or give the ``--pack-struct'` option.
  - GPC uses a more elaborate pseudo random number generator than BP does. Using the ``Random'` and ``Randomize'` functions works the same way, but there is no ``RandSeed'` variable (but a ``SeedRandom'` procedure). However, if you use the ``System'` unit (see above) and define the symbol ``__BP_RANDOM__'` (by giving ``-D__BP_RANDOM__'` on the command line), it will provide a 100% BP compatible pseudo random number generator, including the ``RandSeed'` variable, which will produce exactly the same sequence of pseudo random numbers that BP's pseudo random number generator does. Even the ``Randomize'` function will behave exactly like in BP. However, this will not be noted unless one explicitly tests for it.
  - A few more routines in the ``Dos'` unit besides the ones mentioned above (e.g., ``Intr'`, ``DosVersion'` or ``SetVerify'`) are meaningless on non-Dos systems. By default, the ``Dos'` unit does not provide these routines, but only those that are meaningful on all systems (which are most of its routines, including the most commonly used ones). If you need the unportable ones, you get them by defining the symbol ``__BP_UNPORTABLE_ROUTINES__'` (by giving ``-D__BP_UNPORTABLE_ROUTINES__'` on the command line), but your program will only compile under DJGPP then. @end itemize

    ## IDE versus command line

    On the Dos (DJGPP) and Linux platforms, you can use the RHIDE for GNU Pascal; check the subdirectories of your DJGPP distribution.

    Unfortunately, there is no IDE which would run on all platforms. We are working on it, but this will take some time. Please be patient -- or offer your help!

    Without an IDE, the GNU Pascal Compiler, GPC, is called about like the command-line version of the Borland Pascal Compiler, BPC. Edit your source file(s) with your favorite ASCII editor, then call GNU Pascal with a command line like

          C:\GNU-PAS> gpc hello.pas -o hello.exe

    on your Dos or OS/2 box or

          myhost:/home/joe/gnu-pascal> gpc hello.pas -o hello

    on your Unix (or Unix-compatible) system.

    Don't omit the ``.pas'` suffix: GPC is a common interface for a Pascal compiler, a C, ObjC and C++ compiler, an assembler, a linker, and perhaps an Ada and a FORTRAN compiler. From the extension of your source file GPC figures out which compiler to run. GPC recognizes Pascal sources by the extension ``.pas'`, ``.p'`, ``.pp'` or ``.dpr'`.

    The `-o` is a command line option which tells GPC how the executable has to be named. If not given, the executable will be called ``a.out'` (Unix) or ``a.exe'` (Dos). However, you can use the ``--executable-file-name'` to tell GPC to always call the executable like the source (with the extension removed under Unix and changed to ``.exe'` under Dos).

    Note that GPC is case-sensitive concerning file names and options, so it will not work if you type

          C:\GNU-PAS> GPC HELLO.PAS -O HELLO.EXE

    GPC is a very quiet compiler and doesn't print anything on the screen unless you request it or there is an error. If you want to see what is going on, invoke GPC with additional options:

          -Q            "don't be quiet"  (or: Quassel-Modus in German)

    (with capital ``Q'`!) means that GPC prints out the names of procedures and functions it processes, and

          --verbose

    or abbreviated

          -v

    means that GPC informs you about the stages of compilation, i.e. preprocessing, compiling, assembling, and linking.

    One example (this time for OS/2):

          [C:\GNU-Pascal] gpc --verbose -Q hello.pas

    Throughout this chapter, we will tell you about a lot of command-line switches. They are all invoked this way.

    After compilation, there will be an executable `hello` file in the current directory. (`hello.exe` on Dos or OS/2.) Just run it and enjoy. If you're new to Unix, please note that the current directory is not on the PATH in most installations, so you might have to run your program as ``./hello'`. This also helps to avoid name conflicts with other programs. Such conflicts are especially common with the program name ``test'` which happens to be a standard utility under Unix that does not print any output. If you call your program ``test.pas'`, compile it, and then invoke ``test'`, you will usually not run your program, but the utility which leads to mysterious problems. So, invoke your program as ``./test'` or, better yet, avoid the name ``test'` for your programs.

    If there are compilation errors, GNU Pascal will not stop compilation after the first one -- as Borland Pascal does -- but try to catch all errors in one compilation. If you get more error messages than your screen can hold, you can catch them in a file (e.g. `gpc.out`) or pipe them to a program like ``more'` in the following way:

          gpc hello.pas 2> gpc.out

    This works with OS/2 and any bash-like shell under Unix; for Dos you must get a replacement for `command.com` which supports this kind of redirection, or use the ``redir'` utility (see also the DJGPP FAQ):

          C:\GNU-PAS> redir -eo gpc hello.pas -o hello.exe | more

    You can also use Borland's IDE for GNU Pascal on the Dos platform: Install the GNU Pascal Compiler in the Tools menu (via Options/Tools).

          Name:       GNU Pascal
          Path:       gpc
          Arguments:  $SAVE ALL --executable-file-name $NAME($EDNAME).pas
          HotKey:     Shift+F9

    Note once more that GPC is case-sensitive, so it is important to specify `.pas` instead of the `.PAS` Borland Pascal would append otherwise!

    You can include more command-line arguments to GNU Pascal (e.g. ``--automake'`; see below) as you will learn more about them.

    Since Borland Pascal will try to recompile your program if you use its `Run` menu function, you will need another tool to run your program:

          Name:       Run Program
          Path:       command.com
          Arguments:  /c $NAME($EDNAME)
          HotKey:     Shift+F10

    ## Comments

    According to the ISO 7185 and ISO 10206 standards, Pascal allows recognize comments opened with `(*` and closed with `}`. Borland Pascal does not support such mixed comments, so you might have sources where passages containing comments are "commented out". GPC's default behavior is (like BP) not to allow mixed comments, so you don't need to worry about this. However you can turn them on either by a command-line option, or by a compiler directive:

          --mixed-comments     {$mixed-comments}    (*$mixed-comments*)

    ## BP Compatible Compiler Directives

    All of BP's one-letter compiler directives are supported by GPC, though some of them are ignored because they are not necessary under GPC. Besides, GPC supports a lot more directives. For an overview, see section Compiler Directives And The Preprocessor.

    ## Units, GPI files and AutoMake

    You can use units in the same way as in Borland Pascal. However, there are some additional features.

    Concerning the syntax of a unit, you can, if you want, use Extended Pascal syntax to specify a unit initializer, i.e., instead of writing

          begin
            ...
          end.

    at the end of the unit, you can get the same result with

          to begin do
            begin
              ...
            end;

    and there also exists

          to end do
            begin
              ...
            end;

    which specifies a finalization routine. You can use this instead of Borland Pascal's exit procedures, but for compatibility, the included ``System'` unit also provides the ``ExitProc'` variable. The ``to begin do'` and/or ``to end do'` parts must be followed by the final ``end.'`. In section The Source Structure of ISO-10206 Extended Pascal Modules, you can find information about Extended Pascal Modules, an alternative to units.

    When GPC compiles a unit, it produces two files: an `.o` object file (compatible with other GNU compilers such as GNU C) plus a `.gpi` file which describes the interface.

    (See section GPI files--GNU Pascal Interfaces for GPI file internals.)

    If you want to compile a program that uses units, you must "make" the project. (This is the command-line switch ``-M'` or the IDE keystroke ``F9'` in BP.) For this purpose, GPC provides the command-line switch ``--automake'`:

          gpc --automake hello.pas

    If you want to force everything to be rebuilt rather than only recompile changed files (``-B'` or "build" in BP), use ``--autobuild'` instead of ``--automake'`:

          gpc --autobuild hello.pas

    For more information about the AutoMake mechanism, see section GPC's AutoMake Mechanism--How it Works.

    If you do not want to use the AutoMake mechanism for whatever reason, you can also compile every unit manually and then link everything together.

    GPC does not automatically recognize that something is a unit and cannot be linked; you have to tell this by a command line switch:

          -c            only compile, don't link.

    (If you omit this switch when compiling a unit, you only get a linker error message ``undefined reference to `main''`. Nothing serious.)

    For example, to compile two units, use:

          gpc -c myunit1.pas myunit2.pas

    When you have compiled all units, you can compile a program that uses them without using ``--automake'`:

          gpc hello.pas

    However, using ``--automake'` is recommended, since it will recompile units that were modified.

    You could also specify the program and the units in one command line:

          gpc hello.pas myunit1.pas myunit2.pas

    One of the purposes of writing units is to compile them separately. However, GNU Pascal allows you to have one or more units in the same source file (producing only one `.o` file but separate `.gpi` files). You even can have a Program and one or more units in one source file; in this case, no `.o` file is produced at all.

    ## Optimization

    GNU Pascal is a 32/64 bit compiler with excellent optimization algorithms (which are identically the same as those of GNU C). There are six optimization levels, specified by the command line options ``-O'`, ``-O2'`, ..., ``-O6'`.

    One example:

          program OptimizationDemo;

          procedure Foo;
          var
            A, B : Integer;
          begin
            A := 3;
            B := 4;
            Writeln (A + B)
          end;

          begin
            Foo
          end.

    When GNU Pascal compiles this program with optimization (``-O3'`), it recognizes that the argument to `Writeln' is the constant 7 -- and optimizes away the variables `A` and `B`. If the variables were global, they would not be optimized away because they might be accessed from other places, but the constant 7 would still be optimized.

    For more about optimization, see the GNU C documentation.

    ## Debugging

    The command line option ``-g'` specifies generation of debugging information for GDB, the GNU debugger. GDB comes with its own documentation. Currently, GDB does not understand Pascal syntax, so you should be familiar with C expressions if you want to use it.

    See also "Notes for debugging" in the "Programming" chapter; see section Notes for debugging.

    Sometimes it is nice to have a look at the assembler output of the compiler. You can do this in a debugger or disassembler (which is the only way to do it in BP), but you can also tell GPC to produce assembler code directly: When you specify the `-S` command line option, GPC produces an `.s` file instead of an `.o` file. The `.s` file contains assembler source for your program. More about this in the next section.

    ## Objects

    Objects in the Borland Pascal 7.0 notation are implemented into GNU Pascal with the following differences:

    - the ``private'`, ``protected'`, ``public'` and ``published'` directives are recognized but ignored,
    - data fields and methods may be mixed:

            MyObj = object
              x : Integer;
              procedure Foo; virtual;
              y : Real;
              Function Bar : Char;
            end;

    ## Strings

    Strings are "Schema types" in GNU Pascal which is something more advanced than Borland-style strings. For variables, you cannot specify just `String` as a type like in Borland Pascal; for parameters and pointer types you can. There is no 255 characters length limit. According to Extended Pascal, the maximum string length must be in (parentheses); GNU Pascal accepts [brackets], too, however, like BP.

    For more about strings and schema types see section EP's Schema Types including ``String'`.

    GPC supports Borland Pascal's string handling functions and some more (see section String Operations):

    @multitable {xxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}

  - Borland Pascal @tab GNU Pascal
  - Length @tab Length
  - Pos @tab Pos, Index (1)
  - Str @tab Str, WriteStr (1) (2)
  - Val @tab Val, ReadStr (2)
  - Copy @tab Copy, SubStr, MyStr [2 .. 7] (3)
  - Insert @tab Insert
  - Delete @tab Delete
  - MyStr [0] := #7 @tab SetLength (MyStr, 7)
  - =, <>, <, <=, >, >= @tab =, <>, <, <=, >, >= (4)
  - @tab EQ, NE, LT, LE, GT, GE
  - n/a @tab Trim Notes: (1) The order of parameters of the Extended Pascal routines (``Index'`, ``WriteStr'`) is different from the Borland Pascal routines. (2) ``ReadStr'` and ``WriteStr'` allow an arbitrary number of arguments, and the arguments are not limited to numbers. ``WriteStr'` also allows comfortable formatting like ``Writeln'` does, e.g. ``WriteStr (Dest, Foo : 20, Bar, 1/3 : 10 : 2)'`. (3) ``SubStr'` reports a runtime error if the requested substring does not fit in the given string, ``Copy'` does not (like in BP). (4) By default, the string operators behave like in BP. However, if you use the option ``--no-exact-compare-strings'`, they ignore differences of trailing blanks, so, e.g., ``'foo''` and ``'foo ''` are considered equal. The corresponding functions (``EQ'`, ...) always do exact comparisons.

    ## Typed Constants

    GNU Pascal supports Borland Pascal's "typed constants" but also Extended Pascal's initialized variables:

          var
            x : Integer value 7;

    or

          var
            x : Integer = 7;

    When a typed constant is misused as an initialized variable, a warning is given unless you specify ``--borland-pascal'`.

    When you want a local variable to preserve its value, define it as ``static'` instead of using a typed constant. Typed constants also become static automatically for Borland Pascal compatibility, but it's better not to rely on this "feature" in new programs. Initialized variables do not become static automatically.

          procedure Foo;
          var
            x: static Real;
          begin
            { x keeps its value between two calls to this procedure }
          end;

    For records and arrays, GPC supports both BP style and Extended Pascal style initializers. When you initialize a record, you may omit the field names. When you initialize an array, you may provide indices with a `:`. However, this additional information is ignored completely, so perhaps it's best for the moment to only provide the values ...

        const
          A : Integer = 7;
          B : array [1 .. 3] of Char = ('F', 'o', 'o');
          C : array [1 .. 3] of Char = 'Bar';
          Foo : record
            x, y : Integer;
          end = (x : 3; y : 4);

    ## Bit, Byte and Memory Manipulation

    The bitwise operators ``shl'`, ``shr'`, ``and'`, ``or'`, ``xor'` and ``not'` work in GNU Pascal like in Borland Pascal. As an extension, you can use them as procedures, for example

          and (x, $0000ffff);

    as an alternative to

          x := x and $0000ffff;

    GPC accepts the BP style notation ``$abcd'` for hexadecimal numbers, but you also can use Extended Pascal notation:

           2#11111111  for a binary number,
           8#177       for an octal number,
          16#ff        for a hexadecimal number,

    and so on up to a basis of 36. Of course, you can mix the notations as you like, e.g.:

        program BPEPBaseDemo;
        begin
          Writeln ($cafe = 2#1100101011111110)
        end.

    ``Inc'` and ``Dec'` are implemented like in Borland Pascal. ``Pred'` and ``Succ'` are generalized according to Extended Pascal and can have a second (optional) parameter:

          a := Succ (a, 5);

    BP style ``absolute'` variables work in the context of overloading other variables as well as in the context of specifying an absolute address, but the latter is highly unportable and not very useful even in Dos protected mode.

        (* WARNING: BAD STYLE! *)
        procedure ReadVar (var x : Void; TypeChoice : Char);
        var
          xInt : Integer absolute x;
          xChar : Char absolute x;
          xStr : String (80) absolute x;
        begin
          ...
        end;

    GNU Pascal knows Borland Pascal's procedures `FillChar` and `Move`. However, their use can be dangerous because it often makes implicit unportable assumptions about type sizes, endianness, internal structures or similar things. Therefore, avoid them whenever possible. E.g., if you want to clear an array of strings, don't ``FillChar'` the whole array with zeros (this would overwrite the Schema discriminants, see section Strings), but rather use a ``for'` loop to assign the empty string to each string. In fact, this is also more efficient than ``FillChar'`, since it only has to set the length field of each string to zero.

    ## User-defined Operators in GPC

    GNU Pascal allows the user to define operators according to the Pascal-SC syntax:

          type
            Point = record
              x, y : Real;
            end;

          operator + (a, b : Point) c : Point;
          begin
            c.x := a.x + b.x;
            c.y := a.y + b.y;
          end;

    The Pascal-SC operators ``+>'`, ``+<'`, etc. for exact numerical calculations are not implemented, but you can define them.

    (And if you know more about modules in Pascal-SC than just their existence, please contact us as well! We could probably easily implement them if we knew how they look like. Something quite close to Pascal-SC modules already is implemented as "GNU specific modules".)

    ## Data Types in BP and GPC

    - Integer types have different sizes in Borland and GNU Pascal: @multitable {xxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxx} {xxxxxxxxxx} {xxxxxxxx}
    - Borland Pascal @tab GNU Pascal @tab Bits (1) @tab Signed
    - ShortInt @tab ByteInt @tab 8 @tab yes
    - Integer @tab ShortInt @tab 16 @tab yes
    - LongInt @tab Integer @tab 32 @tab yes
    - Comp @tab LongInt, Comp @tab 64 @tab yes
    - Byte @tab Byte @tab 8 @tab no
    - Word @tab ShortWord @tab 16 @tab no
    - n/a @tab Word @tab 32 @tab no
    - n/a @tab LongWord @tab 64 @tab no (1) The size of the GNU Pascal types may depend on the platform. The sizes above apply to 32 bit platforms, including the x86. If you care for types with exactly the same size as in Borland Pascal, take a look at the ``System'` unit and read its comments. You can get the size of a type with ``SizeOf'` in bytes (like in Borland Pascal) and with ``BitSizeOf'` in bits, and you can declare types with a specific size (given in bits), e.g.:

          type
            MyInt  = Integer (42);  { 42 bits, signed }
            MyWord = Word (2);      { 2 bits, unsigned, i.e., 0 .. 3 }
            MyCard = Cardinal (2);  { the same }

            HalfInt = Integer (BitSizeOf (Integer) div 2);
              { A signed integer type which is half as big as the normal
                `Integer' type, regardless of how big `Integer' is on any
                platform the program is compiled on. }

    - Borland's Real types are supported except for the 6-byte software Real (but the ``System'` unit provides conversion routines for them). GNU Pascals's ``Real'` type has 8 bytes on the x86 and is the same as ``Double'`. In addition there are alternative names for real types: @multitable {xxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxx}
    - Borland Pascal @tab GNU Pascal
    - Single @tab Single, ShortReal
    - Real @tab n/a
    - Double @tab Double, Real
    - Extended @tab Extended, LongReal
    - Comp @tab LongInt, Comp (see above)
    - Complex numbers: According to Extended Pascal, GNU Pascal has built-in complex numbers and supports a number of mathematical functions on them, e.g. ``Abs'`, ``Sqr'`, ``Sqrt'`, ``Exp'`, ``Ln'`, ``Sin'`, ``Cos'`, ``ArcTan'`.
    - Record types: GNU Pascal by default aligns 32-bit fields on 4-byte addresses because this improves performance. So, e.g., the record

          type
            MyRec = record
              f, o, oo : Boolean;
              Bar : Integer
            end;

      has 8 bytes, not 7. Use the `--pack-struct` option or declare the record as ``packed'` to force GPC to pack it to 7 bytes. However, note that this produces somewhat less efficient code on the x86 and far less efficient code on certain other processors. Packing records and arrays is mostly useful only when using large structures where memory usage is a real concern, or when reading or writing them from/to binary files where the exact layout matters.
    - In addition to BP's procedural types, GNU Pascal has pointers to procedures:

          type
            FuncPtr = ^Function (Real) : Real;

      GNU Pascal also supports Standard Pascal's procedural parameters -- see below. Furthermore, GNU Pascal allows you to call local procedures through procedural pointers, variables or parameters without reverting to any dirty tricks (like assembler, which is necessary in Borland Pascal).

    ## Files

    - GPC supports files like in Borland Pascal, including untyped files, ``BlockRead'`, ``BlockWrite'` and ``Assign'`. Instead of ``Assign'`, you can also use the ``Bind'` mechanism of Extended Pascal. Besides the routines supproted by BP, there are many more routines available that deal with files, file names and similar things in a portable way. In contrast to Borland Pascal, you don't have to use any platform-specific units to do these kinds of things, though portable emulations of those units (e.g., of the ``Dos'` and ``WinDos'` units) are also available for compatibility.

    ## Built-in Constants

    - The ``MaxInt'`, ``MaxLongInt'`, ``Pi'` constants are supported like in BP.
    - Other built-in constants: GNU Pascal has ``MaxChar'`, ``MaxReal'`, ``MinReal'`, ``EpsReal'` and a number of other useful constants.

    ## Built-in Operators in BP and GPC

    Besides the operators found in Borland Pascal, GNU Pascal supports the following operators:

    - Exponentiation: According to Extended Pascal, GNU Pascal supports the exponentiation operators `pow` and `**` which do not exist in Borland Pascal. You can use `x pow y` for integer and `x ** y` for real or complex exponents. The basis may be integer, real or complex in both cases.
    - Address operator: GNU Pascal accepts Borland's `@`, but also `&` as an address operator.
    - GNU Pascal has a symmetric set difference operator `set1 >< set2`. For more about this, see section Set Operations.

    ## Built-in Procedures and Functions

    - ``GetMem'` and ``FreeMem'` are supported like in BP. ``GetMem'` can also act as a function in GNU Pascal:

            p := GetMem (1024);

      The second parameter to ``FreeMem'` is ignored by GNU Pascal and may be omitted. Memory blocks are always freed with the same size they were allocated with. Remark: Extended Pascal Schema types provide a cleaner approach to most of the applications of ``GetMem'` and ``FreeMem'`.
    - ``Min'` and ``Max'`: GNU Pascal has built-in ``Min'` and ``Max'` functions (two arguments) which work for all ordinal types (``Integer'`, ``Char'`, ...) plus ``Real'`.
    - ``UpCase'`, ``High'`, ``Low'` and similar functions are built-in. In contrast to Borland Pascal, GNU Pascal's ``UpCase'` function is aware of non-ASCII characters of certain languages (e.g., accented letters and "umlauts"), but for compatibility this feature is disables in ``--borland-pascal'` mode. There is also a ``LoCase'` function.
    - ``Lo'`, ``Hi'`, ``Swap'` functions: not built-in, but available in the ``System'` unit.

    ## Special Parameters

    - Untyped reference parameters can be denoted by

            procedure Foo (var x);

      like in Borland Pascal. In GNU Pascal, you can also use

            procedure Foo (var x : Void);

    - GNU Pascal defines ellipsis parameters for variable argument lists:

            procedure Foo (a : Integer; ...);

      However, GPC does not (yet) provide a portable mechanism to access the additional arguments.
    - Structured function return values: According to Extended Pascal, GNU Pascal allows functions to return records and arrays.
    - BP style open array parameters

            procedure Foo (a : array of Integer);

      are implemented. However, Standard Pascal ``conformant array parameters'` are usually a cleaner mechanism to pass arrays of variable size.
    - Besides BP compatible procedural types, GNU Pascal supports Standard Pascal's procedural parameters:

            procedure DrawGraph (function f (x : Real) : Real);

    ## Miscellaneous

    - Headlines: According to Extended Pascal, a program headline must contain the program's parameters:

             program Foo (Input, Output);

      In GNU Pascal, headline parameters are optional. If the headline is omitted entirely, a warning is given unless you have specified ``--borland-pascal'` in the command line.
    - ``case'` statements: In a ``case'` statement, GNU Pascal allows `otherwise` (according to Extended Pascal) as an alternative to `else`:

            case x of
              1 : Writeln ('one');
              2 : Writeln ('two');
            otherwise
              Writeln ('many');
            end;

      Note: In the absence of a ``case'` or ``otherwise'` branch, missing cases labels cause an error in Extended Pascal (which goes unnoticed in Borland Pascal). GPC does not give this error, but a warning if the ``-Wswitch'` option is given, however only for enumeration types.
    - Character constants: BP compatible character constants like ``^M'` as well as ``#13'` are implemented into GNU Pascal.
    - Sets: GNU Pascal has a `Card` function for sets which counts their elements. Unlike Borland Pascal, GNU Pascal does not limit sets to the range 0 .. 255.
    - Inline: GNU Pascal allows "inline" Pascal procedures and functions, while Borland Pascal only allows machine code to be inlined: Borland Pascal:

            function Max (x, y : Integer) : Integer;
            inline ($58 / $59 / $3b / $c1 / $7f / $01 / $91);

      GNU Pascal:

            inline function Max (x, y : Integer) : Integer;
            begin
              if x > y then
                Max := x
              else
                Max := y
            end;

      (Actually, a more general ``Max'` function is already built-in.) This feature is not so important as it might seem because in optimization level 3 or higher (see section The most commonly used options to GPC), GNU Pascal automatically inlines short procedures and functions.

    ## BP and Extended Pascal

    Pascal is a well-known programming language and hardly needs to be described here. Note, however, that there is a large difference between the language used by the BP compiler and the Pascal Standards.

    Extended Pascal is a standardized language based on the original Standard Pascal, but with significant extensions. Unfortunately, Borland Pascal does not conform to any of the Pascal standards. Writing a program that both complies to Extended Pascal (or even Standard Pascal) and compiles with BP is almost impossible for any non-trivial task.

    On the other hand, BP has some nice features that make it very powerful in the environments in which it runs. However, some of those features are of little use on non-Dos systems and would not be good candidates for standardization.

    There are also several BP features which are semantically similar to features in Standard Pascal or Extended Pascal, but syntactically different.

    Therefore, in order to be useful to users coming from either side, GPC supports both the standards and the BP dialect as good as possible. By default, GPC allows features from any dialect it knows. By giving a dialect option such as ``--borland-pascal'` or ``--extended-pascal'`, you can tell GPC to disable the features not found in that dialect, and to adjust its warning behaviour to the dialect.

    The different sets of reserved words are a little problem, but GPC solves it by making the words in question only "conditionally reserved" which works transparently without problems in most cases. Still, giving a dialect option will disable all keywords not part of this dialect.

    Apart from this, there are surprisingly few real conflicts between the dialects. Therefore, you can usually compile your BP code without the ``--borland-pascal'` option and make use of all of GPC's features. You might be surprised, though, when GPC accepts things you didn't know were allowed. :-)

    Finally, if you want to make use of some of GPC's extensions (compared to BP) and still keep the code compileable with BP without using ``ifdef'`s all over the place, we suggest you look at the unit ``gpc-bp.pas'`, shipped with GPC, which contains BP versions of some of GPC's features. Please read the comments at the beginning of the unit to find out more about it.

    ## Portability hints

    GPC offers you the possibility to make your code fully portable to each of the many platforms supported by GPC. It would be a pity not to make use of this.

    This section lists some known pitfalls that often hinder otherwise well-written programs to take full advantage of GPC. If you have never used any compiler but Borland Pascal and similar compilers, some of the advices might look strange to you. But this is just the same level of strangeness that your old programs will have for you once you have understood the principles of cross-platform portability. Remember that many tricks you have always been applying almost automatically in Borland Pascal were necessary to overcome certain limitations of the Dos platform and to compensate for the compiler's missing optimization. Programming with an optimizing compiler like GPC for platforms without a 64 kB limit is a completely new experience -- and perhaps it is among the reasons why you are now working with GPC in the first place?

    ### Portability -- why?

    Okay -- but why should I bother and make my program portable? I know that all who want to use my program are running WXYZ-OS anyway.

    Yes, but that's the result of a self-fulfilling prophecy. It depends on you whether it will always remain like this or not. Consider a program ABC written for a single platform, WXYZ-OS. Naturally, only WXYZ-OS-users get interested in ABC. The author gets feedback only from WXYZ-OS users and does not see any reason to make the program cross-platform. Then people realize that if they want to run ABC they must move to WXYZ-OS. The author concludes that people only want WXYZ-OS programs, and so on.

    To break out, just create a portable version of your program now. Then all OSes have equal chances to show their abilities when running your program, and your customers can choose their OS. Then, maybe, they decide to use your program just for the reason that they can be sure that it will run on all present and future platforms and not only on a specific one -- who knows?

    My program is a tool specifically designed to make the best of the STUV feature of WXYZ-OS. There is no point in making it portable.

    How much do you know about non-WXYZ-OSes? Just ask an expert how the STUV feature is named elsewhere. Be sure, if it is of value, it exists almost everywhere.

    ## Low-level features

    I am using a lot of low-level stuff in my programs, so they cannot be portable.

    You do not use those low-level routines directly in your high-level routines, do you? There should always be a layer "in-between" that encapsulates the low-level routines and present an API to your program that exactly reflects the needs of your application. This "API in between" is the point where you can exchange the low-level routines by portable calls to GPC's Run Time System.

    If you do not have such a layer in-between, then the API of the low-level routines you call are your first approximation for such a layer. If you have ever thought "it would be great if that API function had that additional parameter", then your own extended version of that API function that has that parameter can become part of your "API in between". But then don't stop here: Certainly the API of the OS is not ideal for your program's needs. Just create more routines that encapsulate all OS-specific stuff ...

    When the low-level stuff in question consists of interrupts, assembler and similar things, then the first thing you need is a portable replacement of the functionality. Fortunately, GPC covers many things already in Pascal that require assembler in Borland Pascal:

    - GPC's libraries come with source. You do not need to learn assembler and to write a complete replacement for the CRT unit if you only want to adapt some tiny detail in the behavior of CRT to your personal needs.
    - GPC's Run Time System is fairly complete. For example, to extract the assigned name of a ``File'` variable, you do not need to mess around with the internal representation of those variables, but you can type ``uses GPC'` and then use the ``FileName'` function. In the same unit, you will find a ``FileExists'` function and much more.
    - Manually "constructing" an object is covered by the ``SetType'` procedure in GPC. This is where Turbo Vision uses assembler to load an object from a stream.
    - Calling local procedures and functions via pointers simply works in GPC. This is another place where, for instance, Turbo Vision's ``ForEach'` method uses assembler, while GPC lets you do the same thing in Pascal.
    - Interfacing with the OS can be done through library calls. GPC's built-in functions and the GPC unit offer a rather complete set of routines. And again: You have the source of all this.
    - Using ``FillChar'` and ``Move'` does not necessarily speed up your programs. Using them to circumvent restrictions of the language (e.g. for direct assignments between variables of object or file type) is asking for trouble. ``FillChar'` was created in UCSD Pascal to set consecutive chars in a string to the same value, and ``Move'` was created to move the chars within the same string. Better do not use them for other purposes.

    # The Alphabetical GPC Language Reference

    @macro unnumberedsubsec

    This chapter is still under development. All identifiers are listed, but not all with explanations.

    This chapter contains an alphabetical list of all built-in identifiers of the GNU Pascal compiler. It does not cover extensions provided by external units and libraries which are supposed to come with their own documentation.

    ## abs

    ### Syntax

          Function abs ( i: integer type ): integer type;

    or

          Function abs ( x: real type ): real type;

    or

          Function abs ( z: complex type ): real type;

    ### Description

    Returns the absolute value of the argument. For integer or real values of ``x'`, the definition is

          Function abs ( x: integer or real type ): integer or real type;

          begin (* abs *)
            if x < 0 then
              abs:= -x
            else
              abs:= x;
          end (* abs *);

    whereas for complex values it is

          Function abs ( x: Complex ): Complex;

          begin (* abs *)
            abs:= sqrt ( x * conjugate ( x ) );
          end (* abs *);

    ### Standards

    The function ``abs'` is defined in ISO-7185 Standard Pascal; its application to complex values is defined in ISO-10206 Extended Pascal.

    ### Example

          Program TestAbs;

          Var
            i1: Complex;

          begin
            writeln ( abs ( 42 ) );             (* 42    *);
            writeln ( abs ( -42 ) );            (* 42    *);
            writeln ( abs ( -12.1 ) : 0 : 1 );  (* 12.1  *);
            i1:= cmplx ( 1, 1 );                (* 1 + i *)
            writeln ( abs ( i1 ) : 0 : 3 );     (* 1.414, i.e. sqrt ( 2 ) *)
          end.

    ### See also

    section sqr.

    ## absolute

    ### Syntax

          Var
            variable name: data type absolute variable reference;

    or

          Var
            variable name: data type absolute integer expression;

    ### Description

    The first meaning of the ``absolute'` directive allows to put a variable to the address of another one and thus provides a type-casting mechanism.

    In most cases, variable reference will be just a variable name, but GPC also allows arbitrary expressions here. If variable reference has neither a constant address nor is a variable parameter, GPC prints a warning. This warning is suppressed in "extended syntax" mode which is switched on by the ``--extended-syntax'` option or the ``(*$X+*)'` compiler directive.

    Other type-casting mechanisms in GPC are variant records (which are valid in ISO-7185 Standard Pascal) and explicit type casts.

    The second meaning of ``absolute'` places a variable at a specified address. This is useful on machines without virtual memory addressing for doing certain low-level operations, but should be avoided on systems with memory protection such as Unix-like systems. GPC does not check whether the specified virtual address makes any sense and does not provide a built-in mechanism to map it to a real address.

    GPC warns about this second use of ``absolute'` unless "extended syntax" has been requested.

    ### Standards

    ``absolute'` is a Borland Pascal extension.

    Borland Pascal has a slightly different syntax for the second meaning related to the addressing scheme of Intel X86 processors working in real mode.

    Allowing arbitrary memory references instead of just variable names in the first meaning of ``absolute'` is a GNU Pascal extension.

    ### Example

          Program TestAbsolute;

          (*$X+*)

          Const
            IOmemory = $F0000000;

          Var
            Mem: array [ 0..MaxInt ] of Byte absolute 0;
            SomeIOport: Byte absolute IOmemory + $C030;

          (* Beware:  Using any of the variables above will crash    *)
          (* your program unless you know exactly what you do!       *)
          (* That's why GPC warns about it without the X+ directive. *)

          Var
            x: Real;
            a: array [ 1..SizeOf ( Real ) ] of Byte absolute x;
            i: Integer;

            b: Byte absolute a [ i ];
            (* GNU extension: non-constant memory reference. *)

          begin
            x:= 3.14;
            (* Gather at the internal representation of a real variable. *)
            for i:= 1 to SizeOf ( Real ) do
              write ( a [ i ] : 4 );   (* Or (kind of abuse): `write ( b );' *)
            writeln;
          end.

    ### See also

    section record, section Type Casts.

    ## abstract

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## addr

    ### Syntax

          Function addr ( Const Foo ): Pointer;

    ### Description

    ``addr'` returns the address of its argument. It is equivalent to the address operator and provided for compatibility with Borland Pascal which in turn implements it for backward-compatibility with Turbo Pascal.

    ### Standards

    ``addr'` is a Borland Pascal extension.

    ### Example

          Var
            Foo: ^Integer;
            Bar: Integer;

          [...]

          Foo:= addr ( Bar );  (* Let `Foo' point to `Bar'. *)
          Foo^:= 42;  (* Change the value of `Bar' to 42 *)

    ### See also

    section Operators.

    ## AlignOf

    ### Syntax

          Function AlignOf ( Var x ): Integer;

    ### Description

    Returns the alignment of a type or variable in bytes.

    ### Standards

    ``AlignOf'` is a GNU extension.

    ### Example

          Var
            a: Integer;
            b: array [ 1..8 ] of Char;

          ...

          writeln ( AlignOf ( a ) );  (* Alignment of `Integer'; usually 4 bytes. *)
          writeln ( AlignOf ( b ) );  (* Alignment of `Char'; usually 1 byte. *)

    Although the array is bigger than a single char, it is accessed char by char, so there usually is no need to align it on a 4 byte boundary or such. (This may be false on some platforms.)

    ### See also

    section SizeOf, section BitSizeOf, section TypeOf.

    ## all

    ### Description

    ``all'` is a predefined export interface for Extended Pascal modules. You can use it to export all identifiers declared in an interface module automatically.

    ### Standards

    ``all'` is a GNU extension.

    ### Example

          Module TestAll Interface;

          export
            foo = all;  (* Same as `foo = ( a, b, bar );' *)

          Var
            a, b: Integer;

          Procedure bar;

          end.

    ### See also

    section The Source Structure of ISO-10206 Extended Pascal Modules.

    ## and

    ### Syntax

          Operator and ( operand1, operand2: Boolean ) = result: Boolean;

    or

          Operator and ( operand1, operand2: integer type ) = result: integer type;

    or

          Procedure and ( Var operand1: integer type; operand2: integer type );

    ### Description

    In GNU Pascal, ``and'` has three built-in meanings:

    1. Logical "and" between two ``Boolean'`-type expressions. The result of the operation is of ``Boolean'` type. By default, ``and'` acts as a short-circuit operator in GPC: If the first operand is ``False'`, the second operand is not evaluated because the result is already known to be ``False'`. You can change this to complete evaluation using the ``--no-short-circuit'` command-line option or the ``(*$B+*)'` compiler directive.
    2. Bitwise "and" between two integer-type expressions. The result is of the common integer type of both expressions.
    3. Use as a "procedure": ``operand1'` is "and"ed bitwise with ``operand2'`; the result is stored in ``operand1'`.

    ### Standards

    The logical ``and'` operator is defined in ISO-7185 Standard Pascal.

    According to ISO, you cannot rely on ``and'` being a short-circuit operator. On the other hand, GPC's default behaviour does not contradict the ISO standard. (See section and_then.) However, since it seems to be a de-facto standard among ISO Pascal compilers to evaluate both operands of ``and'`, GPC switches to ``--no-short-circuit'` mode if one of the language dialect options selecting ISO Pascal, for instance ``--extended-pascal'`, is given. Use ``--short-circuit'` to override.

    Use of ``and'` as a bitwise operator for integers is a Borland Pascal extension.

    Use of ``and'` as a "procedure" is a GNU extension.

    ### Example

          Var
            a, b, c: Integer;

          ...

          if ( a = 0 ) and ( b = 0 ) then  (* logical `and' *)
            c:= 1
          else if a and b = 0 then  (* bitwise `and' *)
            c:= 2
          else
            and ( c, a );  (* same as `c:= c and a' *)

    Note the difference between the logical ``and'` and the bitwise ``and'`: When ``a'` is 2 and ``b'` is 4, then ``a and b'` is 0. Beware: ``a and b = 0'` has nothing to do with ``( a = 0 ) and ( b = 0 )'`!

    Since bitwise ``and'` has a higher priority than the ``='` operator, parentheses are needed in ``if ( a = 0 ) and ( b = 0 )'` because otherwise ``0 and b'` would be calculated first, and the remainder would cause a parse error.

    ### See also

    section and_then, section and then, section or, section xor, section Operators.

    ## and then

    ### Description

    ``and then'` is an alias for the short-circuit logical operator ``and_then'`.

    ### Standards

    While ``and_then'` is defined in ISO-10206 Extended Pascal, ``and then'` is a GNU Extension.

    ### Example

          Var
            p: ^Integer;

          [...]

          if ( p <> Nil ) and then ( p^ < 42 ) then  (* This is safe. *)
            [...];

    ### See also

    section and_then, section and, section or else.

    ## and_then

    ### Syntax

          Operator and_then ( operand1, operand2: Boolean ) = result: Boolean;

    ### Description

    The ``and_then'` short-circuit logical operator performs the same operation as the logical operator ``and'`. But while the ISO standard does not specify anything about the evaluation of the operands of ``and'`---they may be evaluated in any order, or not at all---``and_then'` has a well-defined behaviour: It evaluates the first operand. If the result is ``False'`, ``and_then'` returns ``False'` without evaluating the second operand. If it is ``True'`, the second operand is evaluated and returned.

    Since the behaviour described above is the most efficient way to implement ``and'`, GPC by default treats ``and'` and ``and_then'` exactly the same. If you want, for some reason, to have both operands of ``and'` evaluated completely, you must assign both to temporary variables and then use ``and'`---or ``and_then'`, it does not matter.

    ### Standards

    ``and_then'` is an ISO-10206 Extended Pascal extension.

    Some people think that the ISO standard requires both operands of ``and'` to be evaluated. This is false. What the ISO standard does say is that you cannot rely on a certain order of evaluation of the operands of ``and'`; in particular things like

          Var
            p: ^Integer;

          [...]

          if ( p <> Nil ) and ( p^ < 42 ) then
            [...];

    can crash according to ISO Pascal, although they cannot crash when compiled with GNU Pascal running in default mode.

    ### Example

          Var
            p: ^Integer;

          [...]

          if ( p <> Nil ) and_then ( p^ < 42 ) then  (* This is safe. *)
            [...];

    ### See also

    section and then, section and, section or_else.

    ## AnsiChar

    ### Syntax

          Type
            AnsiChar = Char;

    ### Description

    ``AnsiChar'` is an 8 bit char type. Currently, it is the same as ``Char'`, but this might change in the future, once ``wide chars'` (16 bit chars) will be introduced into GPC. Depending on the platform, ``Char'` might be either ``AnsiChar'` or ``WideChar'` then.

    ### Standards

    ``AnsiChar'` is a Borland Delphi extension.

    ### Example

          Var
            A: AnsiChar;  (* There is nothing special with `AnsiChar'. *)
            B: Char;

          [...]

          A:= 'A';
          A:= B;

    ### See also

    section pAnsiChar, section Char.

    ## append

    ### Syntax

          Procedure append ( Var F: any file; [ name: String; ]
                                                    [ blocksize: Cardinal ] );

    ### Description

    ``Append'` opens a file for writing. If the file does not exist, it is created. If it does exist, the file pointer is positioned after the last element.

    Like ``rewrite'` and ``reset'` do, ``append'` accepts an optional second and third parameter for the name of the file in the filesystem and, for untyped files, the block size of the file. (For details, see section rewrite.)

    ### Standards

    ``append'` is a Borland Pascal extension. ISO-10206 Extended Pascal has section extend instead.

    ### Example

          Var
            Sample: Text;

          [...]

          Assign ( Sample, 'sample.txt' );
          rewrite ( Sample );
          writeln ( Sample, 'Hello, World!' );  (* `sample.txt' now has one line *)
          close ( Sample );

          [...]

          append ( Sample );
          writeln ( Sample, 'Hello again!' );   (* `sample.txt' now has two lines *)
          close ( Sample );

    ### See also

    section Assign, section reset, section rewrite, section update, section extend.

    ## arctan

    ### Syntax

          Function arctan ( x: Real ): Real;

    or

          Function arctan ( z: Complex ): Complex;

    ### Description

    ``arctan'` returns the (principal value of the) arcus tangent of the argument. The result is in the range ``-pi / 2 < arctan ( x ) < pi / 2'` for real arguments.

    ### Standards

    The function ``arctan'` is defined in ISO-7185 Standard Pascal; its application to complex values is defined in ISO-10206 Extended Pascal.

    ### Example

          writeln ( 4 * arctan ( 1 ) : 0 : 5 );
          (* yields 3.14159; arctan ( 1 ) = pi / 4. *)

    ### See also

    section sin, section cos, section ln, section arg.

    ## arg

    ### Syntax

          Function arg ( z: Complex ): Real;

    ### Description

    ``arg'` returns the complex "argument", i.e. the angle (in radian) in the complex plane with respect to the real axis, of its parameter ``z'`. The result is in the range of ``-pi < arg ( z ) <= pi'`.

    ### Standards

    ``Arg'` is an ISO-10206 Extended Pascal extension.

    ### Example

          Program TestArg;

          Var
            z: Complex;

          begin
            z:= cmplx ( 1, 1 );  (* 1 + i *)
            writeln ( arg ( z ) : 0 : 5 );
            (* yields 0.78540, i.e. pi / 4. *)
          end.

    ### See also

    section arctan, section ln, section polar.

    ## array

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## asm

    (Under construction.)

    ### Syntax

    ### Description

    See ``ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/contrib/gpcasm.zip'`.

    ### Standards

    ``asm'`, as implemented in GPC, is a GNU extension. It is mostly compatible with GCC's ``asm'`, but not compatible to that of Borland Pascal.

    ### Example

    ### See also

    ## asmname

    ### Syntax

    Procedure/Function header; asmname name;

    or

    variable declaration; asmname name;

    ### Description

    The ``asmname'` directive declares the external name of a procedure, function or variable. The external name of the routine is given explicitly as a case-sensitive string constant. This is useful when interfacing with libraries written in other languages.

    With this extension it is possible to access all external functions, for example the X11 interface functions, and not only those written in lowercase.

    The idea to use ``external'` for this purpose (to avoid name space pollution) conflicts with another Borland extension not yet implemented: In Borland Pascal, the declaration

        Procedure Foo; external 'MyLib';

    means that the procedure Foo should be imported by name (``Foo'`) from a dynamic link library ``mylib.dll'`.

    ### Standards

    ``asmname'` is a GNU Pascal extension.

    ### Example

          var foo : Integer; asmname 'Foo_';

          Function XOpenDisplay ( DisplayName: CString ): Pointer;
            asmname 'XOpenDisplay';

          [...]

          MyDisplay:= XOpenDisplay ( 'MyDisplay' );

    ### See also

    section C, section C_Language, section external.

    ## Assign

    ### Syntax

          Procedure Assign ( Var F: any file; FileName: String );

    ### Description

    ### Standards

    ``Assign'` is a Borland Pascal extension.

    ### Example

    ### See also

    section reset, section rewrite, section update, section extend, section append.

    ## assigned

    (Under construction.)

    ### Syntax

          Function assigned ( p: Pointer ): Boolean;

    or

          Function assigned ( p: procedural type ): Boolean;

    ### Description

    The ``assigned'` function returns ``True'` if the pointer parameter or the address of the procedural parameter is not ``Nil'`; it returns ``False'` if it is ``Nil'`.

    ### Standards

    ``assigned'` is a Borland Pascal extension.

    ### Example

    ### See also

    section NULL, section nil.

    ## attribute

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``attribute'` is a GNU Pascal extension.

    ### Example

    ### See also

    ## begin

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Bind

    (Under construction.)

    ### Syntax

          Procedure Bind ( Var F: any file; B: BindingType );

    ### Description

    ### Standards

    ``Bind'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## bindable

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``bindable'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## Binding

    (Under construction.)

    ### Syntax

          Function Binding ( F: any file ): BindingType;

    ### Description

    ### Standards

    ``Binding'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## BindingType

    (Under construction.)

    ### Syntax

        UnixTimeType = LongInt;

        type
          UnixTimeType = LongInt;
          BindingType = {@@packed} record
            Bound             : Boolean;
            Force             : Boolean;      { Can be set to allow binding to
                                                directories or non-accessible files }
            Extensions_Valid  : Boolean;
            Readable          : Boolean;
            Writable          : Boolean;
            Executable        : Boolean;
            Existing          : Boolean;      { Binding points to an existing file }
            Directory         : Boolean;      { Binding points to an existing
                                                directory; Existing is False then }
            Special           : Boolean;      { Binding points to an existing special
                                                file (device, pipe, socket, etc.);
                                                `Existing' is False then }
            SymLink           : Boolean;      { Binding points to a symbolic link }
            AccessTime,                       { Time of last access }
            ModificationTime,                 { Time of last modification }
            ChangeTime        : UnixTimeType; { Time of last change }
            User,                             { User ID of owner }
            Group,                            { Group ID of owner }
            Mode,                             { Access permissions, cf. ChMod }
            Device,                           { Device the file is on }
            INode             : Integer;      { Unix INode number }
            TextBinary        : Boolean;      { Open a Text file in binary mode }
            Handle            : Integer;      { Can be set to bind a Pascal file to
                                                a given file handle }
            Name              : String (Binding_Name_Length)
          end;

    (@@ Currently, in GPC, BindingType is not actually packed.)

    The fields ``Bound'` and ``Name'` are required by Extended Pascal.

    `Binding_Name_Length` is an implementation-defined constant.

    ### Description

    ### Standards

    ``BindingType'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## BitSizeOf

    ### Syntax

          Function BitSizeOf ( Var x ): SizeType;

    ### Description

    Returns the size of a type or variable in bits.

    ### Standards

    ``BitSizeOf'` is a GNU Pascal extension.

    ### Example

          Var
            a: Integer;
            b: array [ 1..8 ] of Char;
            c: Integer ( 12 );

            d: packed record
              x: Integer ( 12 );
              y: 0..3;
            end (* d *);

          ...

          writeln ( BitSizeOf ( a ) );  (* Size of an `Integer'; usually 32 bits.  *)
          writeln ( BitSizeOf ( b ) );  (* Size of eight `Char's; usually 64 bits. *)
          writeln ( BitSizeOf ( c ) );  (* 16 bits (smallest addressable space).   *)

          writeln ( BitSizeOf ( d ) );    (* 16 *)
          writeln ( BitSizeOf ( d.x ) );  (* 12 *)
          writeln ( BitSizeOf ( d.y ) );  (*  2 *)

    ### See also

    section SizeOf, section AlignOf, section TypeOf.

    ## BlockRead

    (Under construction.)

    ### Syntax

          Procedure BlockRead ( Var F: File; Var Buffer; Blocks: Integer );

    or

          Procedure BlockRead ( Var F: File; Var Buffer; Blocks: Integer;
                                Var BlocksRead: Integer );

    ### Description

    ### Standards

    ``BlockRead'` is an UCSD Pascal extension.

    ### Example

    ### See also

    ## BlockWrite

    (Under construction.)

    ### Syntax

          Procedure BlockWrite ( Var F: File; Const Buffer; Blocks: Integer );

    or

          Procedure BlockWrite ( Var F: File; Const Buffer; Blocks: Integer;
                                 Var BlocksWritten: Integer );

    ### Description

    ### Standards

    ``BlockWrite'` is an UCSD Pascal extension.

    ### Example

    ### See also

    ## Boolean

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``Boolean'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    ### See also

    ## break

    ### Syntax

    ``break'` (simple statement)

    ### Description

    The ``break'` statement causes a loop to exit. It is equivalent to a ``goto'` to the first instruction that follows the body of the loop.

    ### Standards

    ``break'` is a Borland Pascal extension.

    ### Example

          Var
            i: Integer;

          [...]

          i:= 1;
          while i <= 6 do
            begin
              inc ( i );
              writeln ( 'bla' );
              if i > 3 then
                break;
            end (* while *);

    yields

          bla
          bla
          bla

    ### See also

    section continue, section exit, section return, section goto.

    ## Byte

    ### Description

    ``Byte'` is an unsigned integer type which is one "unit" wide. On most platforms one unit has 8 bits, therefore the type is named "byte" and usually has a range of ``0..255'`. (It is the same as section ByteCard.)

    ``Byte'` in GNU Pascal is compatible to ``unsigned char'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``Byte'` is a Borland Pascal extension. (For something equivalent in ISO Pascal, see section Subrange Types.)

    ### See also

    section Integer Types, section Subrange Types.

    ## ByteBool

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## ByteCard

    ### Description

    ``ByteCard'` is an unsigned integer type which is one "unit" wide. On most platforms one unit has 8 bits, therefore the type is prefixed "byte-" and usually has a range of ``0..255'`.

    ``ByteCard'` in GNU Pascal is compatible to ``unsigned char'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``ByteCard'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## ByteInt

    ### Description

    ``ByteInt'` is a signed integer type which is one "unit" wide. On most platforms one unit has 8 bits, therefore the type is prefixed "byte-" and usually has a range of ``-128..127'`.

    ``ByteInt'` in GNU Pascal is compatible to ``signed char'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``ByteInt'` is a GNU Pascal extension.

    ``ByteInt'` in GNU Pascal corresponds to section ShortInt in Borland Pascal.

    ### See also

    section Integer Types, section Subrange Types.

    ## C

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## C_Language

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Card

    (Under construction.)

    ### Syntax

          Function Card ( S: any set ): Integer;

    ### Description

    ``Card'` returns the number of elements in the set S.

    ### Standards

    ``Card'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## Cardinal

    ### Description

    ``Cardinal'` is the "natural" unsigned integer type in GNU Pascal. On most platforms it is 32 bits wide and thus has a range of ``0..4294967295'`. Use it whenever you need a general-purpose unsigned integer type and don't need to care about compatibility to other Pascal dialects.

    As an extension, GPC allows to use ``Cardinal'` as a pseudo-schema to produce types with a specified size in bits; for example

          Type
            Card16 = Cardinal ( 16 );

    defines an unsigned integer type with 16 bits. The same mechanism works for ``Integer'` and ``Word'`, too.

    ``Cardinal'` in GNU Pascal is compatible to ``unsigned int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``Cardinal'` is not defined in ISO Pascal, but several Pascal compilers support it as an extension. In Borland Delphi, for instance, it is an unsigned 16-bit in version 1.0, an unsigned 31-bit integer from version 2.0 on, and an unsigned 32-bit integer from version 4.0 on.

    ### See also

    section Integer Types, section Subrange Types.

    ## case

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``case'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    ### See also

    ## Char

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``Char'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    ### See also

    ## ChDir

    (Under construction.)

    ### Syntax

          Procedure ChDir ( Directory: String );

    ### Description

    ### Standards

    ``ChDir'` is a Borland Pascal extension.

    ### Example

    ### See also

    ## chr

    (Under construction.)

    ### Syntax

          Function chr ( AsciiCode: Integer ): Char;

    ### Description

    ### Standards

    ``chr'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    ### See also

    ## class

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## close

    (Under construction.)

    ### Syntax

          Procedure Close ( Var F: any file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## cmplx

    (Under construction.)

    ### Syntax

          Function cmplx ( RealPart, ImaginaryPart: Real ): Complex;

    ### Description

    ### Standards

    ``cmplx'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## Comp

    ### Description

    ``Comp'` is a signed integer type which is longer than ``Integer'`. On most platforms it is 64 bits wide and thus has a range of ``-9223372036854775808..9223372036854775807'`.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``Comp'` is a Borland Pascal extension.

    In some contexts, Borland Pascal treats ``Comp'` as a "real" type--this behaviour is not supported by GPC.

    ### See also

    section Integer Types, section Subrange Types.

    ## Complex

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``Complex'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## Concat

    (Under construction.)

    ### Syntax

          Function Concat ( S1, S2: String ): String;

    or

          Function Concat ( S1, S2, S3: String ): String;

    or

          ...

    ### Description

    ### Standards

    ``Concat'` is an UCSD Pascal extension.

    ### Example

    ### See also

    ## conjugate

    (Under construction.)

    ### Syntax

          Function conjugate ( z: Complex ): Complex;

    ### Description

    ### Standards

    ``conjugate'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## const

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``Const'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    ### See also

    ## constructor

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``Constructor'` is a Borland Pascal extension.

    ### Example

    ### See also

    ## continue

    ### Syntax

    ``continue'` (simple statement)

    ### Description

    The ``continue'` statement causes a loop to execute the next turn. It is equivalent to a ``goto'` to the end of the block that is the body of the loop.

    ### Standards

    ``continue'` is a Borland Pascal extension.

    ### Example

          Var
            i: Integer;

          [...]

          i:= 1;
          while i <= 6 do
            begin
              inc ( i );
              write ( 'bla' );
              if i <= 3 then
                continue;
              writeln;
            end (* while *);

    yields

          blablabla
          bla
          bla
          bla

    ### See also

    section break, section exit, section return, section goto.

    ## Copy

    ### Syntax

          Function Copy ( S: String; FirstChar, Count: Integer ): String;

    or

          Function Copy ( S: String; FirstChar: Integer ): String;

    ### Description

    ``Copy'` returns a sub-string of S starting with the character at position FirstChar. If Count is given, such many characters will be copied into the sub-string. If Count is omitted, the sub-string will will range to the end of S.

    If ``Count'` is too large for the sub-string to fit in S, the result will be truncated at the end of S. If ``FirstChar'` exceeds the length of S, the empty string will be returned. (For a function which does not truncate but triggers a runtime error instead, see section SubStr.)

    Please note that GPC's strings may be longer than 255 characters. If you want to isolate the second half of a string S starting with the third character, use ``Copy ( S, 3)'` instead of ``Copy ( S, 3, 255 )'`.

    ### Standards

    ``Copy'` is an UCSD Pascal extension. The possibility to omit the third parameter is a GNU Pascal extension.

    ### Example

          Var
            S: String ( 42 );

          [...]

          S:= 'Hello';
          writeln ( Copy ( S, 2, 3 ) );   (* yields "ell" *)
          writeln ( Copy ( S, 3 ) );      (* yields "llo" *)
          writeln ( Copy ( S, 4, 7 ) );   (* yields "lo" *)
          writeln ( Copy ( S, 42 ) );     (* yields the empty string *)

    ### See also

    section SubStr, String slice access.

    ## cos

    (Under construction.)

    ### Syntax

          Function cos ( x: Real ): Real;

    or

          Function cos ( z: Complex ): Complex;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## CString

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## CString2String

    (Under construction.)

    ### Syntax

          Function CString2String ( S: CString ): String;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Date

    (Under construction.)

    ### Syntax

          Function Date ( T: TimeStamp ):
              packed array [ 1..date length ] of Char;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## dec

    (Under construction.)

    ### Syntax

          Procedure dec ( Var x: ordinal type );

    or

          Procedure dec ( Var x: ordinal type; amount: Integer );

    ### Description

    ### Standards

    ``Dec'` is a Borland Pascal extension.

    ### Example

    ### See also

    section inc, ``pred'`.

    ## default

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## DefineSize

    (Under construction.)

    ### Syntax

          Procedure DefineSize ( Var F: any file; NewSize: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Delete

    (Under construction.)

    ### Syntax

          Procedure Delete ( Var S: String; FirstChar, Count: Integer );

    ### Description

    ### Standards

    ``Delete'` is a UCSD Pascal extension.

    ### Example

    ### See also

    ## destructor

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ``Destructor'` is a Borland Pascal extension.

    ### Example

    ### See also

    ## Dispose

    (Under construction.)

    ### Syntax

          Dispose ( PointerVar: Pointer );

    or

          Dispose ( PointerVar: Pointer; tag field values );

    or

          Dispose ( ObjectPointerVar: Pointer; destructor call );

    ### Description

    ### Standards

    ``Dispose'` is defined in ISO-7185 Standard Pascal and supported by most known Pascal variants, but not by UCSD Pascal. Its use for objects is a Borland Pascal extension.

    ### Example

    ### See also

    ## div

    (Under construction.)

    ### Syntax

          Operator div ( p, q: Integer ) = r: Integer;

    ### Description

    ### Standards

    ``div'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    ### See also

    ## do

    ### Syntax

          for ... do statement

    or

          while ... do statement

    or

          with ... do statement

    or

          to begin do statement

    or

          to end do statement

    ### Description

    The ``do'` reserved word is used in combination with other Pascal keywords in many ways. For description and examples see the relevant reference sections: ``for'`, ``while'`, ``with'`, ``to begin'`, ``to end'`.

    ### Standards

    ``do'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    See references.

    ### See also

    section for, section while, section with, section to begin do, section to end do.

    ## Double

    (Under construction.)

    ### Syntax

          Type
            Double = Real;

    ### Description

    ``Double'` is a synonym for the ``Real'` data type and supported for compatibility with other compilers.

    ### Standards

    ``Double'` is a Borland Pascal extension.

    ### Example

          Var
            A: Double;  (* There is nothing special with `Double'. *)
            B: Real;

          [...]

          A:= pi;
          A:= B;

    ### See also

    ## downto

    ### Syntax

          for variable := value1 downto value2 do statement

    ### Description

    The ``downto'` reserved word is used in combination with ``for'` to build a ``for'` loop.

    ### Standards

    ``downto'` is defined in ISO-7185 Standard Pascal and supported by all known Pascal variants.

    ### Example

    See section for.

    ### See also

    section for.

    ## else

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## empty

    (Under construction.)

    ### Syntax

          Function empty ( Var F: any file ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## end

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## eof

    (Under construction.)

    ### Syntax

          Function eof ( Var F: any file ): Boolean;

    or

          Function eof: Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## eoln

    (Under construction.)

    ### Syntax

          Function eoln ( Var F: any file ): Boolean;

    or

          Function eoln: Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## EpsReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## eq

    (Under construction.)

    ### Syntax

          Function eq ( S1, S2: String ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## erase

    (Under construction.)

    ### Syntax

          Procedure erase ( Var F: any file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## exit

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## exp

    (Under construction.)

    ### Syntax

          Function exp ( x: Real ): Real;

    or

          Function exp ( z: Complex ): Complex;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## export

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## exports

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## extend

    (Under construction.)

    ### Syntax

          Procedure extend ( Var F: any file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Extended

    (Under construction.)

    ### Syntax

          Type
            Extended = LongReal;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## extern

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## external

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## False

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## far

    ### Description

    The ``far'` directive can be appended to a procedure or function heading but is ignored by GPC. It is there for Borland compatibility, only. (Since the GNU compilers provide a flat memory model, the distinction between ``near'` and ``far'` pointers is void.)

    ### Standards

    ``far'` is a Borland Pascal extension.

    ### Example

          Var
            p: Procedure;

          Procedure Foo; far;  (* `far' has no effect in GPC *)

          begin (* Foo *)
            [...]
          end (* Foo *);

          [...]

          p:= Foo;  (* Would also work without `far' in GPC. *)

    ### See also

    section near.

    ## FileMode

    (Under construction.)

    ### Syntax

          Var
            FileMode: Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## file

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## FilePos

    (Under construction.)

    ### Syntax

          Function FilePos ( Var F: any file ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## FileSize

    (Under construction.)

    ### Syntax

          Function FileSize ( Var F: any file ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## FillChar

    (Under construction.)

    ### Syntax

          Procedure FillChar ( Var Dest; Count: Integer; Value: Char );

    or

          Procedure FillChar ( Var Dest; Count: Integer; Value: Byte );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## flush

    (Under construction.)

    ### Syntax

          Procedure flush ( Var F: any file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## for

    (Under construction.)

    ### Syntax

          for ordinal variable := initial value to final value do
            statement

    or

          for ordinal variable := initial value downto final value do
            statement

    or

          for ordinal variable in some set do
            statement

    ### Description

    ### Standards

    ### Example

    ### See also

    ## forward

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## frac

    (Under construction.)

    ### Syntax

          Function frac ( x: Real ): Real;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## FreeMem

    ### Syntax

          Procedure FreeMem ( Var p: Pointer; Size: Cardinal );

    or

          Procedure FreeMem ( Var p: Pointer );

    ### Description

    Releases a chunk of memory previously allocated using ``GetMem'`. The parameter Size is optional, and its value is ignored.

    Since Extended Pascal's schemata provide a cleaner way to implement dynamical arrays and such, we recommend using ``GetMem'` and ``FreeMem'` only for low-level applications or for interfacing with other languages.

    ### Standards

    ``FreeMem'` is a Borland Pascal extension. ``FreeMem'` with only one parameter is a GNU Pascal extension.

    ### Example

    See section GetMem

    ### See also

    section GetMem, section EP's Schema Types including ``String'`, section Dispose, section Mark, section Release.

    ## function

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## ge

    (Under construction.)

    ### Syntax

          Function ge ( S1, S2: String ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Get

    (Under construction.)

    ### Syntax

          Procedure Get ( Var F: typed file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## GetMem

    ### Syntax

          Procedure GetMem ( Var p: Pointeger; Size: Cardinal );

    or

          Function GetMem ( Size: Cardinal ): Pointer;

    ### Description

    Allocates dynamical storage on the heap and returns a pointer to it in ``p'` or as the function result.

    Since Extended Pascal's schemata provide a cleaner way to implement dynamical arrays and such, we recommend using ``GetMem'` and ``FreeMem'` only for low-level applications.

    ### Standards

    ``GetMem'` is a Borland Pascal extension. The use of ``GetMem'` as a function is a GNU Pascal extension.

    ### Example

    The Borland-comatibility Unit ``Graph'` from the ``BPcompat'` package supports a ``GetImage'` and a ``PutImage'` procedure which need a variable of size ``ImageSize'` as a buffer. Since these are "black box" routines, the buffer can't reasonably be a schema providing a dynamical array. Instead, we have to use ``GetMem'` and ``FreeMem'` for dynamical memory allocation.

          Program TestGetMem;

          uses
            Graph;

          Var
            Buffer: Pointer;
            Size: Cardinal;

          begin
            [...]
            Size:= ImageSize ( 10, 10, 60, 30 );
            Buffer:= GetMem ( Size );  (* or: GetMem ( Buffer, Size ); *)
            GetImage ( 10, 10, 60, 30, Buffer^ );
            [...]
            FreeMem ( Buffer );  (* or: FreeMem ( Buffer, Size ); *)
            [...]
          end.

    ### See also

    section FreeMem, section New, section EP's Schema Types including ``String'`.

    ## GetTimeStamp

    (Under construction.)

    ### Syntax

          Procedure GetTimeStamp ( Var T: TimeStamp );

    ### Description

    ### Standards

    ``GetTimeStamp'` is an ISO-10206 Extended Pascal extension.

    ### Example

    ### See also

    ## goto

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## gt

    (Under construction.)

    ### Syntax

          Function gt ( S1, S2: String ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Halt

    (Under construction.)

    ### Syntax

          Procedure Halt;

    or

          Procedure Halt ( ExitCode: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## high

    (Under construction.)

    ### Syntax

          Function high ( ordinal type or variable ): Integer;

    or

          Function high ( array type or variable ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## if

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Im

    (Under construction.)

    ### Syntax

          Function Im ( z: Complex ): Real;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## import

    ### Description

    The reserved word ``import'` in the import part of a program makes the program import an interface. The syntax is

          Program foo;

          import
            bar1;
            bar3 ( baz1 => glork1 ) in 'baz.pas';
            bar2 only ( baz2, baz3 => glork2 );

          [...]

    The ``in'` above tells GPC to look for the ``Module'` in the specified file; otherwise the file name is derived from the name of the interface by adding first ``.p'`, then ``.pas'`---which only works if the name of the exported interface coincides with the file name.

    The symbol ``=>'` denotes import renaming: The entity which is exported under the name ``baz1'` by the interface ``bar3'` will be known under the new name ``glork1'` in the program.

    The ``only'` qualifier means that only the listed identifiers will be imported from the interface. Renaming works together with ``only'`, too.

    There must be at most one import part in a program.

    The interfaces needn't be exported by Extended Pascal Modules but may be UCSD/Borland Pascal Units as well.

    ### Standards

    ``import'` and Modules in general are an ISO-10206 Extended Pascal extension.

    GNU Pascal does not yet support ``qualified'` import.

    ### See also

    section module, section unit, section uses.

    ## implementation

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## in

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## inc

    (Under construction.)

    ### Syntax

          Procedure inc ( Var x: ordinal type );

    or

          Procedure inc ( Var x: ordinal type; amount: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Index

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## inherited

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## inline

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## InOutRes

    (Under construction.)

    ### Syntax

          Var
            InOutRes: Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## InOutResStr

    (Under construction.)

    ### Syntax

          Var
            InOutResStr: CString;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Input

    (Under construction.)

    ### Syntax

          Var
            Input: Text;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Insert

    (Under construction.)

    ### Syntax

          Procedure Insert ( Source: String; Var Dest: String; Position: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## int

    (Under construction.)

    ### Syntax

          Function int ( x: Real ): Real;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Integer

    ### Description

    ``Integer'` is the "natural" signed integer type in GNU Pascal. On most platforms it is 32 bits wide and thus has a range of ``-2147483648..2147483647'`. Use it whenever you need a general-purpose signed integer type.

    As an extension, GPC allows to use ``Integer'` as a pseudo-schema to produce types with a specified size in bits; for example

          Type
            Int16 = Integer ( 16 );

    defines an integer type with 16 bits. The same mechanism works for ``Cardinal'` and ``Word'`, too.

    ``Integer'` in GNU Pascal is compatible to ``int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    In ISO Pascal, ``Integer'` is the only built-in integer type. (However see section Subrange Types.)

    ### See also

    section Integer Types, section Subrange Types.

    ## interface

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## interrupt

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## IOresult

    (Under construction.)

    ### Syntax

          Function IOresult: Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## is

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## label

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## LastPosition

    (Under construction.)

    ### Syntax

          Function LastPosition ( Var F: typed file ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## le

    (Under construction.)

    ### Syntax

          Function le ( S1, S2: String ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## length

    (Under construction.)

    ### Syntax

          Function length ( S: String ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## library

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## ln

    (Under construction.)

    ### Syntax

          Function ln ( x: Real ): Real;

    or

          Function ln ( z: Complex ): Complex;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## LoCase

    (Under construction.)

    ### Syntax

          Function LoCase ( Ch: Char ): Char;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## LongCard

    ### Description

    ``LongCard'` is an unsigned integer type which is longer than ``Cardinal'`. On most platforms it is 64 bits wide and thus has a range of ``0..18446744073709551615'`.

    ``LongCard'` in GNU Pascal is compatible to ``long long unsigned int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``LongCard'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## LongInt

    ### Description

    ``LongInt'` is a signed integer type which is longer than ``Integer'`. On most platforms it is 64 bits wide and thus has a range of ``-9223372036854775808..9223372036854775807'`.

    ``LongInt'` in GNU Pascal is compatible to ``long long int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``LongInt'` is a Borland Pascal extension. Borland Pascal defines ``LongInt'` as a 32-bit signed integer type (section Integer in GNU Pascal).

    ### See also

    section Integer Types, section Subrange Types.

    ## LongestCard

    ### Description

    ``LongestCard'` is GPC's longest-possible unsigned integer type. Currently, this is the same as section LongCard. On most platforms it is 64 bits wide and thus has a range of ``0..18446744073709551615'`.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``LongestCard'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## LongestInt

    ### Description

    ``LongestInt'` is GPC's longest-possible signed integer type. Currently, this is the same as section LongInt. On most platforms it is 64 bits wide and thus has a range of ``-9223372036854775808..9223372036854775807'`.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``LongestInt'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## LongestReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## LongestWord

    ### Description

    ``LongestWord'` is GPC's longest-possible unsigned integer type. Currently, this is the same as section LongWord. On most platforms it is 64 bits wide and thus has a range of ``0..18446744073709551615'`. (It is the same as section LongestCard.)

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``LongestWord'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## LongReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## LongWord

    ### Description

    ``LongWord'` is an unsigned integer type which is larger than ``Word'`. On most platforms it is 64 bits wide and thus has a range of ``0..18446744073709551615'`. It is the same as section LongCard.

    ``LongWord'` in GNU Pascal is compatible to ``long long unsigned int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``LongWord'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## low

    (Under construction.)

    ### Syntax

          Function low ( ordinal type or variable ): Integer;

    or

          Function low ( array type or variable ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## lt

    (Under construction.)

    ### Syntax

          Function lt ( S1, S2: String ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Mark

    (Under construction.)

    ### Syntax

          Procedure Mark ( Var P: Pointer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## max

    (Under construction.)

    ### Syntax

          Function max ( x1, x2: ordinal or real type ): same type;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MaxChar

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MaxInt

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MaxReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MedCard

    ### Description

    ``MedCard'` is an unsigned integer type which is not smaller than ``Cardinal'`. On most platforms it actually is the same as ``Cardinal'` and 32 bits wide and thus has a range of ``0..4294967295'`.

    ``MedCard'` in GNU Pascal is compatible to ``long unsigned int'` in GNU C. This compatibility is the reason why ``MedCard'` exists.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``MedCard'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## MedInt

    ### Description

    ``MedInt'` is a signed integer type which is not smaller than ``Integer'`. On most platforms it actually is the same as ``Integer'` and 32 bits wide and thus has a range of ``-2147483648..2147483647'`.

    ``MedInt'` in GNU Pascal is compatible to ``long int'` in GNU C. This compatibility is the reason why ``MedInt'` exists.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``MedInt'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## MedReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MedWord

    ### Description

    ``MedWord'` is an unsigned integer type which is not smaller than ``Word'`. On most platforms it actually is the same as ``Word'` and 32 bits wide and thus has a range of ``0..4294967295'`. It is the same as section MedCard.

    ``MedWord'` in GNU Pascal is compatible to ``long unsigned int'` in GNU C. This compatibility is the reason why ``MedWord'` exists.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``MedWord'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## min

    (Under construction.)

    ### Syntax

          Function min ( x1, x2: ordinal or real type ): same type;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MinReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MkDir

    (Under construction.)

    ### Syntax

          Procedure MkDir ( Directory: String );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## mod

    (Under construction.)

    ### Syntax

          Operator mod ( p, q: Integer ) = r: Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## module

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## move

    (Under construction.)

    ### Syntax

          Procedure move ( Const Source; Var Dest; Count: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MoveLeft

    (Under construction.)

    ### Syntax

          Procedure MoveLeft ( Const Source; Var Dest; Count: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## MoveRight

    (Under construction.)

    ### Syntax

          Procedure MoveRight ( Const Source; Var Dest; Count: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## near

    ### Description

    The ``near'` directive can be appended to a procedure or function heading but is ignored by GPC. It is there for Borland compatibility, only. (Since the GNU compilers provide a flat memory model, the distinction between ``near'` and ``near'` pointers is void.)

    ### Standards

    ``near'` is a Borland Pascal extension.

    ### Example

          Var
            p: Procedure;

          Procedure Foo; near;  (* `near' has no effect in GPC *)

          begin (* Foo *)
            [...]
          end (* Foo *);

          [...]

          p:= Foo;  (* Works, despite the `near'. *)

    ### See also

    section far.

    ## ne

    (Under construction.)

    ### Syntax

          Function ne ( S1, S2: String ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## New

    (Under construction.)

    ### Syntax

          Procedure New ( Var P: any pointer );

    or

          Procedure New ( Var P: pointer to a variant record; tag fields);

    or

          Procedure New ( Var P: pointer to a schema; discriminants);

    or

          Procedure New ( Var P: pointer to an object; constructor call);

    or

          Function New ( any pointer type ): same type;

    or

          Function New ( variant record pointer type;
                         tag fields): same type;

    or

          Function New ( schema pointer type;
                         discriminants): same type;

    or

          Function New ( object pointer type;
                         constructor call): same type;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## NewCString

    (Under construction.)

    ### Syntax

          Function NewCString ( Const S: String ): CString;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## nil

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## not

    (Under construction.)

    ### Syntax

          Operator not ( b1, b2: Boolean ) = result: Boolean;

    or

          Operator not ( i1, i2: integer type ) = result: integer type;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## NULL

    (Under construction.)

    ### Syntax

          Var NULL: Void absolute 0;

    ### Description

    Variable at address `Nil`.

    ### Standards

    Delphi

    ### Example

    ### See also

    section nil.

    ## object

    ### Description

    The keyword ``object'` is used to declare a new object type:

          Type
            foo = object
              a: Integer;
              Constructor Init;
              Procedure bar ( x: Integer ); virtual;
            end (* foo *);

    (For a longer example, see section Object-orientated Programming.)

    ### Standards

    GNU Pascal follows the Borland Pascal 7.0 object model.

    ISO Pascal does not support Object-orientated programming. There is an ANSI draft for an "Object Pascal" language which is not yet supported by GPC, but planned. The Delphi language, also called "Object Pascal" by Borland, is currently not supported by GPC either.

    ### See also

    section Object-orientated Programming, section record.

    ## odd

    (Under construction.)

    ### Syntax

          Function odd ( i: Integer ): Boolean;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## of

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## only

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## operator

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## or

    ### Syntax

          Operator or ( operand1, operand2: Boolean ) = result: Boolean;

    or

          Operator or ( operand1, operand2: integer type ) = result: integer type;

    or

          Procedure or ( Var operand1: integer type; operand2: integer type );

    ### Description

    In GNU Pascal, ``or'` has three built-in meanings:

    1. Logical "or" between two ``Boolean'`-type expressions. The result of the operation is of ``Boolean'` type. By default, ``or'` acts as a short-circuit operator in GPC: If the first operand is ``True'`, the second operand is not evaluated because the result is already known to be ``True'`. You can change this to complete evaluation using the ``--no-short-circuit'` command-line option or the ``(*$B+*)'` compiler directive.
    2. Bitwise "or" between two integer-type expressions. The result is of the common integer type of both expressions.
    3. Use as a "procedure": ``operand1'` is "or"ed bitwise with ``operand2'`; the result is stored in ``operand1'`.

    ### Standards

    The logical ``or'` operator is defined in ISO-7185 Standard Pascal.

    According to ISO, you cannot rely on ``or'` being a short-circuit operator. On the other hand, GPC's default behaviour does not contradict the ISO standard. (See section or_else.) However, since it seems to be a de-facto standard among ISO Pascal compilers to evaluate both operands of ``or'`, GPC switches to ``--no-short-circuit'` mode if one of the language dialect options selecting ISO Pascal, for instance ``--extended-pascal'`, is given. Use ``--short-circuit'` to override.

    Use of ``or'` as a bitwise operator for integers is a Borland Pascal extension.

    Use of ``or'` as a "procedure" is a GNU Pascal extension.

    ### Example

          Var
            a, b, c: Integer;

          ...

          if ( a = 0 ) or ( b = 0 ) then  (* logical `or' *)
            c:= 1
          else if a or b = 0 then  (* bitwise `or' *)
            c:= 2
          else
            or ( c, a );  (* same as `c:= c or a' *)

    Note the difference between the logical ``or'` and the bitwise ``or'`: When ``a'` is 2 and ``b'` is 4, then ``a or b'` is 6. Beware: ``a or b = 0'` happens to mean the same as ``( a = 0 ) and ( b = 0 )'`. (Note the ``and'`!)

    Since bitwise ``or'` has a higher priority than the ``='` operator, parentheses are needed in ``if ( a = 0 ) or ( b = 0 )'` because otherwise ``0 or b'` would be calculated first, and the remainder would cause a parse error.

    ### See also

    section and, section xor, section Operators.

    ## or else

    ### Description

    ``or else'` is an alias for the short-circuit logical operator ``or_else'`.

    ### Standards

    While ``or_else'` is defined in ISO-10206 Extended Pascal, ``or else'` is a GNU Extension.

    ### Example

          Var
            a: Integer;

          [...]

          if ( a = 0 ) or else ( 100 div a > 42 ) then  (* This is safe. *)
            [...];

    ### See also

    section or_else, section or, section and then.

    ## or_else

    ### Syntax

          Operator or_else ( operand1, operand2: Boolean ) = result: Boolean;

    ### Description

    The ``or_else'` short-circuit logical operator performs the same operation as the logical operator ``or'`. But while the ISO standard does not specify anything about the evaluation of the operands of ``or'`---they may be evaluated in any order, or not at all---``or_else'` has a well-defined behaviour: It evaluates the first operand. If the result is ``True'`, ``or_else'` returns ``True'` without evaluating the second operand. If it is ``False'`, the second operand is evaluated and returned.

    Since the behaviour described above is the most efficient way to implement ``or'`, GPC by default treats ``or'` and ``or_else'` exactly the same. If you want, for some reason, to have both operands of ``or'` evaluated completely, you must assign both to temporary variables and then use ``or'`---or ``or_else'`, it does not matter.

    ### Standards

    ``or_else'` is an ISO-10206 Extended Pascal extension.

    Some people think that the ISO standard requires both operands of ``or'` to be evaluated. This is false. What the ISO standard does say is that you cannot rely on a certain order of evaluation of the operands of ``or'`; in particular things like

          Var
            a: Integer;

          [...]

          if ( a = 0 ) or ( 100 div a > 42 ) then
            [...];

    can crash according to ISO Pascal, although they cannot crash when compiled with GNU Pascal running in default mode.

    ### Example

          Var
            a: Integer;

          [...]

          if ( a = 0 ) or_else ( 100 div a > 42 ) then  (* This is safe. *)
            [...];

    ### See also

    section or else, section or, section and_then.

    ## ord

    (Under construction.)

    ### Syntax

          Function ord ( Ch: Char ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## others

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## otherwise

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Output

    (Under construction.)

    ### Syntax

          Var
            Output: Text;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## pack

    (Under construction.)

    ### Syntax

    ### Description

          Procedure pack ( Source: unpacked array;
                           FirstElement: index type;
                           Var Dest: packed array );

    ### Standards

    ### Example

    ### See also

    ## packed

    ### Description

    ``packed'` is a reserved word. According to ISO-7185 Standard Pascal it can preceed ``array'` and ``record'` type definitions to indicate that memory usage should be minimized for variables of this type, possibly at the expense of loss of speed.

    As a GNU extension, ``packed'` can also be applied to section Subrange Types.

    ### Standards

    The reserved word ``packed'` is defined in ISO-7185 Standard Pascal.

    According to ISO standard, only packed arrays of char with lower bound 1 qualify as strings of fixed length. GNU Pascal neither requires ``packed'` nor the lower bound of 1 here.

    ### Example

          Type
            MonthInt = packed 1..12;  (* needs one byte   *)
            FastMonthInt = 1..12;     (* needs four bytes *)

            FixString10 = packed array [ 1..10 ] of Char;
            FoxyString10 = array [ 0..9 ] of Char;

            Flags = packed array [ 1..32 ] of Boolean;  (* needs four Bytes *)

            DateRec = packed record
              day: 1..31;            (* five bits *)
              month: MonthInt;       (* four bits *)
              year: Integer ( 15 );  (* 15 bits = -16384..16383 *)
            end (* DateRec *);

            Dates = array [ 1..1000 ] of DateRec;

          Var
            S: FixString10;
            T: FoxyString10;

          [...]

          S:= 'Hello!';   (* blank padded *)
          writeln ( S );

          T:= 'GNU Pascal';  (* GPC extension: this also works. *)
          writeln ( T );

    ``DateRec'` has 24 bits = 3 bytes in total; ``Dates'` has 3000 bytes.

    ### See also

    section pack, section unpack, section SizeOf, section AlignOf, section BitSizeOf.

    ## page

    (Under construction.)

    ### Syntax

          Procedure Page ( Var F: Text );

    or

          Procedure Page;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## pAnsiChar

    (Under construction.)

    ### Syntax

          Type
            pAnsiChar = ^AnsiChar;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## ParamCount

    ### Syntax

          Function ParamCount: Integer;

    ### Description

    ``ParamCount'` returns the number of command-line arguments given to the program. ``ParamCount'` returns 0 if no arguments have been given to the program; the name of the program as an implicit argument is not counted.

    ### Standards

    ``ParamCount'` is a Borland Pascal extension.

    ### Example

          Program Test;

          Var
            i: Integer;

          begin
            writeln ( 'You have invoked this program with ',
                      ParamCount, ' arguments.' );
            writeln ( 'These are:' );
            for i:= 1 to ParamCount do
              writeln ( ParamStr ( i ) );
          end.

    ### See also

    section ParamStr.

    ## ParamStr

    (Under construction.)

    ### Syntax

          Function ParamStr ( ParmNumber: Integer ): String;

    ### Description

    Note: If you are using the Dos (DJGPP) or MS-Windows (mingw32) version of GPC and are getting unexpected results from ``ParamStr'`, please see the section "Command-line Arguments Handling in DJGPP" of the DJGPP FAQ list.

    ### Standards

    ### Example

    ### See also

    ## pChar

    (Under construction.)

    ### Syntax

          Type
            pChar = ^Char;

    or

          Type
            pChar = CString;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Pointer

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## polar

    (Under construction.)

    ### Syntax

          Function polar ( rho, phi: Real ): Complex;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## pos

    (Under construction.)

    ### Syntax

          Function pos ( SearchPattern, Source: String ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Position

    (Under construction.)

    ### Syntax

          Function Position ( Var F: typed file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## pow

    (Under construction.)

    ### Syntax

          Operator pow ( base: Real; exponent: Integer ) = power: Real;

    or

          Operator pow ( base: Complex; exponent: Integer ) = power: Complex;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## pred

    ### Syntax

          Function pred ( i: ordinal type ): ordinal type;

    or

          Function pred ( i: ordinal type; j: Integer ): ordinal type;

    or, with extended syntax (``--extended-syntax'` or ``(*$X+*)'`),

          Function pred ( p: pointer type ): pointer type;

    or

          Function pred ( p: pointer type; j: Integer ): pointer type;

    ### Description

    Returns the predecessor of the ordinal type value ``i'`, or, if the second argument ``j'` is given, its ``j'`th predecessor. For integer values ``i'`, this is ``i - 1'` (or ``i - j'`). (No, ``pred'` does not work faster than plain subtraction. Both are optimized to a single machine instruction or even expanded by the compiler, if possible.)

    If extended syntax is on, the argument may also be a pointer value. In this case, the address is decremented by the size of the variable pointed to, or, if ``j'` is given, by ``j'` times the size of the variable pointed to. If ``p'` points to an element of an array, the returned pointer will point to the (``j'`th) previous element of the array.

    ### Standards

    The ``pred'` function is defined in ISO-7185 Standard Pascal. The optional second parameter is defined in ISO-10206 Extended Pascal. Application of ``pred'` to pointers is defined in Borland Pascal. The combination of the second argument with application to pointers is a GNU extension.

    ### Example

          Program PredTest;

          Type
            Metasyntactical = ( foo, bar, baz );

          Var
            m: Metasyntactical;
            c: Char;
            a: array [ 1..7 ] of Integer;
            p: ^Integer;

          begin
            m:= pred ( bar );     (* foo *)
            c:= pred ( 'Z', 2 );  (* 'X' *)
            a [ 1 ]:= 42;
            a [ 4 ]:= pred ( a [ 1 ] );     (* 41 *)
            a [ 5 ]:= pred ( a [ 4 ], 3 );  (* 38 *)
            (*$X+*)
            p:= @a [ 5 ];
            p:= pred ( p );     (* now points to `a [ 4 ]' *)
            p:= pred ( p, 3 );  (* now points to `a [ 1 ]' *)
          end.

    ### See also

    section succ, section dec, section Pointer Arithmetics.

    ## private

    (Under construction.)

    ### Syntax

    ### Description

    GPC currently accepts but ignores the ``private'` directive in object type declarations.

    ### Standards

    ### Example

    ### See also

    section protected, section public, section published.

    ## procedure

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## program

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## property

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## protected

    (Under construction.)

    ### Syntax

    ### Description

    The Extended Pascal meaning of ``protected'` is supported by GPC.

    GPC currently accepts but ignores the ``protected'` directive in object type declarations.

    ### Standards

    Extended Pascal and Borland Pascal, but with different meanings.

    ### Example

    ### See also

    section const, section import, section private, section public, section published.

    ## PtrCard

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## PtrInt

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## PtrWord

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## public

    (Under construction.)

    ### Syntax

    ### Description

    GPC currently accepts but ignores the ``public'` directive in object type declarations.

    ### Standards

    ### Example

    ### See also

    section private, section protected, section published.

    ## published

    (Under construction.)

    ### Syntax

    ### Description

    GPC currently accepts but ignores the ``published'` directive in object type declarations.

    ### Standards

    ### Example

    ### See also

    section private, section protected, section public.

    ## Put

    (Under construction.)

    ### Syntax

          Procedure Put ( Var F: typed file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## qualified

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Re

    (Under construction.)

    ### Syntax

          Function Re ( z: Complex ): Real;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## read

    (Under construction.)

    ### Syntax

          Procedure read ( Var F: typed file; variable );

    or

          Procedure read ( Var F: Text; variables );

    or

          Procedure read ( variables );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## readln

    (Under construction.)

    ### Syntax

          Procedure readln ( Var F: Text; variables );

    or

          Procedure readln ( variables );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## ReadStr

    (Under construction.)

    ### Syntax

          Procedure ReadStr ( Const S: String; variables );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Real

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## record

    ### Description

    The reserved word ``record'` starts the definition of a new record type. The syntax is

          foo = record
            field declarations
          end (* foo *);

    or, with a variant part,

          foo = record
            field declarations
            case bar: variant type of
              selector: ( field declarations );
              selector .. selector, selector: ( field declarations );
              ...
          end (* foo *);

    or, without a variant selector field,

          foo = record
            field declarations
            case variant type of
              selector: ( field declarations );
              selector .. selector, selector: ( field declarations );
              ...
          end (* foo *);

    Records can be ``packed'` to save memory usage at the expense of speed.

    The variants of a variant record share one location in memory (inside the record) and thus can be used to emulate type casting without violating ISO-7185 Standard Pascal.

    ### Standards

    The reserved word ``record'` and record types are defined in ISO-7185 Standard Pascal.

    According to ISO Pascal, the variant type must be an identifier. GNU Pascal, like UCSD and Borland Pascal, also allows a subrange here.

    Subranges in the variant fields, e.g. `case Integer of 2 .. 5`, are a GPC extension.

    ### Example

        Type
          fooPtr = ^foo;

          foo = record
            bar: Integer;
            nextFoo: fooPtr;
            case choice: 1..6 of
              1      : ( a: Integer );   (* These three choices share *)
              2, 6   : ( b: Real );      (* one location in memory.   *)
              3 .. 5 : ( c: Char;
                         d: Boolean );
          end (* foo *);

          smallFoo = packed record
            b: 0..3;
            a: Integer ( 5 );
            r: Boolean;
          end (* smallFoo *);   (* needs 1 byte *)

        Var
          f: foo;

        [...]

        f.b:= 3.14;
        writeln ( f.a );  (* yields some strange number which is part of the   *)
                          (* internal representation of the real number `f.b'. *)

    ### See also

    section packed, section array, section object.

    ## Release

    (Under construction.)

    ### Syntax

          Procedure Release ( P: Pointer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## rename

    (Under construction.)

    ### Syntax

          Procedure Rename ( Var F: any file; NewName: String );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## repeat

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## reset

    (Under construction.)

    ### Syntax

          Procedure reset ( Var F: any file );

    or

          Procedure reset ( Var F: any file; FileName: String );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## resident

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## restricted

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Result

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## return

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## rewrite

    (Under construction.)

    ### Syntax

          Procedure rewrite ( Var F: any file );

    or

          Procedure rewrite ( Var F: any file; FileName: String );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## RmDir

    (Under construction.)

    ### Syntax

          Procedure RmDir ( Directory: String );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## round

    (Under construction.)

    ### Syntax

          Function round ( x: Real ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## RunError

    (Under construction.)

    ### Syntax

          Procedure RunError ( ErrorCode: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Seek

    (Under construction.)

    ### Syntax

          Procedure Seek ( Var F: typed file; NewPosition: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## SeekRead

    (Under construction.)

    ### Syntax

          Procedure SeekRead ( Var F: typed file; NewPosition: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## SeekUpdate

    (Under construction.)

    ### Syntax

          Procedure SeekUpdate ( Var F: typed file; NewPosition: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## SeekWrite

    (Under construction.)

    ### Syntax

          Procedure SeekWrite ( Var F: typed file; NewPosition: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## segment

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Self

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## set

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## SetFileTime

          Procedure SetFileTime ( Var F: any file; time: UnixTimeType );

    ### Syntax

    ### Description

    ### Standards

    ``SetFileTime'` is a GNU extension.

    ### Example

    ### See also

    ## SetLength

    ### Syntax

          Procedure SetLength ( Var S: String; NewLength: Integer );

    ### Description

    ``SetLength'` explicitly assigns a new length ``NewLength'` to the string parameter `S`. The contents of the string is not changed; if the operation increases the length of the string, the characters appended at the end are undefined.

    If you want to use ``SetLength'`, please enable "extended syntax" (``--extended-syntax'` or ``(*$X+*)'`).

    ### Standards

    ``SetLength'` is a Borland Delphi 2.0 extension.

    ### Example

        program SetLengthDemo;

        {$X+}  { Enable "dangerous" features }

        var
          S : String (26);

        begin
          S := 'Hello, world!';
          SetLength (S, Length ('Hello'));
          Writeln (S);                                     { 'Hello' }
          SetLength (S, 26);
          Writeln (S);               { 'Hello, world!(%$xy"!#&~+(/]' }
                              { undefined characters ^^^^^^^^^^^^^^  }

          SetLength (S, 42);  { The overflow is *not* (yet) detected }
          Writeln (S);        { This might cause a runtime error.    }
        end.

    ### See also

    section length, section String, section SetType.

    ## SetType

    ### Syntax

          Procedure SetType ( Var SomeObject; VMT: Pointer );

    ### Description

    The procedure ``SetType'` explicitly assigns a value to the implicit VMT field of an object. This is normally done implicitly when a constructor is called.

    You can use this to write a polymorphic I/O routine which reads an object from a file. In this case, you cannot reasonably use ``New'` to allocate the storage, but you ``GetMem'` it and initialize the object manually using ``SetType'` before calling the constructor explicitly.

    This is a dangerous feature which yields a warning unless ``(*$X+*)'` is given.

    ### Standards

    ``SetType'` is a GNU extension.

    ### Example

          (*$X+*)

          Type
            BasePtr = ^BaseObj;

            BaseObj = object
              Constructor Load;
            end (* BaseObj *)

            [Successor objects ...]

          [...]

          Function GetObject = Result: BasePtr;

          Var
            Size: Cardinal;
            VMT: Pointer;

          begin (* GetObject *)
            [Read the size of the object from some file and store it in `Size'.]
            GetMem ( Result, Size );
            [Read some ID from some file and look up the `VMT' from some table.]
            SetType ( Result^, VMT );
            (* Now the object is ready, and the constructor can be called. *)
            [Look up the correct constructor from some table and call it.]
          end (* GetObject *);

    ### See also

    section TypeOf, section Object-orientated Programming.

    ## ShortCard

    ### Description

    ``ShortCard'` is an unsigned integer type which is not larger than ``Cardinal'`. On most platforms it is 16 bits wide and thus has a range of ``0..65535'`.

    ``ShortCard'` in GNU Pascal is compatible to ``short unsigned int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``ShortCard'` is a GNU Pascal extension.

    ### See also

    section Integer Types, section Subrange Types.

    ## ShortInt

    ### Description

    ``ShortInt'` is a signed integer type which is not larger than ``Integer'`. On most platforms it is 16 bits wide and thus has a range of ``-32768..32767'`.

    ``ShortInt'` in GNU Pascal is compatible to ``short int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``ShortInt'` is a Borland Pascal extension. In Borland Pascal, ``ShortInt'` is an 8-bit signed integer type (``ByteInt'` in GNU Pascal).

    ### See also

    section Integer Types, section Subrange Types.

    ## ShortReal

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## ShortWord

    ### Description

    ``ShortWord'` is an unsigned integer type which is not larger than ``Word'`. On most platforms it is 16 bits wide and thus has a range of of ``0..65535'`. It is the same as section ShortCard.

    ``ShortWord'` in GNU Pascal is compatible to ``short unsigned int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``ShortWord'` is a GNU Pascal extension.

    ``ShortWord'` in GNU Pascal essentially corresponds to ``Word'` in Borland Pascal and Delphi where it is a 16-bit unsigned integer type.

    ### See also

    section Integer Types, section Subrange Types.

    ## Single

    (Under construction.)

    ### Syntax

          Type
            Single = ShortReal;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## shl

    ### Syntax

          Operator shl ( operand1, operand2: integer type ) = result: integer type;

    or

          Procedure shl ( Var operand1: integer type; operand2: integer type );

    ### Description

    In GNU Pascal, ``shl'` has two built-in meanings:

    1. Bitwise shift left of an integer-type expression by another integer value. The result is of the type of the first operand.
    2. Use as a "procedure": ``operand1'` is shifted left by ``operand2'`; the result is stored in ``operand1'`.

    ### Standards

    ``shl'` is a Borland Pascal extension.

    Use of ``shl'` as a "procedure" is a GNU Pascal extension.

    ### Example

          Var
            a: Integer;

          ...

          a:= 1 shl 7;  (* yields 128 = 2 pow 7 *)
          shl ( a, 4 );  (* same as `a:= a shl 4' *)

    ### See also

    section shr, section Operators.

    ## shr

    ### Syntax

          Operator shr ( operand1, operand2: integer type ) = result: integer type;

    or

          Procedure shr ( Var operand1: integer type; operand2: integer type );

    ### Description

    In GNU Pascal, ``shr'` has two built-in meanings:

    1. Bitwise shift right of an integer-type expression by another integer value. The result is of the type of the first operand.
    2. Use as a "procedure": ``operand1'` is shifted right by ``operand2'`; the result is stored in ``operand1'`.

    ### Standards

    ``shr'` is a Borland Pascal extension.

    Unlike the Borland compilers, GNU Pascal cares about the signedness of the first operand: If a signed integer with a negative value is shifted right, "one" bits are filled in from the left.

    Use of ``shr'` as a "procedure" is a GNU extension.

    ### Example

          Var
            a: Integer;

          ...

          a:= 1024 shr 4;  (* yields 64 *)
          a:= -127 shr 4;  (* yields -7 *)
          shr ( a, 2 );  (* same as `a:= a shr 2' *)

    ### See also

    section shl, section Operators.

    ## sin

    (Under construction.)

    ### Syntax

          Function sin ( x: Real ): Real;

    or

          Function sin ( z: Complex ): Complex;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## SizeOf

    ### Syntax

          Function SizeOf ( Var x ): SizeType;

    ### Description

    Returns the size of a type or variable in bytes.

    ### Standards

    ``SizeOf'` is an UCSD Pascal extension.

    ### Example

          Var
            a: Integer;
            b: array [ 1..8 ] of Char;

          ...

          writeln ( SizeOf ( a ) );  (* Size of an `Integer'; often 4 bytes. *)
          writeln ( SizeOf ( b ) );  (* Size of eight `Char's; usually 8 bytes. *)

    ### See also

    section BitSizeOf, section AlignOf, section TypeOf.

    ## SmallInt

    ### Description

    ``SmallInt'` is a signed integer type which is not larger than ``Integer'`. On most platforms it is 16 bits wide and thus has a range of ``-32768..32767'`. It is the same as ``ShortInt'` (see section ShortInt).

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ``SmallInt'` is a Delphi 2.0 extension.

    ### See also

    section ShortInt, section Integer Types, section Subrange Types.

    ## sqr

    ### Syntax

          Function sqr ( i: integer type ): integer type;

    or

          Function sqr ( x: real type ): real type;

    or

          Function sqr ( z: complex type ): complex type;

    ### Description

    Returns the square of the argument:

          Function sqr ( x: some type ): some type;

          begin (* sqr *)
            sqr:= x * x;  (* or: x pow 2 *)
          end (* sqr *);

    ### Standards

    The function ``sqr'` is defined in ISO-7185 Standard Pascal; its application to complex values is defined in ISO-10206 Extended Pascal.

    ### Example

          Program TestSqr;

          Var
            i: Complex;

          begin
            i:= cmplx ( 0, 1 );
            writeln ( Re ( sqr ( i ) : 0 : 3 );
            (* yields -1.000 *)
          end.

    ### See also

    section pow, section sqrt, section abs, section Operators.

    ## sqrt

    ### Syntax

          Function sqrt ( x: real type ): real type;

    or

          Function sqrt ( z: complex type ): complex type;

    ### Description

    Returns the positive square root of the argument.

    For real arguments, it is an error if the argument is negative.

    For complex arguments, ``sqrt'` returns the principal value of the root of the argument, i.e. the root with positive real part, or, if the real part is zero, that one with positive imaginary part.

    ### Standards

    The function ``sqrt'` is defined in ISO-7185 Standard Pascal; its application to complex values is defined in ISO-10206 Extended Pascal.

    ### Example

          Program TestSqrt;

          Var
            m1: Complex;

          begin
            m1:= cmplx ( -1, 0 );  (* -1 *)
            writeln ( Re ( sqrt ( m1 ) ) : 6 : 3, Im ( sqrt ( m1 ) ) : 6 : 3 );
            (* yields 1.000 -1.000, i.e. the imaginary unit, i *)
          end.

    ### See also

    section pow, section sqr, section Operators.

    ## StandardError

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## StandardInput

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## StandardOutput

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## static

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## StdErr

    ### Syntax

          Var
            StdErr: Text;

    ### Description

    The ``StdErr'` variable is connected to the standard error device. To report errors, you should prefer ``writeln ( StdErr, 'everything wrong' )'` over ``writeln ( 'everything wrong' )'`.

    ### Standards

    ``StdErr'` is a GNU Pascal extension.

    ### Example

          Var
            Denominator: Integer;

          ...

          readln ( Denominator );
          if Denominator = 0 then
            writeln ( StdErr, ParamStr ( 0 ), ': division by zero' )
          else
            writeln ( '1 / ', Denominator, ' = ', 1 / Denominator )

    ### See also

    section StandardError, section Output, section Input.

    ## Str

    (Under construction.)

    ### Syntax

          Procedure Str ( x: integer or real; Var Dest: String );

    or

          Procedure Str ( x: integer or real : field width; Var Dest: String );

    or

          Procedure Str ( x: Real : field width : precision; Var Dest: String );

    or

          Procedure Str ( repeated constructs as described above; Var Dest: String );

    ### Description

    ### Standards

    ``Str'` is an UCSD Pascal extension, generalized by Borland Pascal. The possibility to handle more than one variable with one call to ``Str'` is a GNU Pascal extension.

    ISO-10206 Extended Pascal defines ``WriteStr'` instead of ``Str'`.

    ### Example

    ### See also

    section WriteStr.

    ## CStringCopyString

    (Under construction.)

    ### Syntax

          Function CStringCopyString ( Dest: CString; Const Source: String ): CString;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## String

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## String2CString

    (Under construction.)

    ### Syntax

          Function String2CString ( Const S: String ): CString;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## SubStr

    ### Syntax

          Function SubStr ( S: String; FirstChar: Integer ): String;

    or

          Function SubStr ( S: String; FirstChar, Count: Integer ): String;

    ### Description

    ``SubStr'` returns a sub-string of S starting with the character at position FirstChar. If Count is given, such many characters will be copied into the sub-string. If Count is omitted, the sub-string will will range to the end of S.

    If ``Count'` is too large for the sub-string to fit in S or if ``FirstChar'` exceeds the length of S, ``SubStr'` triggers a runtime error. (For a function returning the empty string instead, see section Copy.)

    ### Standards

    ``SubStr'` is a ISO 10206 Extended Pascal extension.

    ### Example

          Var
            S: String ( 42 );

          [...]

          S:= 'Hello';
          writeln ( SubStr ( S, 2, 3 ) );   (* yields "ell" *)
          writeln ( SubStr ( S, 3 ) );      (* yields "llo" *)
          writeln ( SubStr ( S, 4, 7 ) );   (* yields a runtime error *)
          writeln ( SubStr ( S, 42 ) );     (* yields a runtime error *)

    ### See also

    section Copy, String slice access.

    ## succ

    ### Syntax

          Function succ ( i: ordinal type ): ordinal type;

    or

          Function succ ( i: ordinal type; j: Integer ): ordinal type;

    or, with extended syntax (``--extended-syntax'` or ``(*$X+*)'`),

          Function succ ( p: pointer type ): pointer type;

    or

          Function succ ( p: pointer type; j: Integer ): pointer type;

    ### Description

    Returns the successor of the ordinal type value ``i'`, or, if the second argument ``j'` is given, its ``j'`th successor. For integer values ``i'`, this is ``i + 1'` (or ``i + j'`). (No, ``succ'` does not work faster than plain addition. Both are optimized to a single machine instruction or even expanded by the compiler, if possible.)

    If extended syntax is on, the argument may also be a pointer value. In this case, the address is incremented by the size of the variable pointed to, or, if ``j'` is given, by ``j'` times the size of the variable pointed to. If ``p'` points to an element of an array, the returned pointer will point to the (``j'`th) next element of the array.

    ### Standards

    The ``succ'` function is defined in ISO-7185 Standard Pascal. The optional second parameter is defined in ISO-10206 Extended Pascal. Application of ``succ'` to pointers is defined in Borland Pascal. The combination of the second argument with application to pointers is a GNU extension.

    ### Example

          Program SuccTest;

          Type
            Metasyntactical = ( foo, bar, baz );

          Var
            m: Metasyntactical;
            c: Char;
            a: array [ 1..7 ] of Integer;
            p: ^Integer;

          begin
            m:= succ ( foo );     (* bar *)
            c:= succ ( 'A', 4 );  (* 'E' *)
            a [ 1 ]:= 42;
            a [ 2 ]:= succ ( a [ 1 ] );     (* 43 *)
            a [ 5 ]:= succ ( a [ 2 ], 7 );  (* 50 *)
            (*$X+*)
            p:= @a [ 1 ];
            p:= succ ( p );     (* now points to `a [ 2 ]' *)
            p:= succ ( p, 3 );  (* now points to `a [ 5 ]' *)
          end.

    ### See also

    section pred, section inc, section Pointer Arithmetics.

    ## Text

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## then

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Time

    (Under construction.)

    ### Syntax

          Function Time ( T: TimeStamp ):
              packed array [ 1..time length ] of Char;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## TimeStamp

    (Under construction.)

    ### Syntax

        type
          TimeStamp = {@@packed} record
            DateValid,
            TimeValid   : Boolean;
            Year        : Integer;
            Month       : 1 .. 12;
            Day         : 1 .. 31;
            DayOfWeek   : 0 .. 6;  { 0 means Sunday }
            Hour        : 0 .. 23;
            Minute      : 0 .. 59;
            Second      : 0 .. 61; { to allow for leap seconds }
            MicroSecond : 0 .. 999999
          end;

    (@@ Currently, in GPC, TimeStamp is not actually packed.)

    All fields except DayOfWeek and MicroSecond are required by Extended Pascal.

    @@ `TimeStamp` may be later extended in GPC to contain the following additional fields:

        Dst_used   : Boolean;  { If daylight savings are used }
        TimeZone   : Integer;  { Positive if west, in minutes }
        TimerValid : Boolean;  { Is the following timer valid }
        us_Timer   : Integer;  { A microsecond timer that is a 32 bit
                                  modulus of the timer returned by the system. }

    Fields `Dst_used, TimeZone` and `DayOfWeek` will be valid when `DateValid` is `True`. Field `us_Timer` will be valid when `TimerValid` is `True`.

    ### Description

    ### Standards

    ### Example

    ### See also

    ## to

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## to begin do

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## to end do

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Trim

    (Under construction.)

    ### Syntax

          Function Trim ( S: String ): String;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## True

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## trunc

    (Under construction.)

    ### Syntax

          Function trunc ( x: Real ): Integer;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Truncate

    (Under construction.)

    ### Syntax

          Procedure Truncate ( Var F: any file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## type

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## type of

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## TypeOf

    ### Syntax

          Function TypeOf ( Var x ): Pointer;

    ### Description

    Returns a pointer to the VMT of an object type or variable. This pointer can be used to identify the type of an object.

    ### Standards

    ISO Pascal does not define ``TypeOf'`, Borland Pascal does.

    ### Example

          Type
            fooPtr = ^foo;
            barPtr = ^bar;

            foo = object        (* Has a VMT, though it doesn't *)
              x: Integer;       (* contain virtual methods.     *)
              Constructor Init;
            end (* foo *);

            bar = object ( foo )
              y: Integer;
            end (* bar *);

          Var
            MyFoo: fooPtr;

          [...]

          MyFoo:= New ( barPtr, Init );

          if TypeOf ( MyFoo^ ) = TypeOf ( bar ) then  (* True *)
            writeln ( 'OK' );

    ### See also

    section BitSizeOf, section AlignOf, section TypeOf, section SetType, section Object-orientated Programming.

    ## UnBind

    (Under construction.)

    ### Syntax

          Procedure UnBind ( Var F: any file );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## unit

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## unpack

    (Under construction.)

    ### Syntax

          Procedure unpack ( Source: packed array;
                             Var Dest: unpacked array;
                             FirstElement: index type );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## until

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## UpCase

    (Under construction.)

    ### Syntax

          Function UpCase ( Ch: Char ): Char;

    ### Description

    ### Standards

    ### Example

    ### See also

    ## update

    (Under construction.)

    ### Syntax

          Procedure update ( Var F: any file );

    or

          Procedure update ( Var F: any file; FileName: String );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## uses

    ### Description

    The reserved word ``uses'` in the import part of a program makes the program import an interface. The syntax is

          Program foo;

          uses
            bar1,
            bar2 in 'baz.pas',
            bar3;

          [...]

    or, in a Unit,

          Unit Bar3;

          Interface

          uses
            bar1,
            bar2 in 'baz.pas';

          [...]

    The ``in'` above tells GPC to look for the ``Unit'` in the specified file; otherwise the file name is derived from the name of the interface by adding first ``.p'`, then ``.pas'`.

    There must be at most one import part in a program.

    In a Unit, there is only one import part in the interface part; GPC currently does not support a second import part in the implementation part.

    The imported interface needn't be an UCSD/Borland Pascal Unit, it may be an interface exported by an Extended Pascal Module as well.

    ### Standards

    ISO Pascal does not define ``uses'` and Units in general. UCSD and Borland Pascal do, but without the ``in'` extension. Delphi supports ``uses'` like described above.

    ### See also

    section unit, section module, section import.

    ## Val

    (Under construction.)

    ### Syntax

          Procedure Val ( Const Source: String; Var x: integer or real );

    or

          Procedure Val ( Const Source: String; Var x: integer or real;
                          Var ErrorCode: Integer );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## value

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## var

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## view

    Not yet implemented.

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## virtual

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Void

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## volatile

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## while

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## with

    (Under construction.)

    ### Syntax

    ### Description

    ### Standards

    ### Example

    ### See also

    ## Word

    ### Description

    ``Word'` is the "natural" unsigned integer type in GNU Pascal. On most platforms it is 32 bits wide and thus has a range of ``0..4294967295'`. It is the same as section Cardinal, introduced for compatibility with other Pascal compilers.

    As an extension, GPC allows to use ``Word'` as a pseudo-schema to produce types with a specified size in bits; for example

          Type
            Word16 = Cardinal ( 16 );

    defines an unsigned integer type with 16 bits. The same mechanism works for ``Cardinal'` and ``Integer'`, too.

    ``Word'` in GNU Pascal is compatible to ``unsigned int'` in GNU C.

    There are lots of other integer types in GPC, see section Integer Types.

    ### Standards

    ISO Pascal does not define ``Cardinal'`. (However see section Subrange Types.)

    The ``Word'` type appears in Borland Pascal and Delphi, too, where it is a 16-bit unsigned integer type.

    ### See also

    section Integer Types, section Subrange Types.

    ## write

    (Under construction.)

    ### Syntax

          Procedure write ( Var F: typed file; variable );

    or

          Procedure write ( Var F: Text; values and format specifications );

    or

          Procedure write ( values and format specifications );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## writeln

    (Under construction.)

    ### Syntax

          Procedure writeln ( Var F: Text; values and format specifications );

    or

          Procedure writeln ( values and format specifications );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## WriteStr

    (Under construction.)

    ### Syntax

          Procedure WriteStr ( Var Dest: String; values and format specifications );

    ### Description

    ### Standards

    ### Example

    ### See also

    ## xor

    ### Syntax

          Operator xor ( operand1, operand2: Boolean ) = result: Boolean;

    or

          Operator xor ( operand1, operand2: integer type ) = result: integer type;

    or

          Procedure xor ( Var operand1: integer type; operand2: integer type );

    ### Description

    In GNU Pascal, ``xor'` has three built-in meanings:

    1. Logical "exclusive or" between two ``Boolean'`-type expressions. The result of the operation is of ``Boolean'` type. (Logical ``foo xor bar'` in fact has the same effect as ``foo <> bar'`.)
    2. Bitwise "exclusive or" between two integer-type expressions. The result is of the common integer type of both expressions.
    3. Use as a "procedure": ``operand1'` is "xor"ed bitwise with ``operand2'`; the result is stored in ``operand1'`.

    ### Standards

    ISO Pascal does not define the ``xor'` operator; Borland Pascal and Delphi do.

    Use of ``xor'` as a "procedure" is a GNU extension.

    ### Example

          Var
            a, b, c: Integer;

          ...

          if ( a = 0 ) xor ( b = 0 ) then
            c:= 1  (* happens if either `a' or `b' is zero,    *)
                   (* but not if both are zero or both nonzero *)

          else if a xor b = 0 then
            c:= 2

          else
            xor ( c, a );  (* same as `c:= c xor a' *)

    ### See also

    section and, section or, section Operators.

    @unmacro unnumberedsubsec

    # Keywords supported by GNU Pascal

    This chapter lists all keywords understood by GNU Pascal.

    By default, keywords can be redefined to make it possible that every correct ISO 7185 program can be compiled. However, you can use the compiler dialect switches (e.g., `--extended-pascal` or `--borland-pascal`) to tell GPC that keywords of a given standard must not be redefined.

    The keywords are taken from the following standards:

    - ISO 7185 Standard Pascal (SP)
    - ISO 10206 Extended Pascal (EP)
    - ANSI draft Object Pascal (OP)
    - USCD Pascal (USCD)
    - Borland Pascal 7.0 (BP)
    - Borland Delphi (BD)
    - Pascal-SC (PXSC, Pascal eXtensions for Scientific Calculations)
    - VAX Pascal (VP)
    - GNU Pascal extensions (GPC)

    In GPC you are free to re-define everything that is not a reserved word in ISO 7185 Pascal in your program or the dialect selected. E.g., you do not have to modify your code for GPC if you have an identifier like `Restricted` or `Value` or some such, unless you compile with the ``--extended-pascal'` option.

    The following table lists all known keywords with short descriptions. The links point to the longer descriptions in the reference.

    absolute (BP, BD, GPC) (see section absolute)
      overloaded variable declaration
    abstract (OP, GPC) (see section abstract)
      abstract object type declaration (not yet implemented)
    all (GPC) (see section all)
      ``export'` (see section export) extension (``export foo = all'`)
    and (any) (see section and)
      Boolean or bitwise ``and'` operator or part of the ``and then'` (see section and then) operator
    and_then (EP, OP, GPC) (see section and_then)
      short-circuit Boolean ``and'` (see section and) operator
    array (any) (see section array)
      array type declaration
    asm (BP, BD, GPC) (see section asm)
      GNU style inline assembler code
    asmname (GPC) (see section asmname)
      linker name of routines and variables
    attribute (GPC) (see section attribute)
      attributes of routines and variables
    begin (any) (see section begin)
      begin of a code block, part of a ``to begin do'` (see section to begin do) module constructor
    bindable (EP, OP, GPC) (see section bindable)
      external binding of files
    case (any) (see section case)
      multi-branch conditional statement or variant record type
    class (OP, BD, GPC) (see section class)
      OOE/Delphi style object classes (not yet implemented)
    const (any) (see section const)
      constant declaration or constant parameter declaration
    constructor (OP, BP, BD, GPC) (see section constructor)
      object constructor
    destructor (OP, BP, BD, GPC) (see section destructor)
      object destructor
    div (any) (see section div)
      integer or real division operator
    do (any) (see section do)
      part of a ``while'` (see section while) or ``for'` (see section for) loop or a ``to begin do'` (see section to begin do) or ``to end do'` (see section to end do) module constructor or destructor
    downto (any) (see section downto)
      part of a ``for'` (see section for) loop when counting downwards
    else (any) (see section else)
      alternative part of an ``if'` (see section if) statement, default case label or part of the ``or else'` (see section or else) operator
    end (any) (see section end)
      end of a code block, end of a ``case'` (see section case) statement, end of a record or object declaration, part of a ``to end do'` (see section to end do) module destructor
    export (EP, OP, BP, BD, GPC) (see section export)
      module interface export
    exports (BP, BD, GPC) (see section exports)
      library export (not yet implemented)
    external (EP, OP, UCSD, BP, BD, GPC) (see section external)
      declaration of external objects
    file (any) (see section file)
      non-text file type declaration
    for (any) (see section for)
      loop statement where the number of loops is known in advance
    forward (UCSD, BP, BD, GPC) (see section forward)
      declaration of a routine whose definition follows below
    function (any) (see section function)
      function declaration
    goto (any) (see section goto)
      statement to jump to a ``label'` (see section label)
    if (any) (see section if)
      conditional statement
    import (EP, OP, GPC) (see section import)
      module interface import
    implementation (EP, OP, UCSD, BP, BD, GPC) (see section implementation)
      module or unit implementation part
    in (any) (see section in)
      set membership test or part of a ``for'` (see section for) loop when iterating through sets
    inherited (OP, BP, BD, GPC) (see section inherited)
      reference to methods of ancestor object types
    inline (GPC) (see section inline)
      declaration of inline routines
    interface (EP, OP, UCSD, BP, BD, GPC) (see section interface)
      module or unit interface part
    interrupt (BP, BD) (see section interrupt)
      interrupt handler declaration (not yet implemented)
    is (OP, BD, GPC) (see section is)
      object type membership test (not yet implemented)
    label (any) (see section label)
      label declaration for a ``goto'` (see section goto) statement
    library (BP, BD, GPC) (see section library)
      library declaration (not yet implemented)
    mod (any) (see section mod)
      integer remainder operator
    module (EP, OP, GPC) (see section module)
      EP style or PXSC style (only partially implemented) modules
    nil (any) (see section nil)
      reserved value for unassigned pointers
    not (any) (see section not)
      Boolean or bitwise ``not'` operator
    object (BP, BD, GPC) (see section object)
      BP style object declaration
    of (any) (see section of)
      part of an array, set or typed file type declaration, a ``case'` (see section case) statement, a variant record type or a ``type of'` (see section type of) type inquiry
    only (EP, OP, GPC) (see section only)
      import specification
    operator (PXSC, GPC) (see section operator)
      operator declaration
    or (any) (see section or)
      Boolean or bitwise ``or'` operator or part of the ``or else'` (see section or else) operator
    or_else (EP, OP, GPC) (see section or_else)
      short-circuit Boolean ``or'` (see section or) operator
    otherwise (EP, OP, GPC) (see section otherwise)
      default case label
    packed (any) (see section packed)
      declaration of packed record or array types, also packed ordinal subranges
    pow (EP, OP, GPC) (see section pow)
      exponentiation operator with integer exponent
    private (BP, BD, GPC) (see section private)
      private object fields
    procedure (any) (see section procedure)
      procedure declaration
    program (any) (see section program)
      start of a Pascal program
    property (OP, BD, GPC) (see section property)
      variable properties (not yet implemented)
    protected (EP, OP, BD, GPC) (see section protected)
      read-only formal parameters and protected object fields
    public (BP, BD, GPC) (see section public)
      public object fields
    published (BP, BD, GPC) (see section published)
      published object fields
    qualified (EP, OP, GPC) (see section qualified)
      import specification
    record (any) (see section record)
      structured type declaration
    repeat (any) (see section repeat)
      loop statement
    resident (BP, BD) (see section resident)
      library export specification (not yet implemented)
    restricted (EP, OP, GPC) (see section restricted)
      type specification
    segment (UCSD) (see section segment)
      segment specification (not yet implemented)
    set (any) (see section set)
      set type declaration
    shl (BP, BD, GPC) (see section shl)
      bitwise left shift operator
    shr (BP, BD, GPC) (see section shr)
      bitwise right shift operator
    static (GPC) (see section static)
      static variable declaration
    then (any) (see section then)
      part of an ``if'` (see section if) statement or part of the ``and then'` (see section and then) operator
    to (any) (see section to)
      part of a ``for'` (see section for) loop when counting upwards or a ``to begin do'` (see section to begin do) or ``to end do'` (see section to end do) module constructor or destructor
    type (any) (see section type)
      type declaration or part of a ``type of'` (see section type of) type inquiry
    unit (UCSD, BP, BD, GPC) (see section unit)
      UCSD and BP style unit declaration
    until (any) (see section until)
      end of a ``repeat'` (see section repeat) statement
    uses (UCSD, BP, BD, GPC) (see section uses)
      unit import
    value (EP, OP, GPC) (see section value)
      variable initializer
    var (any) (see section var)
      variable declaration or reference parameter declaration
    view (OP, GPC) (see section view)
      object class view (not yet implemented)
    virtual (OP, BP, BD, GPC) (see section virtual)
      virtual object method declaration
    volatile (GPC) (see section volatile)
      volatile variable declaration
    while (any) (see section while)
      loop statement
    with (any) (see section with)
      automatic record or object field access
    xor (BP, BD, GPC) (see section xor)
      Boolean or bitwise ``exclusive or'` operator

    # Where to get support for GNU Pascal; how to report bugs

    Here you can find information on how you can support (professional or voluntary) for GPC, how to find out about the known bugs in GPC, how to use GPC's Test Suite, and how to report new bugs you might encounter.

    Note: If you have installed a GPC binary distribution, you usually won't have the test suite installed (you can download the GPC source distribution to get it, however), so the section ``Running the GPC Test Suite'` does not apply to you. Still, you can find in the section ``Contributing Tests to the Test Suite'` how to report GPC bugs in the form of new test programs so we can fix them as fast as possible.

    ## Where to get support for GPC

    GPC is free software and comes without any warranty.

    If you want to get professional support except, you can pay an individual or a company to provide such a service.

    To find such an individual or company, look into the GNU Service Directory which is a list of people who offer support and other consulting services. It is in the file ``SERVICE'` in the GNU GCC distribution and in the GNU Emacs distribution, ``/pub/gnu/GNUinfo/SERVICE'` on a GNU FTP host, and @uref{http://www.gnu.ai.mit.edu/prep/service.html} in the World Wide Web. Contact the Free Software Foundation (FSF) to get a copy or to be listed in it (see the file ``COPYING'` for the address).

    In addition, you can try to find support through the Internet. The first address is the GNU Pascal mailing list, @email{gpc@gnu.de}. To join the list, send an e-mail to @email{gpc-request@gnu.de}.

    You can also ask the Usenet newsgroups for help. There is no specialized newsgroup for GNU Pascal, so use the one which is most appropriate for your problem. When in doubt, we recommend @uref{news://comp.lang.pascal.misc}.

    Please honor our work by contributing yours. When somebody has solved your problems in a newsgroup, watch out for other people's problems you can help to solve.

    ## The GPC Mailing List

    @@ under construction

    The address of the GNU Pascal mailing list is @email{gpc@gnu.de}. To join the list, send an e-mail to @email{gpc-request@gnu.de}.

    ## The GPC FAQ

    @@ under construction

    Please see the file ``FAQ'`.

    ## The GPC To-Do List

    There are some known bugs in GPC which will take some time to be fixed. (Any help welcome!) You can find the current To-Do list on the GPC home page in the WWW, @uref{http://agnes.dida.physik.uni-essen.de/~gnu-pascal/todo.html}.

    If you encounter a bug with GPC, please check whether it is one of the known bugs. If not, report it to the GNU Pascal mailing list. (But always report it if you solve the problem! ;-)

    ## Running the GPC Test Suite

    The files in the test directory and subdirectories are for testing GPC only and should not be of any other use.

    Note: A few of the tests do not make sense on all systems. They are equipped with checks and will be skipped if they find the system not suitable. Skipped tests do *not* indicate a GPC bug, unless you have a reason to be sure that the particular test should make sense on your system.

    - To run the whole test suite, type ``make'` in the test directory (or ``make check'` in the ``p'` object directory after building GPC).
    - The output will show all errors encountered (hopefully none) and tests skipped, and finally display a summary giving the number of successful, failed and skipped tests. Any failed test indicates a bug in GPC which should be reported to the GPC mailing list, @email{gpc@gnu.de}. Don't forget to mention the operating system you ran the test on and any other relevant information about what you did.
    - You can also type ``make check-gpc-long'` to get a long output which is a sequence of file names followed by ``OK'` for successful tests, ``SKIPPED'` for skipped tests (both in capital letters), and anything else for failed tests.
    - To run only some of the tests, you can type something like ``make MASK="foo[1-7]*.pas"'` or ``make MASK="foo42.pas" check-gpc-long'`.
    - To clean up after running the tests, type ``make clean'`.

    ## Contributing Tests to the Test Suite

    If you want to contribute a test program, please note the following formalities which are easy to fulfill and make it much easier for us to reproduce and finally fix the problem:

    - Please send a description of the problem, with the full text of any error messages encountered, or a description of how some output varies from the expected output. Send it to the GPC mailing list, @email{gpc@gnu.de}. Always specify the operating system type with version and the machine type (try ``uname -a'` if unsure) as well as the version of GPC as printed by ``gpc -v'`.

    The rest of this section applies if the problem is with the compiler itself, not an installation problem or something like this.

    - Please provide a test program to reproduce the problem. The test program should be as short as possible, but by all means, please send a complete program and make sure that it still reproduces the problem before you send it. Too often, users have sent code which contained obvious syntax errors far before the actual problem, or just code fragments we could only make wild guesses about. This is unproductive for us and doesn't help you get your problem solved.
    - The file containing the main program must contain the keyword ``program'` (case-insensitively) to be recognized by the testing script. Other files, which can contain units or modules or data needed by the program, must not contain the word ``program'`.
    - Since the test suite must run under very ... nah ... strange operating systems, too, file names must be distinguished in their first eight characters (case-insensitively) and should not contain anything but letters, numbers, hyphens, underscores and a single dot. The extension must be ``.pas'` to be recognized by the testing script. Furthermore, any ancillary files (units, modules, includes, data files) should not be longer than "8+3" characters. It is often a good idea to use your name, nickname or initials followed by a number as the file name.
    - The test program, when run, should produce a line of output consisting of the string ``OK'` (followed by a newline), if everything went as expected, and something else (e.g. ``failed'`, possibly followed by the reason of failure) if something went wrong.
    - However, if the program is intended to check whether GPC catches an (intentional) error in the program, place the string ``WRONG'` somewhere in the test program, preferably in a comment in the line that contains the intentional error, and make the program output ``failed'` or something like this if it does compile erroneously.

    The following special features of the testing script may be helpful for constructing tests:

    - If the expected output is something else than ``OK'`, place it in a file ``<basename>.out'` (where ``<basename>'` is the name of the test program without the ``.pas'` extension).
    - If the test program expects some input, place it in a file ``<basename>.in'`. It will automatically be redirected to the program's standard input.
    - If the test needs some special flags to be given to the GPC command line, place them in a comment preceeded by ``FLAG'`, e.g.:

          (* FLAG --extended-pascal -Werror *)

    - The source file name of the test program will be passed as the first command-line argument to the test program run.
    - If a test needs to be run in a special way, you can accompany the program with a script ``<basename>.run'` that will do the actual test after the test program was compiled. In order to be portable, this script should run ``/bin/sh'` and only use standard tools. The source file name of the test program will be passed as the first command-line argument to the run script in this case. The compiled file is always called ``a.out'`.
    - If a test needs to be compiled in a special way (e.g., to decide whether to skip the test), place the commands in a script (preferably called ``<basename>.cmp'`), and put the file name of the script (without directory) in a comment preceeded by ``COMPILE-CMD:'` into the source of the test program. The compile script will be run *instead* of any other action for this test program, so it gives you maximum flexibility to do whatever you need to do. In order to be portable, this script should run ``/bin/sh'` and only use standard tools. The first command-line argument to the compile script will be the compiler to use, including all options. The second argument will be the source file name of the test program. For some typical tests, there are standard compile scripts, e.g. ``i386.cmp'` which will skip the test unless run on an i386 compatible processor. This is necessary, e.g., when testing assembler code. Of course, it's still better to avoid having to use such scripts when possible.

    # Contributors to GNU Pascal

    Jukka Virtanen
      invented GNU Pascal in March 1988, implemented the ISO-7185 and most of the ISO-10206 standard, etc.
    Peter Gerwinski
      added Borland-Pascal-related and other extensions to GNU Pascal in summer 1995, ported GPC to EMX, does most of the development of the compiler since 1996, created and maintains the WWW home page, does some other administrative stuff, etc.
    Jan-Jaap van der Heijden
      ported GPC to DJGPP and to Microsoft Windows 95/NT, added ELF support in spring 1996, solved a lot of configuration and compatibility problems, created the GPC FAQ, etc.
    Frank Heckenbach
      rewrote and maintains the Run Time System since July 1997, wrote most of the standard units distributed with GPC (including BP compatibility units), wrote a large number of test programs, maintains the GPC To-Do list (see section The GPC To-Do List) etc.
    Dr Abimbola A. Olowofoyeku ("The African Chief")
      created the original versions of many BP compatibility units in May 1997, contributed code to other units and the Run Time System, helped porting GPC and the units to Cygwin and Mingw, wrote a number of test programs, etc.
    Nick Burrett
      fixed some bugs and cleaned up GPC in May 1998, etc.
    Matthias Klose
      integrated GPC into EGCS and Debian GNU/Linux in May 1998, improved the installation process, etc.
    Alexey Volokhov
      improved the performance of GPC's module (unit) support in June 1997.
    Bill Currie
      implemented more Borland extensions into GPC in July 1997.

    The development of GNU Pascal profits a lot from independent contributions (which are not part of this distribution):

    Berend de Boer
      wrote a lot of useful documentation about Extended Pascal in 1995.
    Markus Gerwinski
      created the drawing showing a Gnu with Blaise Pascal (JPEG, 3 kB) (PNG, 10 kB) and helped to design the WWW home page in October 1996.
    Russ Whitaker
      updated and maintains the GPC FAQ, section The GPC FAQ.
    Nicola Girardi
      contributed a GPC unit for the ``svgalib'` graphics library for some platforms @uref{http://agnes.dida.physik.uni-essen.de/~nicola/} in February 2000.
    Phil Nelson
      created a bug reporting system for GPC in October 1996. @item Robert Höhne wrote RHIDE @uref{http://www.tu-chemnitz.de/~rho/rhide.html}, an integrated development environment for GNU compilers running under Dos (DJGPP) and Linux, and added support for GNU Pascal in autumn 1996.
    Sven Hilscher
      wrote BGI2GRX @uref{ftp://agnes.dida.physik.uni-essen.de/~gnu-pascal/contrib/}, a BP compatible ``Graph'` unit for some platforms in December 1996.
    Dario Anzani ("Predator Zeta")
      contributed documentation about the use of assembler in GNU Pascal in May 1997.
    Lluis de Yzaguirre i Maura
      set up a HTML version of the GNU Pascal mailing list archives, section The GPC Mailing List), in September 1997.
    `(-:---------:-)`
      This space is reserved for your name. ;-) Please contact us at the GPC mailing list, section The GPC Mailing List), if you have something interesting for us.

    We thank everybody who supports us by reporting bugs, contributing knowledge and good ideas, donating development tools, and giving us the opportunity to test GPC on a large variety of systems. We are particularly indebted (in alphabetical order, individuals first) to

    Sietse Achterop, Geoffrey Arnold, Ariel Bendersky, Pablo Bendersky, John Blakeney, Nils Bokermann, Patrice Bouchand, Jim Brander, Matze Braun, J. David Bryan, Nick Burrett, Ricky W. Butler, Dr. E. Buxbaum, Larry Carter, Janet Casey, Romain Chantereau, Emmanuel Chaput, Carl Eric Codere, Miklos Cserzo, Tim Currie, Stefan A. Deutscher, Anja Drewitz, Thomas Dunbar, Andreas Eckleder, Sven Engelhardt, Klaus Espenlaub, Toby Ewing, David Fiddes, Alfredo Cesar Fontana, Kevin A. Foss, Marius Gedminas, Nicholas Geovanis, Jose Oliver Gil, Jakob Heinemann, Mason Ip, Andreas Jaeger, David James, Niels Kristian Bech Jensen, Achim Kalwa, Tim Kaulmann, Victor Khimenko, Russell King, Donald E. Knuth, Tomasz Kowaltowski, Jochen Kuepper, Krzysztof Kwapien, Randy Latimer, Olivier Lecarme, Wren Lee, Martin Liddle, Kennith Linder, Stephen Lindholm, Orlando Llanes, Miguel Lobo, Benedict Lofstedt, Maurice Lombardi, Dmitry S. Luhtionov, Jesper Lund, Martin Maechler, Michael Meeks, Clyde Meli, Axel Mellinger, Jeff Miller, John Miller, Russell Minnich, Jason Moore, Scott A. Moore, Andreas Neumann, Klaus Friis Ostergaard, Alexandre Oliva, Ole Osterby, Matija Papec, Miguel A. Alonso Pardo, Robert R. Payne, Opie Pecheux, Ronald Perrella, Pierre Phaneuf, Nuno Pinhao, Larry Poorman, John L. Ries, Phil Robertson, Jim Roland, Carl-Johan Schenstrom, Thomas D. Schneider, George Shapovalov, Richard Sharman, Pat Sharp, Arcadio Alivio Sincero, Tomas Srb, David Starner, Mark Taylor, Robin S. Thompson, Ian Thurlbeck, Ivan Torshin, Bernhard Tschirren, Kresimir Veselic, Alejandro Villarroel, Peter Weber, Christian Wendt, Gareth Wilson, Marc van Woerkom, Salaam Yitbarek, Eli Zaretskii, Mariusz Zynel, the BIP at the University of Birmingham, UK, the Institut fuer Festkoerperforschung (IFF) at the Forschungszentrum Juelich, Germany,

    and everybody we might have forgotten to mention here. Thanks to all of you!

    GNU Pascal is based on GNU CC by Richard Stallman. Several people have contributed to GNU CC:

    - The idea of using RTL and some of the optimization ideas came from the program PO written at the University of Arizona by Jack Davidson and Christopher Fraser. See "Register Allocation and Exhaustive Peephole Optimization", Software Practice and Experience 14 (9), Sept. 1984, 857-866.
    - Paul Rubin wrote most of the preprocessor.
    - Leonard Tower wrote parts of the parser, RTL generator, and RTL definitions, and of the Vax machine description.
    - Ted Lemon wrote parts of the RTL reader and printer.
    - Jim Wilson implemented loop strength reduction and some other loop optimizations.
    - Nobuyuki Hikichi of Software Research Associates, Tokyo, contributed the support for the Sony NEWS machine.
    - Charles LaBrec contributed the support for the Integrated Solutions 68020 system.
    - Michael Tiemann of Cygnus Support wrote the support for inline functions and instruction scheduling. Also the descriptions of the National Semiconductor 32000 series cpu, the SPARC cpu and part of the Motorola 88000 cpu.
    - Jan Stein of the Chalmers Computer Society provided support for Genix, as well as part of the 32000 machine description.
    - Randy Smith finished the Sun FPA support.
    - Robert Brown implemented the support for Encore 32000 systems.
    - David Kashtan of SRI adapted GNU CC to VMS.
    - Alex Crain provided changes for the 3b1.
    - Greg Satz and Chris Hanson assisted in making GNU CC work on HP-UX for the 9000 series 300.
    - William Schelter did most of the work on the Intel 80386 support.
    - Christopher Smith did the port for Convex machines.
    - Paul Petersen wrote the machine description for the Alliant FX/8.
    - Dario Dariol contributed the four varieties of sample programs that print a copy of their source.
    - Alain Lichnewsky ported GNU CC to the Mips cpu.
    - Devon Bowen, Dale Wiles and Kevin Zachmann ported GNU CC to the Tahoe.
    - Jonathan Stone wrote the machine description for the Pyramid computer.
    - Gary Miller ported GNU CC to Charles River Data Systems machines.
    - Richard Kenner of the New York University Ultracomputer Research Laboratory wrote the machine descriptions for the AMD 29000, the DEC Alpha, the IBM RT PC, and the IBM RS/6000 as well as the support for instruction attributes. He also made changes to better support RISC processors including changes to common subexpression elimination, strength reduction, function calling sequence handling, and condition code support, in addition to generalizing the code for frame pointer elimination.
    - Richard Kenner and Michael Tiemann jointly developed reorg.c, the delay slot scheduler.
    - Mike Meissner and Tom Wood of Data General finished the port to the Motorola 88000.
    - Masanobu Yuhara of Fujitsu Laboratories implemented the machine description for the Tron architecture (specifically, the Gmicro).
    - James van Artsdalen wrote the code that makes efficient use of the Intel 80387 register stack.
    - Mike Meissner at the Open Software Foundation finished the port to the MIPS cpu, including adding ECOFF debug support, and worked on the Intel port for the Intel 80386 cpu.
    - Ron Guilmette implemented the `protoize` and `unprotoize` tools, the support for Dwarf symbolic debugging information, and much of the support for System V Release 4. He has also worked heavily on the Intel 386 and 860 support.
    - Torbjorn Granlund implemented multiply- and divide-by-constant optimization, improved long long support, and improved leaf function register allocation.
    - Mike Stump implemented the support for Elxsi 64 bit CPU.
    - John Wehle added the machine description for the Western Electric 32000 processor used in several 3b series machines (no relation to the National Semiconductor 32000 processor).

    # The GPC Source Reference

    > "The Source will be with you. Always."

    This chapter describes internals of GPC. It is meant for GPC developers and those who want to become devlopers, or just want to know more about how the compiler works. It does not contain information needed when using GPC to compile programs.

    This section tells you how to look up additional information about the GNU Pascal compiler from its source code. It replaces chapters like "syntax diagrams" you probably know from the documentation of other compilers.

    Proprietary compilers often come with a lot of technical information about the internals of the compiler. This is necessary because their vendors want to avoid to distribute the source of the compiler -- which is always the most definitive source of this technical information.

    With GNU compilers, on the other hand, you are free to get the source code, look how your compiler works internally, customize it for your own needs, and to re-distribute it in modified or unmodified form. You may even take money for this redistribution. (For details, see the GNU General Public License, section GNU GENERAL PUBLIC LICENSE.)

    The following subsections are your guide to the GNU Pascal source code. If you have further questions, be welcome to ask them at the GNU Pascal mailing list (see section Where to get support for GNU Pascal; how to report bugs).

    All file paths mentioned in this chapter are relative to the GNU Pascal source directory, usually a subdirectory ``p'` of the GCC source.

    (Under construction.)

    For more information, see chapters "Portability" through "Fragments" in section `Top' in "Using and Porting GNU CC".

    ## GPC's Lexical Analyzer

    The source file ``gpc-lex.c'` contains the so-called lexical analyzer of the GNU Pascal compiler. (For those of you who know ``flex'`: This file was not created using ``flex'` but is maintained manually.) This very-first stage of the compiler is responsible for reading what you have written and dividing it into tokens, the "atoms" of each computer language. The source ``gpc-lex.c'` essentially contains one large function, ``yylex()'`.

    Here is, for example, where the real number ``3.14'` and the subrange ``3..14'` are distinguished, and where Borland-style character constants like ``#13'` and ``^M'` are recognized. This is not always a trivial task, for example look at the following type declaration:

          Type
            X = ^Y;
            Y = packed array [ ^A..^B ] of Char;
            Z = ^A..^Z;

    If you wish to know how GPC distinguishes the pointer forward declaration ``^Y'` and the subrange ``^A..^Z'`, see ``gpc-lex.c'`, function ``yylex()'`, ``case '^':'` in the big ``switch'` statement.

    There are several situation where GPC's lexical analzyer becomes context-sensitive. One is described above, another example is the token ``protected'`, a reserved word in ISO-10206 Extended Pascal, but an ordinary identifier in ISO-7185 Standard Pascal. It appears in parameter lists

          Procedure foo ( protected bar: Integer );

    and says that the parameter ``bar'` must not be changed inside the body of the procedure.

    OTOH, if you write a valid ISO-7185 Standard Pascal program, you can declare a parameter ``protected'`:

          Procedure foo ( protected, bar: Integer );

    Here both standards contradict each other. GPC solves this problem by checking explicitly for "protected" in the lexical analyzer: If a comma or a colon follows, this is an ordinary identifier, otherwise it's a reserved word. Having this, GPC even understands

          Procedure foo ( protected protected: Integer );

    without losing the special meaning of ``protected'` as a reserved word.

    The responsible code is in ``gpc-lex.c'`---look out for ``PROTECTED'`.

    If you ever encouter a bug with the lexical analyzer--now you know where to hunt for it.

    ## Language Definition: GPC's Parser

    The file ``parse.y'` contains the "bison" source code of GNU Pascal's parser. This stage of the compilation analyzes and checks the syntax of your Pascal program, and it generates an intermediate, language-independent code which is then passed to the GNU back-end.

    The bison language essentially is a machine-readable form of the Backus-Naur Form, the symbolic notation of grammars of computer languages. "Syntax diagrams" are a graphical variant of the Backus-Naur Form.

    For details about the "bison" language, see section `' in the Bison manual. A short overview how to pick up some information you might need for programming follows.

    Suppose you have forgotten how a variable is declared in Pascal. After some searching in ``parse.y'` you have found the following:

          /* variable declaration part */

          variable_declaration_part:
              LEX_VAR variable_declaration_list semi
            | LEX_VAR semi
                { error ("missing variable declaration"); }
            ;

          variable_declaration_list:
              variable_declaration
            | variable_declaration_list semi variable_declaration
                { yyerrok; }
            | error
            | variable_declaration_list error variable_declaration
                {
                  error ("missing semicolon");
                  yyerrok;
                }
            | variable_declaration_list semi error
            ;

    Translated into English, this means: "The variable declaration part consists of the reserved word (lexical token) ``var'` followed by a `variable declaration list' and a semicolon. A semicolon immediately following ``var'` is an error. A `variable declaration list' in turn consists of one or more `variable declarations', separated by semicolons." (The latter explanation requires that you understand the recursive nature of the definition of ``variable_declaration_list'`.)

    Now we can go on and search for ``variable_declaration'`.

          variable_declaration:
              id_list
                {
                  [...]
                }
              enable_caret ':' optional_qualifier_list type_denoter
                {
                  [...]
                }
              absolute_or_value_specification
                {
                  [...]
                }
            ;

    (The ``[...]'` are placeholders for some C statements which aren't important for understanding GPC's grammar.)

    From this you can look up that a variable declaration in GNU Pascal consists of an "id list", followed by "enable_caret" (whatever that means), a colon, an "optional qualifier list", a "type denoter", and an "absolute or value specification". Some of these parts are easy to understand, the others you can look up from ``parse.y'`. Remember that the reserved word ``var'` preceeds all this, and a semicolon follows all this.

    Now you know the procedure how to get the exact grammar of the GNU Pascal language from the source.

    The C statements, not shown above, are in some sense the most important part of the bison source, because they are responsible for the generation of the intermediate code of the GNU Pascal front-end, the so-called tree nodes. For instance, the C code in "type denoter" juggles a while with variables of the type ``tree'`, and finally returns (assigns to ``$$'`) a so-called tree list which contains the information about the type. The "variable declaration" gets this tree list (as the argument ``$6'`) and passes the type information to the C function ``declare_vars()'` (declared in ``util.c'`). This function ``declare_vars()'` does the real work of compiling a variable declaration.

    This, the parser, is the place where it becomes Pascal.

    ## Tree Nodes

    If you want really to understand how the GNU Pascal language front-end works internally and perhaps want to improve the compiler, it is important that you understand GPC's internal data structures.

    The data structure used by the language front-end to hold all information about your Pascal program are the so-called "tree nodes". (Well, it needn't be Pascal source--tree nodes are language independent.) The tree nodes are kind of objects, connected to each other via pointers. Since the GNU compiler is written in C and was created at a time where nobody really thought about object-orientated programming languages yet, a lot of effort has been taken to create these "objects" in C.

    Here is an extract from the "object hierarchy". Omissions are marked with "..."; nodes in parentheses are "abstract": They are never instantiated and aren't really defined. They only appear here to clarify the structure of the tree node hierarchy. The complete list is in ``../tree.def'`; additional information can be found in ``../tree.h'`.

          (tree_node)
          |
          |--- error_mark  (* enables GPC to continue after first error *)
          |
          |--- (identifier)
          |    |
          |    |--- identifier_node
          |    |
          |    \--- op_identifier
          |
          |--- tree_list  (* general-purpose "container object" *)
          |
          |--- tree_vec
          |
          |--- block
          |
          |--- (type)  (* information about types *)
          |    |
          |    |--- void_type
          |    |
          |    |--- integer_type
          |   ...
          |    |
          |    |--- record_type
          |    |
          |    |--- function_type
          |    |
          |    \--- lang_type  (* for language-specific extensions *)
          |
          |--- integer_cst  (* an integer constant *)
          |
          |--- real_cst
          |
          |--- string_cst
          |
          |--- complex_cst
          |
          |--- (declaration)
          |    |
          |    |--- function_decl
          |   ...
          |    |
          |    |--- type_decl
          |    |
          |    \--- var_decl
          |
          |--- (reference)
          |    |
          |    |--- component_ref
          |   ...
          |    |
          |    \--- array_ref
          |
          |--- constructor
          |
          \--- (expression)
               |
               |--- modify_expr  (* assignment *)
               |
               |--- plus_expr  (* addition *)
              ...
               |
               |--- call_expr  (* procedure/function call *)
               |
               |--- goto_expr
               |
               \--- loop_expr  (* for all loops *)

    Most of these tree nodes--struct variables in fact--contain pointers to other tree nodes. A ``tree_list'` for instance has a ``tree_value'` and a ``tree_purpose'` slot which can contain arbitrary data; a third pointer ``tree_chain'` points to the next ``tree_list'` node and thus allows us to create linked lists of tree nodes.

    One example: When GPC reads the list of identifiers in a variable declaration

          Var
            foo, bar, baz: Integer;

    the parser creates a chain of ``tree_list'`s whose ``tree_value'`s hold ``identifier_node'`s for the identifiers ``foo'`, ``bar'`, and ``baz'`. The function ``declare_vars()'` (declared in ``util.c'`) gets this tree list as a parameter, does some magic, and finally passes a chain of ``var_decl'` nodes to the back-end.

    The ``var_decl'` nodes in turn have a pointer ``tree_type'` which holds a ``_type'` node--an ``integer_type'` node in the example above. Having this, GPC can do type-checking when a variable is referenced.

    For another example, let's look at the following statement:

          baz:= foo + bar;

    Here the parser creates a ``modify_expr'` tree node. This node has two pointers, ``tree_operand[0]'` which holds a representation of ``baz'`, a ``var_decl'` node, and ``tree_operand[1]'` which holds a representation of the sum ``foo + bar'`. The sum in turn is represented as a ``plus_expr'` tree node whose ``tree_operand[0]'` is the ``var_decl'` node ``foo'`, and whose ``tree_operand[1]'` is the ``var_decl'` node ``bar'`. Passing this (the ``modify_expr'` node) to the back-end results in assembler code for the assignment.

    If you want to have a closer look at these tree nodes, write a line ``(*$debug-tree="Foobar"*)'` into your program with ``FooBar'` being some identifier in your program. (Note the capitalization of the first character in the internal representation.) This tells GPC to output the ``identifier_local_value'` tree node--the meaning of this identifier--to the standard error device in human-readable form.

    While hacking and debugging GPC, you will also wish to have a look at these tree nodes in other cases. Use the ``debug_tree()'` function to do so. (In fact ``(*$debug-tree="Foobar"*)'` does nothing else than to ``debug_tree()'` the ``identifier_local_value'` of the ``Foobar'` identifier node.)

    ## Parameter Passing

    GPC supports a lot of funny things in parameter lists: ``protected'` and ``const'` parameters, strings with specified or unspecified length, conformant arrays, objects as ``Var'` parameters, etc. All this requires sophisticated type-checking; the responsible function is ``convert_arguments()'` in the source file ``gpc-typeck.c'`. Every detail can be looked up from there.

    Some short notes about the most interesting cases follow.

    Conformant arrays:
      First, the array bounds are passed (an even number of parameters of an ordinal type), then the address of the array itself.
    Procedural parameters:
      These need special care because a function passed as a parameter can be confused with a call to the function whose result is then passed as a parameter. See also the functions ``maybe_call_function()'` and ``probably_call_function()'` in ``util.c'`.
    Chars:
      According to ISO-10206 Extended Pascal, formal char parameters accept string values. GPC does the necessary conversion implicitly. The empty string produces a space.
    Strings and schemata:
      Value parameter strings and schemata of known size are really passed by value. Value parameter strings and schemata of unknown size are passed by reference, and GPC creates temporary variable to hold a copy of the string.
    ``Const'` parameters:
      If a constant value is passed to a ``Const'` parameter, GPC assigns the value to a temporary variable whose address is passed.
    Typeless parameters:
      These are denoted by ``Var foo'` or ``Var foo: Void'` and are compatible to C's ``void *'` parameters; the size of such entities is not passed. Maybe we will change this in the future and pass the size for ``Var foo'` parameters whereas ``Var foo: Void'` will remain compatible to C.
    ``CString'` parameters:
      GPC implicitly converts any string value such that the address of the actual string data is passed. However, GPC does not implicitly append a ``chr ( 0 )'` terminator, except for string constants.

    ## GPI files--GNU Pascal Interfaces

    This section documents the mechanism how GPC transfers information from the exporting Modules and Units to the Program, Module or Unit which imports (uses) the information.

    A GPI file contains a precompiled GNU Pascal Interface. "Precompiled" means in this context that the Interface already has been parsed (i.e. the front-end has done its work), but that no assembler output has been produced yet.

    The GPI file format is an implementation-dependent (but not too implementation-dependent ;-) file format for storing GNU Pascal Interfaces to be exported--Extended Pascal and PXSC module interfaces as well as interface parts of Borland Pascal Units compiled with GNU Pascal.

    To see what information is stored in or loaded from a GPI file, run GPC with an additional command-line option ``--debug-gpi'`. Then, GPC will write a human-readable version of what is being stored/loaded to the standard error device. (See also: section Tree Nodes.)

    While parsing an Interface, GPC stores the names of exported objects in tree lists--in ``gpc-parse.y'`, the bison (yacc) source of GPC's parser, search for ``handle_autoexport'`. At the end of the Interface, everything is stored in one or more GPI files. This is called in ``gpc-parse.y'`---search for ``create_gpi_files'`. (See also: section Language Definition: GPC's Parser, for an introduction to ``gpc-parse.y'`)

    Everything else is done in gpc-module.c. Here you can find the source of ``create_gpi_files()'` which documents the file format: First, a header of 33 bytes containing the string ``GNU Pascal Module/Unit Interface\n'` is stored, then the name of the primary source file of the module as a string, then the name of the exported interface as a tree node (see below), after that all exported names in the order as they were stored while parsing.

    The names and the objects (i.e. constants, data types, variables and functions) they refer to are internally represented as so-called tree nodes as defined in the files ``../tree.h'` and ``../tree.def'` from the GNU compiler back-end. (See also: section Tree Nodes.) The names are stored as ``identifier_node'`s, their meanings as ``identifier_global_value'`s of these nodes. The main problem when storing tree nodes is that they form a complicated tree in memory with a lot of circular references making it hard to decide which information must be stored and which mustn't.

    The functions ``load_tree()'` and ``store_tree'` load/store a tree node with the contents of all its contained pointers in a GPI file.

    Each tree node has a ``tree_code'` indicating what kind of information it contains. Each different tree node must be stored in a different way. See the source of ``load_tree()'` and ``store_tree()'` for details.

    Most tree nodes contain pointers to other tree nodes; therefore ``load_tree()'` and ``store_tree()'` are recursive functions. The ``--debug-gpi'` debugging informations contains the recursion level in parantheses, e.g. ``loaded (2):'` means that the loaded information was requested by a pointer contained in a tree node requested by a pointer contained in a tree node representing an exported symbol.

    Since this recursion can be circular (think of a record containing a pointer to a record of the same type), we must resolve references to tree nodes which already have been loaded. For this reason, all nodes are recorded in a hash buffer--see ``gpi-hash.c'`.

    There are some special tree_nodes (e.g. ``integer_type_node'` or ``NULL_TREE'`) which are used very often. They have been assigned (normally invalid) unique ``tree_code'`s, so they can be stored in a single byte.

    That's it. Now you should be able to "read" GPI files using GPC's ``--debug-gpi'` option. If you encounter a case where the loaded information differs too much from the stored information, you have found a bug--congratulations! What "too much" means, depends on the object being stored in or loaded from the GPI file. Remind that the order things are loaded from a GPI file is the reversed order things are stored when considering different recursion levels, but the same order when considering ths same recursion level.

    ## GPC's AutoMake Mechanism--How it Works

    When a Program/Module/Unit imports (uses) an Interface, GPC searches for the GPI file (see section GPI files--GNU Pascal Interfaces) derived from the name of the Interface.

    Case 1: A GPI file was found.

    Each GPI file contains the name of the primary source file (normally a ``.pas'` or ``.p'` file) of the Module/Unit, and the names of all interfaces imported. GPC reads this information and invokes itself with a command like

          gpc foo.pas -M -o foo.d

    This means: preprocess the file, and write down the name of the object file and those of all its source files in ``foo.d'`. GPC reads ``foo.d'` and looks if the object file exists and if the source was modified since the creation of the object file and the gpi file. If so, GPC calls itself again to compile the primary source file. When everything is done, the ``.d'` file is removed. If there was no need to recompile, all interfaces imported by the Module/Unit are processed in the same way as this one.

    Case 2: No GPI file was found.

    In this case, GPC derives the name of the source file from that of the Interface by trying first ``interface.p'`, then ``interface.pas'`. This will almost always work with Borland Pascal Units, almost never with Extended Pascal Modules. With Extended Pascal, compile the Module once manually in order to produce a GPI file.

    All this is done by the function ``gpi_open()'` which uses some auxiliary functions such as ``module_must_be_recompiled()'` and ``compile_module()'`.

    Each time an object file is compiled or recognized as being up-to-date, its name is stored in a temporary file with the same base name as all the other temporary files used by GPC but the extension ``.gpc'`. When the top-level ``gpc'` is invoked (which calls ``gpc1'` later on), it passes the name of this temporary file as an additional command line parameter to ``gpc1'`. After compilation has been completed, the top-level ``gpc'` reads the temporary file and adds the new object files to the arguments passed to the linker.

    The additional command ``--amtmpfile'` (not to be specified by the user!) is passed to child GPC processes, so all compiles use the same temporary file.

    The source for this is merely in ``gpc-module.c'`, but there are also some hacks in ``gpc.c'`, additional command line options in ``lang-options.h'` and ``gpc-decl.c'`, and ``gpc-defs.h'` contains declarations for the functions and global variables.

    ## Files that make up GPC; Integrating GNU Pascal in GCC

    NOTE: This is not up to date.

    1. The GNU back end (gbe). Used to convert RTL into asm. Supposed to be language independant. Files are in the GCC source directory.

           toplev.c
           version.c
           tree.c
           print-tree.c
           stor-layout.c
           fold-const.c
           function.c
           stmt.c
           expr.c
           calls.c
           expmed.c
           explow.c
           optabs.c
           varasm.c
           rtl.c
           print-rtl.c
           rtlanal.c
           emit-rtl.c
           real.c
           dbxout.c
           sdbout.c
           dwarfout.c
           xcoffout.c
           integrate.c
           jump.c
           cse.c
           loop.c
           unroll.c
           flow.c
           stupid.c
           combine.c
           regclass.c
           local-alloc.c
           global.c
           reload.c
           reload1.c
           caller-save.c
           insn-peep.c
           reorg.c
           sched.c
           final.c
           recog.c
           reg-stack.c
           insn-opinit.c
           insn-recog.c
           insn-extract.c
           insn-output.c
           insn-emit.c
           insn-attrtab.c
           getpwd.c
           convert.c
           bc-emit.c
           bc-optab.c

       Unfortunately, some of them are not completely language independent and need patching for GPC. This patch is in the ``p/diffs'` subdirectory. It affects these files:

           convert.c
           dbxout.c
           expr.c
           fold-const.c
           function.c
           optabs.c
           stor-layout.c
           toplev.c

    2. Pascal language implementation files hacked from GCC source. In the ideal world, we would optimize them so much for Pascal that their GCC roots would no longer be recognizable. ;-) These files are in the ``p/'` subdirectory and are the following:

           gpcpp.c       (cccp.c)
           gpc-common.c  (c-common.c)
           gpc-convert.c (c-convert.c)
           gpc-decl.c    (c-decl.c)
           lang.c        (c-lang.c)
           gpc-lex.c     (c-lex.c)
           gpc-typeck.c  (c-typeck.c)

       Some are even reused unmodified and are still in the GCC source directory:

           c-aux-info.c
           c-iterate.c
           c-pragma.c

    3. GPC sources written from scratch. They are in the ``p/'` subdirectory.

           gpc-defs.h
           hash.h
           module.c
           parse.y
           util.c
           version.c
           gpc.c
           setop.c
           gpi-hash.c
           gpi-hash.h
           circle-buf.c

    # GNU GENERAL PUBLIC LICENSE

    Version 2, June 1991

        Copyright (C) 1989, 1991 Free Software Foundation, Inc.
        59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

        Everyone is permitted to copy and distribute verbatim copies
        of this license document, but changing it is not allowed.

    ## Preamble

    The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

    When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

    To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

    For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

    We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

    Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

    Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

    The precise terms and conditions for copying, distribution and modification follow.

    ## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

    1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
    2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
    3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
       1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
       2. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
       3. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
       These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
    4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
       1. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
       2. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
       3. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
       The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
    5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
    6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
    7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
    8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
    9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
    10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
    11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

        NO WARRANTY

    12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
    13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

    ## END OF TERMS AND CONDITIONS

    ## How to Apply These Terms to Your New Programs

    If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

    To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

        one line to give the program's name and a brief idea of what it does.
        Copyright (C) 19yy  name of author

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

    Also add information on how to contact you by electronic and paper mail.

    If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

        Gnomovision version 69, Copyright (C) 19yy name of author
        Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
        type `show w'.
        This is free software, and you are welcome to redistribute it
        under certain conditions; type `show c' for details.

    The hypothetical commands ``show w'` and ``show c'` should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than ``show w'` and ``show c'`; they could even be mouse-clicks or menu items--whatever suits your program.

    You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

        Yoyodyne, Inc., hereby disclaims all copyright interest in the program
        `Gnomovision' (which makes passes at compilers) written by James Hacker.

        signature of Ty Coon, 1 April 1989
        Ty Coon, President of Vice

    This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

    # The GNU Manifesto

    > The GNU Manifesto which appears below was written by Richard Stallman at the beginning of the GNU project, to ask for participation and support. For the first few years, it was updated in minor ways to account for developments, but now it seems best to leave it unchanged as most people have seen it.

    > Since that time, we have learned about certain common misunderstandings that different wording could help avoid. Footnotes added in 1993 help clarify these points.

    > For up-to-date information about the available GNU software, please see the latest issue of the GNU's Bulletin. The list is much too long to include here.

    ## What's GNU? Gnu's Not Unix!

    GNU, which stands for Gnu's Not Unix, is the name for the complete Unix-compatible software system which I am writing so that I can give it away free to everyone who can use it.(1) Several other volunteers are helping me. Contributions of time, money, programs and equipment are greatly needed.

    So far we have an Emacs text editor with Lisp for writing editor commands, a source level debugger, a yacc-compatible parser generator, a linker, and around 35 utilities. A shell (command interpreter) is nearly completed. A new portable optimizing C compiler has compiled itself and may be released this year. An initial kernel exists but many more features are needed to emulate Unix. When the kernel and compiler are finished, it will be possible to distribute a GNU system suitable for program development. We will use TeX as our text formatter, but an nroff is being worked on. We will use the free, portable X window system as well. After this we will add a portable Common Lisp, an Empire game, a spreadsheet, and hundreds of other things, plus on-line documentation. We hope to supply, eventually, everything useful that normally comes with a Unix system, and more.

    GNU will be able to run Unix programs, but will not be identical to Unix. We will make all improvements that are convenient, based on our experience with other operating systems. In particular, we plan to have longer file names, file version numbers, a crashproof file system, file name completion perhaps, terminal-independent display support, and perhaps eventually a Lisp-based window system through which several Lisp programs and ordinary Unix programs can share a screen. Both C and Lisp will be available as system programming languages. We will try to support UUCP, MIT Chaosnet, and Internet protocols for communication.

    GNU is aimed initially at machines in the 68000/16000 class with virtual memory, because they are the easiest machines to make it run on. The extra effort to make it run on smaller machines will be left to someone who wants to use it on them.

    To avoid horrible confusion, please pronounce the `G' in the word `GNU' when it is the name of this project.

    ## Why I Must Write GNU

    I consider that the golden rule requires that if I like a program I must share it with other people who like it. Software sellers want to divide the users and conquer them, making each user agree not to share with others. I refuse to break solidarity with other users in this way. I cannot in good conscience sign a nondisclosure agreement or a software license agreement. For years I worked within the Artificial Intelligence Lab to resist such tendencies and other inhospitalities, but eventually they had gone too far: I could not remain in an institution where such things are done for me against my will.

    So that I can continue to use computers without dishonor, I have decided to put together a sufficient body of free software so that I will be able to get along without any software that is not free. I have resigned from the AI lab to deny MIT any legal excuse to prevent me from giving GNU away.

    ## Why GNU Will Be Compatible with Unix

    Unix is not my ideal system, but it is not too bad. The essential features of Unix seem to be good ones, and I think I can fill in what Unix lacks without spoiling them. And a system compatible with Unix would be convenient for many other people to adopt.

    ## How GNU Will Be Available

    GNU is not in the public domain. Everyone will be permitted to modify and redistribute GNU, but no distributor will be allowed to restrict its further redistribution. That is to say, proprietary modifications will not be allowed. I want to make sure that all versions of GNU remain free.

    ## Why Many Other Programmers Want to Help

    I have found many other programmers who are excited about GNU and want to help.

    Many programmers are unhappy about the commercialization of system software. It may enable them to make more money, but it requires them to feel in conflict with other programmers in general rather than feel as comrades. The fundamental act of friendship among programmers is the sharing of programs; marketing arrangements now typically used essentially forbid programmers to treat others as friends. The purchaser of software must choose between friendship and obeying the law. Naturally, many decide that friendship is more important. But those who believe in law often do not feel at ease with either choice. They become cynical and think that programming is just a way of making money.

    By working on and using GNU rather than proprietary programs, we can be hospitable to everyone and obey the law. In addition, GNU serves as an example to inspire and a banner to rally others to join us in sharing. This can give us a feeling of harmony which is impossible if we use software that is not free. For about half the programmers I talk to, this is an important happiness that money cannot replace.

    ## How You Can Contribute

    I am asking computer manufacturers for donations of machines and money. I'm asking individuals for donations of programs and work.

    One consequence you can expect if you donate machines is that GNU will run on them at an early date. The machines should be complete, ready to use systems, approved for use in a residential area, and not in need of sophisticated cooling or power.

    I have found very many programmers eager to contribute part-time work for GNU. For most projects, such part-time distributed work would be very hard to coordinate; the independently-written parts would not work together. But for the particular task of replacing Unix, this problem is absent. A complete Unix system contains hundreds of utility programs, each of which is documented separately. Most interface specifications are fixed by Unix compatibility. If each contributor can write a compatible replacement for a single Unix utility, and make it work properly in place of the original on a Unix system, then these utilities will work right when put together. Even allowing for Murphy to create a few unexpected problems, assembling these components will be a feasible task. (The kernel will require closer communication and will be worked on by a small, tight group.)

    If I get donations of money, I may be able to hire a few people full or part time. The salary won't be high by programmers' standards, but I'm looking for people for whom building community spirit is as important as making money. I view this as a way of enabling dedicated people to devote their full energies to working on GNU by sparing them the need to make a living in another way.

    ## Why All Computer Users Will Benefit

    Once GNU is written, everyone will be able to obtain good system software free, just like air.(2)

    This means much more than just saving everyone the price of a Unix license. It means that much wasteful duplication of system programming effort will be avoided. This effort can go instead into advancing the state of the art.

    Complete system sources will be available to everyone. As a result, a user who needs changes in the system will always be free to make them himself, or hire any available programmer or company to make them for him. Users will no longer be at the mercy of one programmer or company which owns the sources and is in sole position to make changes.

    Schools will be able to provide a much more educational environment by encouraging all students to study and improve the system code. Harvard's computer lab used to have the policy that no program could be installed on the system if its sources were not on public display, and upheld it by actually refusing to install certain programs. I was very much inspired by this.

    Finally, the overhead of considering who owns the system software and what one is or is not entitled to do with it will be lifted.

    Arrangements to make people pay for using a program, including licensing of copies, always incur a tremendous cost to society through the cumbersome mechanisms necessary to figure out how much (that is, which programs) a person must pay for. And only a police state can force everyone to obey them. Consider a space station where air must be manufactured at great cost: charging each breather per liter of air may be fair, but wearing the metered gas mask all day and all night is intolerable even if everyone can afford to pay the air bill. And the TV cameras everywhere to see if you ever take the mask off are outrageous. It's better to support the air plant with a head tax and chuck the masks.

    Copying all or parts of a program is as natural to a programmer as breathing, and as productive. It ought to be as free.

    ## Some Easily Rebutted Objections to GNU's Goals

    > "Nobody will use it if it is free, because that means they can't rely on any support."

    > "You have to charge for the program to pay for providing the support."

    If people would rather pay for GNU plus service than get GNU free without service, a company to provide just service to people who have obtained GNU free ought to be profitable.(3)

    We must distinguish between support in the form of real programming work and mere handholding. The former is something one cannot rely on from a software vendor. If your problem is not shared by enough people, the vendor will tell you to get lost.

    If your business needs to be able to rely on support, the only way is to have all the necessary sources and tools. Then you can hire any available person to fix your problem; you are not at the mercy of any individual. With Unix, the price of sources puts this out of consideration for most businesses. With GNU this will be easy. It is still possible for there to be no available competent person, but this problem cannot be blamed on distribution arrangements. GNU does not eliminate all the world's problems, only some of them.

    Meanwhile, the users who know nothing about computers need handholding: doing things for them which they could easily do themselves but don't know how.

    Such services could be provided by companies that sell just hand-holding and repair service. If it is true that users would rather spend money and get a product with service, they will also be willing to buy the service having got the product free. The service companies will compete in quality and price; users will not be tied to any particular one. Meanwhile, those of us who don't need the service should be able to use the program without paying for the service.

    > "You cannot reach many people without advertising, and you must charge for the program to support that."

    > "It's no use advertising a program people can get free."

    There are various forms of free or very cheap publicity that can be used to inform numbers of computer users about something like GNU. But it may be true that one can reach more microcomputer users with advertising. If this is really so, a business which advertises the service of copying and mailing GNU for a fee ought to be successful enough to pay for its advertising and more. This way, only the users who benefit from the advertising pay for it.

    On the other hand, if many people get GNU from their friends, and such companies don't succeed, this will show that advertising was not really necessary to spread GNU. Why is it that free market advocates don't want to let the free market decide this?(4)

    > "My company needs a proprietary operating system to get a competitive edge."

    GNU will remove operating system software from the realm of competition. You will not be able to get an edge in this area, but neither will your competitors be able to get an edge over you. You and they will compete in other areas, while benefiting mutually in this one. If your business is selling an operating system, you will not like GNU, but that's tough on you. If your business is something else, GNU can save you from being pushed into the expensive business of selling operating systems.

    I would like to see GNU development supported by gifts from many manufacturers and users, reducing the cost to each.(5)

    > "Don't programmers deserve a reward for their creativity?"

    If anything deserves a reward, it is social contribution. Creativity can be a social contribution, but only in so far as society is free to use the results. If programmers deserve to be rewarded for creating innovative programs, by the same token they deserve to be punished if they restrict the use of these programs.

    > "Shouldn't a programmer be able to ask for a reward for his creativity?"

    There is nothing wrong with wanting pay for work, or seeking to maximize one's income, as long as one does not use means that are destructive. But the means customary in the field of software today are based on destruction.

    Extracting money from users of a program by restricting their use of it is destructive because the restrictions reduce the amount and the ways that the program can be used. This reduces the amount of wealth that humanity derives from the program. When there is a deliberate choice to restrict, the harmful consequences are deliberate destruction.

    The reason a good citizen does not use such destructive means to become wealthier is that, if everyone did so, we would all become poorer from the mutual destructiveness. This is Kantian ethics; or, the Golden Rule. Since I do not like the consequences that result if everyone hoards information, I am required to consider it wrong for one to do so. Specifically, the desire to be rewarded for one's creativity does not justify depriving the world in general of all or part of that creativity.

    > "Won't programmers starve?"

    I could answer that nobody is forced to be a programmer. Most of us cannot manage to get any money for standing on the street and making faces. But we are not, as a result, condemned to spend our lives standing on the street making faces, and starving. We do something else.

    But that is the wrong answer because it accepts the questioner's implicit assumption: that without ownership of software, programmers cannot possibly be paid a cent. Supposedly it is all or nothing.

    The real reason programmers will not starve is that it will still be possible for them to get paid for programming; just not paid as much as now.

    Restricting copying is not the only basis for business in software. It is the most common basis because it brings in the most money. If it were prohibited, or rejected by the customer, software business would move to other bases of organization which are now used less often. There are always numerous ways to organize any kind of business.

    Probably programming will not be as lucrative on the new basis as it is now. But that is not an argument against the change. It is not considered an injustice that sales clerks make the salaries that they now do. If programmers made the same, that would not be an injustice either. (In practice they would still make considerably more than that.)

    > "Don't people have a right to control how their creativity is used?"

    "Control over the use of one's ideas" really constitutes control over other people's lives; and it is usually used to make their lives more difficult.

    People who have studied the issue of intellectual property rights carefully (such as lawyers) say that there is no intrinsic right to intellectual property. The kinds of supposed intellectual property rights that the government recognizes were created by specific acts of legislation for specific purposes.

    For example, the patent system was established to encourage inventors to disclose the details of their inventions. Its purpose was to help society rather than to help inventors. At the time, the life span of 17 years for a patent was short compared with the rate of advance of the state of the art. Since patents are an issue only among manufacturers, for whom the cost and effort of a license agreement are small compared with setting up production, the patents often do not do much harm. They do not obstruct most individuals who use patented products.

    The idea of copyright did not exist in ancient times, when authors frequently copied other authors at length in works of non-fiction. This practice was useful, and is the only way many authors' works have survived even in part. The copyright system was created expressly for the purpose of encouraging authorship. In the domain for which it was invented--books, which could be copied economically only on a printing press--it did little harm, and did not obstruct most of the individuals who read the books.

    All intellectual property rights are just licenses granted by society because it was thought, rightly or wrongly, that society as a whole would benefit by granting them. But in any particular situation, we have to ask: are we really better off granting such license? What kind of act are we licensing a person to do?

    The case of programs today is very different from that of books a hundred years ago. The fact that the easiest way to copy a program is from one neighbor to another, the fact that a program has both source code and object code which are distinct, and the fact that a program is used rather than read and enjoyed, combine to create a situation in which a person who enforces a copyright is harming society as a whole both materially and spiritually; in which a person should not do so regardless of whether the law enables him to.

    > "Competition makes things get done better."

    The paradigm of competition is a race: by rewarding the winner, we encourage everyone to run faster. When capitalism really works this way, it does a good job; but its defenders are wrong in assuming it always works this way. If the runners forget why the reward is offered and become intent on winning, no matter how, they may find other strategies--such as, attacking other runners. If the runners get into a fist fight, they will all finish late.

    Proprietary and secret software is the moral equivalent of runners in a fist fight. Sad to say, the only referee we've got does not seem to object to fights; he just regulates them ("For every ten yards you run, you can fire one shot"). He really ought to break them up, and penalize runners for even trying to fight.

    > "Won't everyone stop programming without a monetary incentive?"

    Actually, many people will program with absolutely no monetary incentive. Programming has an irresistible fascination for some people, usually the people who are best at it. There is no shortage of professional musicians who keep at it even though they have no hope of making a living that way.

    But really this question, though commonly asked, is not appropriate to the situation. Pay for programmers will not disappear, only become less. So the right question is, will anyone program with a reduced monetary incentive? My experience shows that they will.

    For more than ten years, many of the world's best programmers worked at the Artificial Intelligence Lab for far less money than they could have had anywhere else. They got many kinds of non-monetary rewards: fame and appreciation, for example. And creativity is also fun, a reward in itself.

    Then most of them left when offered a chance to do the same interesting work for a lot of money.

    What the facts show is that people will program for reasons other than riches; but if given a chance to make a lot of money as well, they will come to expect and demand it. Low-paying organizations do poorly in competition with high-paying ones, but they do not have to do badly if the high-paying ones are banned.

    > "We need the programmers desperately. If they demand that we stop helping our neighbors, we have to obey."

    You're never so desperate that you have to obey this sort of demand. Remember: millions for defense, but not a cent for tribute!

    > "Programmers need to make a living somehow."

    In the short run, this is true. However, there are plenty of ways that programmers could make a living without selling the right to use a program. This way is customary now because it brings programmers and businessmen the most money, not because it is the only way to make a living. It is easy to find other ways if you want to find them. Here are a number of examples.

    A manufacturer introducing a new computer will pay for the porting of operating systems onto the new hardware.

    The sale of teaching, hand-holding and maintenance services could also employ programmers.

    People with new ideas could distribute programs as freeware, asking for donations from satisfied users, or selling hand-holding services. I have met people who are already working this way successfully.

    Users with related needs can form users' groups, and pay dues. A group would contract with programming companies to write programs that the group's members would like to use.

    All sorts of development can be funded with a Software Tax:

    > Suppose everyone who buys a computer has to pay x percent of the price as a software tax. The government gives this to an agency like the NSF to spend on software development.

    > But if the computer buyer makes a donation to software development himself, he can take a credit against the tax. He can donate to the project of his own choosing--often, chosen because he hopes to use the results when it is done. He can take a credit for any amount of donation up to the total tax he had to pay.

    > The total tax rate could be decided by a vote of the payers of the tax, weighted according to the amount they will be taxed on.

    > The consequences:

    > - The computer-using community supports software development.
    > - This community decides what level of support is needed.
    > - Users who care which projects their share is spent on can choose this for themselves.

    In the long run, making programs free is a step toward the post-scarcity world, where nobody will have to work very hard just to make a living. People will be free to devote themselves to activities that are fun, such as programming, after spending the necessary ten hours a week on required tasks such as legislation, family counseling, robot repair and asteroid prospecting. There will be no need to be able to make a living from programming.

    We have already greatly reduced the amount of work that the whole society must do for its actual productivity, but only a little of this has translated itself into leisure for workers because much nonproductive activity is required to accompany productive activity. The main causes of this are bureaucracy and isometric struggles against competition. Free software will greatly reduce these drains in the area of software production. We must do this, in order for technical gains in productivity to translate into less work for us.

    # Funding Free Software

    If you want to have more free software a few years from now, it makes sense for you to help encourage people to contribute funds for its development. The most effective approach known is to encourage commercial redistributors to donate.

    Users of free software systems can boost the pace of development by encouraging for-a-fee distributors to donate part of their selling price to free software developers--the Free Software Foundation, and others.

    The way to convince distributors to do this is to demand it and expect it from them. So when you compare distributors, judge them partly by how much they give to free software development. Show distributors they must compete to be the one who gives the most.

    To make this approach work, you must insist on numbers that you can compare, such as, "We will donate ten dollars to the Frobnitz project for each disk sold." Don't be satisfied with a vague promise, such as "A portion of the profits are donated," since it doesn't give a basis for comparison.

    Even a precise fraction "of the profits from this disk" is not very meaningful, since creative accounting and unrelated business decisions can greatly alter what fraction of the sales price counts as profit. If the price you pay is $50, ten percent of the profit is probably less than a dollar; it might be a few cents, or nothing at all.

    Some redistributors do development work themselves. This is useful too; but to keep everyone honest, you need to inquire how much they do, and what kind. Some kinds of development make much more long-term difference than others. For example, maintaining a separate version of a program contributes very little; maintaining the standard version of a program for the whole community contributes much. Easy new ports contribute little, since someone else would surely do them; difficult ports such as adding a new CPU to the GNU C compiler contribute more; major new features or packages contribute the most.

    By establishing the idea that supporting further development is "the proper thing to do" when distributing free software for a fee, we can assure a steady flow of resources into making more free software.

        Copyright (C) 1994 Free Software Foundation, Inc.
        Verbatim copying and redistribution of this section is permitted
        without royalty; alteration is not permitted.

    # Index

    ## *

  - *
  - **

    ## +

  - +, +

    ## -

  - -
  - --amtmpfile
  - --autobuild
  - --autolink
  - --automake
  - --borland-char-constants
  - --borland-pascal
  - --cidefine
  - --csdefine
  - --debug-gpi
  - --debug-source
  - --debug-tree
  - --delphi
  - --delphi-comments
  - --exact-compare-strings
  - --executable-file-name
  - --executable-path
  - --extended-pascal
  - --extended-syntax
  - --field-widths
  - --gnu-pascal
  - --gpc-main, --gpc-main
  - --gpi-destination-path
  - --ignore-function-results
  - --implementation-only
  - --interface-only
  - --io-checking
  - --lines
  - --macros
  - --mixed-comments
  - --nested-comments
  - --no-autobuild
  - --no-autolink
  - --no-automake
  - --no-borland-char-constants
  - --no-default-paths
  - --no-delphi-comments
  - --no-exact-compare-strings
  - --no-executable-path
  - --no-extended-syntax
  - --no-field-widths
  - --no-ignore-function-results
  - --no-io-checking
  - --no-macros
  - --no-mixed-comments
  - --no-nested-comments
  - --no-object-destination-path
  - --no-object-path
  - --no-pedantic
  - --no-short-circuit
  - --no-signed-char
  - --no-stack-checking
  - --no-transparent-file-names
  - --no-truncate-strings
  - --no-typed-address (same as ``{$T-}'`)
  - --no-unit-destination-path
  - --no-unit-path
  - --no-unsigned-char
  - --no-write-capital-exponent
  - --no-write-clip-strings
  - --no-write-real-blank
  - --object-destination-path
  - --object-pascal
  - --object-path
  - --pascal-sc
  - --pedantic
  - --progress-bar
  - --progress-messages
  - --setlimit
  - --short-circuit
  - --signed-char
  - --stack-checking
  - --standard-pascal
  - --standard-pascal-level-0
  - --transparent-file-names
  - --truncate-strings
  - --typed-address (same as ``{$T+}'`)
  - --unit-destination-path
  - --unit-path
  - --unsigned-char
  - --uses
  - --write-capital-exponent
  - --write-clip-strings
  - --write-real-blank
  - -Wfield-name-problem
  - -Wmixed-comments
  - -Wnear-far
  - -Wnested-comments
  - -Wno-field-name-problem
  - -Wno-mixed-comments
  - -Wno-near-far
  - -Wno-nested-comments
  - -Wno-typed-const
  - -Wno-warnings
  - -Wtyped-const
  - -Wwarnings

    ## /

  - /

    ## >

  - ><

    ## a

  - abs
  - absolute, absolute
  - abstract, abstract
  - addr
  - alignment, alignment
  - AlignOf
  - all, all
  - and, and, and
  - and then
  - and_then, and_then
  - AnsiChar
  - append
  - ArcTan
  - arctan
  - arg
  - Arg
  - array, array
  - array, conformant
  - array, open
  - asm, asm
  - asmname, asmname, asmname
  - Assign
  - assigned
  - attribute, attribute
  - AutoMake internals

    ## b

  - Bar
  - bar
  - begin, begin
  - binary distributions, installing
  - Bind, Bind
  - bindable, bindable
  - Binding, Binding
  - BindingType
  - Bison parser generator
  - bits
  - BitSizeOf
  - BlockRead
  - BlockWrite
  - Boolean
  - break
  - bugs
  - Built-in
  - Byte
  - ByteBool
  - ByteCard
  - ByteInt

    ## c

  - C, C, C
  - C language
  - C_Language, C_Language
  - Card, Card
  - Cardinal
  - case, case
  - Char
  - ChDir
  - chr
  - class, class
  - close
  - cmplx
  - Cmplx
  - command line options
  - Comp
  - compiler directives
  - Complex
  - Concat, Concat
  - configuration dependent compilation notes
  - conformant arrays
  - conjugate
  - const, const
  - constants
  - constructor, constructor
  - continue
  - contributors
  - Copy
  - Cos
  - cos
  - cross-compilers
  - CString
  - CString2String
  - CStringCopyString

    ## d

  - Date, Date
  - Dec
  - dec
  - default
  - DefineSize
  - Delete
  - destructor, destructor
  - Dispose, Dispose
  - div, div
  - djgpp
  - do, do
  - DOS, MS-, DOS, MS-
  - Double
  - downto, downto

    ## e

  - else, else
  - empty
  - EMX
  - end, end
  - endianness
  - eof
  - eoln
  - EpsReal
  - eq
  - erase
  - exit
  - Exp
  - exp
  - export, export
  - exports, exports
  - extend
  - Extended
  - extern, extern
  - external, external, external

    ## f

  - False
  - far
  - file, file
  - File Layout
  - FileMode
  - FilePos
  - FileSize
  - FillChar
  - flush
  - foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo, foo
  - for, for
  - forward, forward
  - frac
  - FreeMem, FreeMem
  - front-end, front-end
  - function, function
  - functional type
  - functions as parameters
  - functions, predefined

    ## g

  - ge
  - Get, Get
  - GetMem, GetMem
  - GetTimeStamp, GetTimeStamp
  - GNU Pascal command line options
  - goto, goto
  - GPC and other languages
  - GPC, internals
  - GPC, source
  - GPI files
  - grammar
  - gt

    ## h

  - Halt
  - help
  - high

    ## i

  - if, if
  - Im, Im
  - implementation, implementation
  - import, import
  - in, in
  - Inc
  - inc
  - Index
  - inherited, inherited, inherited
  - inline, inline
  - InOutRes
  - InOutResStr
  - Input
  - Insert
  - installing binary distributions
  - installing GNU Pascal
  - int
  - Integer
  - Integer types
  - integer types, compatibility
  - integer types, main branch
  - integer types, natural
  - integer types, specified size
  - integer types, summary
  - interface, interface
  - intermediate code
  - interrupt, interrupt
  - IOresult
  - is, is

    ## l

  - label, label
  - language definition
  - LastPosition, LastPosition
  - le
  - length
  - lexical analyzer
  - Libraries
  - library, library
  - linking
  - Ln
  - ln
  - LoCase
  - LongCard
  - LongestCard
  - LongestInt
  - LongestReal
  - LongestWord
  - LongInt
  - LongReal
  - LongWord
  - low
  - lt

    ## m

  - magic
  - main program, main program
  - Mark
  - Max
  - max
  - MaxChar
  - MaxInt
  - MaxReal
  - MedCard
  - MedInt
  - MedReal
  - MedWord
  - min
  - Min
  - MinReal
  - MkDir
  - mod, mod
  - module, module
  - Modules, source structure
  - move
  - MoveLeft
  - MoveRight
  - MS-DOS, MS-DOS

    ## n

  - ne
  - near
  - New, New, New
  - NewCString
  - news
  - nil, nil
  - not, not, not
  - Notes for debugging
  - NULL

    ## o

  - object, object
  - Object-orientated programming
  - Objects
  - odd
  - of, of
  - only, only
  - OOP
  - operator, operator
  - Operators
  - operators, built-in
  - operators, user-defined
  - options, GNU Pascal command line
  - or, or, or
  - or else
  - or_else, or_else
  - ord
  - OS/2
  - others
  - otherwise, otherwise
  - Output
  - output file option, output file option

    ## p

  - pack
  - packed, packed
  - page
  - pAnsiChar
  - ParamCount, ParamCount
  - parameter passing
  - parameter, protected
  - ParamStr, ParamStr
  - parser
  - parser generator, Bison
  - pChar
  - Pointer
  - pointer arithmetics
  - pointer types
  - Polar
  - polar
  - pos
  - Position, Position
  - pow, pow, pow
  - Pred
  - pred
  - preprocessor
  - private, private
  - procedural parameters
  - procedural type
  - procedure, procedure
  - procedures, predefined
  - program, program
  - programming in GPC
  - Programs, source structure
  - property, property
  - protected, protected, protected
  - protected, parameter
  - PtrCard
  - PtrInt
  - PtrWord
  - public, public
  - published, published
  - Put, Put

    ## q

  - qualified, qualified

    ## r

  - Re, Re
  - read
  - readln
  - ReadStr
  - Real
  - record, record
  - record, variant
  - Release
  - rename
  - repeat, repeat
  - reset
  - resident, resident
  - restricted, restricted
  - Result
  - return
  - rewrite
  - RmDir
  - round
  - routines, predefined
  - Run Time Library, Run Time Library
  - RunError

    ## s

  - schemata
  - Seek
  - SeekRead, SeekRead
  - SeekUpdate, SeekUpdate
  - SeekWrite, SeekWrite
  - segment, segment
  - Self
  - set, set
  - SetFileTime
  - SetLength
  - SetType
  - shl, shl, shl
  - ShortCard
  - ShortInt
  - ShortReal
  - ShortWord
  - shr, shr, shr
  - Sin
  - sin
  - Single
  - SizeOf
  - SmallInt
  - source structures
  - Sqr
  - sqr
  - Sqrt
  - sqrt
  - StandardError
  - StandardInput
  - StandardOutput
  - static, static
  - StdErr
  - Str
  - String
  - String2CString
  - subrange types
  - SubStr
  - succ
  - Succ
  - support

    ## t

  - Text
  - then, then
  - Time, Time
  - TimeStamp
  - to, to
  - to begin do
  - to end do
  - tree nodes
  - Trim
  - True
  - trunc
  - Truncate
  - type, type
  - type casts
  - type of
  - TypeOf
  - types, initializers
  - types, restricted
  - types, schema

    ## u

  - UnBind
  - Unbind
  - unit, unit
  - Units, source structure
  - unpack
  - until, until
  - UpCase
  - update
  - Update
  - uses, uses

    ## v

  - Val
  - value, value
  - var, var
  - view, view
  - virtual, virtual
  - VMT
  - Void
  - volatile, volatile

    ## w

  - while, while
  - Windows 95
  - Windows NT
  - with, with
  - Word
  - write
  - writeln
  - WriteStr

    ## x

  - xor, xor, xor

    This document was generated on 28 May 2000 using the texi2html translator version 1.51.