This is ../p/doc/info/gpc.info, produced by makeinfo version 4.0 from
gpc.texi.

INFO-DIR-SECTION GNU programming tools
START-INFO-DIR-ENTRY
* GPC: (gpc).                   The GNU Pascal Compiler.
END-INFO-DIR-ENTRY
INFO-DIR-SECTION Individual utilities
START-INFO-DIR-ENTRY
* GPC: (gpc)Invoking GPC.       The GNU Pascal Compiler.
END-INFO-DIR-ENTRY

   This file documents the GNU Pascal Compiler.

   Copyright (C) 1988-2002 Free Software Foundation, Inc.

   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
Project", "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 Project", "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.


File: gpc.info,  Node: Type Casts,  Next: OOP,  Prev: String Slice Access,  Up: Programming

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:

     program TypeCastDemo;
     
     var
       Ch: Char;
       i: Integer;
     
     begin
       i := Integer (Ch)
     end.

   Another, more complicated, example:

     program TypeCst2Demo;
     
     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 }
     
     begin
       Foo1 := CharPtr (Bar);
       Foo2 := CharPtr (Succ (Bar))
     end.

   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
current 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 *Note 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 *Note Endianness::).


     program TrapsOfTypeCastsDemo;
     
     { 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 *Note OOP::), 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: *Note absolute::, *Note Alignment::, *Note Endianness::,
*Note OOP::, *Note Ord::, *Note Chr::, *Note Round::, *Note Trunc::.


File: gpc.info,  Node: OOP,  Next: Compiler Directives,  Prev: Type Casts,  Up: Programming

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
       z := c;
       inherited bar (z)  { or: FooParent.Bar (z) }
     end;

   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)


File: gpc.info,  Node: Compiler Directives,  Next: Library Routines,  Prev: OOP,  Up: Programming

Compiler Directives And The Preprocessor
========================================

   GPC, like UCSD Pascal 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 of these directives are case-insensitive (but
some of them have case-sensitive arguments). Directives are local and
can be changed 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 either without
special options or 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 (*note GPC
Command Line Options::) can be turned into a compiler directive
(exceptions are those options that contain directory names, such as
`--unit-path', because they refer to the installation on a particular
system, and therefore should be set system-wide, rather than in a
source file):

     --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 arithmetic, ...)
     
     --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'
                                    (the name is converted to lower case)
     
     {$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 the preprocessor directives in C style, e.g.
`#include', but this is deprecated because of possible confusion 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.


File: gpc.info,  Node: Library Routines,  Next: Other Languages,  Prev: Compiler Directives,  Up: Programming

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.

* Menu:

* File Routines::
* String Operations::
* Accessing Command Line Arguments::
* Memory Management Routines::
* Operations for Integer and Ordinal Types::
* Complex Number Operations::
* Set Operations::
* Date And Time Routines::


File: gpc.info,  Node: File Routines,  Next: String Operations,  Up: Library Routines

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

   * 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
              FileSize := 0
            else
              FileSize := LastPosition (f) + 1;
            Unbind(f);
          end;

     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 *Note 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.


File: gpc.info,  Node: String Operations,  Next: Accessing Command Line Arguments,  Prev: File Routines,  Up: Library Routines

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.


File: gpc.info,  Node: Accessing Command Line Arguments,  Next: Memory Management Routines,  Prev: String Operations,  Up: Library Routines

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 argument #', Counter, ' is `',
                  ParamStr (Counter), '''')
     end.


File: gpc.info,  Node: Memory Management Routines,  Next: Operations for Integer and Ordinal Types,  Prev: Accessing Command Line Arguments,  Up: Library Routines

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 freed later by another `FreeMem' call:

     program PartialFreeMemDemo;
     
     type
       Vector = array [0 .. 1023] of Integer;
       VecPtr = ^Vector;
     
     var
       p, q: VecPtr;
     
     begin
       GetMem (p, 1024 * SizeOf (Integer));
       q := VecPtr (@p^[512]);
     
       { ... }
     
       FreeMem (p, 512 * SizeOf (Integer));
     
       { ... }
     
       FreeMem (q, 512 * SizeOf (Integer));
     end.


File: gpc.info,  Node: Operations for Integer and Ordinal Types,  Next: Complex Number Operations,  Prev: Memory Management Routines,  Up: Library Routines

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.



File: gpc.info,  Node: Complex Number Operations,  Next: Set Operations,  Prev: Operations for Integer and Ordinal Types,  Up: Library Routines

Complex Number Operations
-------------------------

   @@ A lot of details 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 ComplexOperationsDemo (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.


File: gpc.info,  Node: Set Operations,  Next: Date And Time Routines,  Prev: Complex Number Operations,  Up: Library Routines

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)'.


File: gpc.info,  Node: Date And Time Routines,  Prev: Set Operations,  Up: Library Routines

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 *Note TimeStamp::.


File: gpc.info,  Node: Other Languages,  Next: Notes for Debugging,  Prev: Library Routines,  Up: Programming

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.

* Menu:

* Importing Libraries from Other Languages::
* Exporting GPC Libraries to Other Languages::


File: gpc.info,  Node: Importing Libraries from Other Languages,  Next: Exporting GPC Libraries to Other Languages,  Up: Other Languages

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 *Note 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 `{$gpc-main="GPCmain"}'.


File: gpc.info,  Node: Exporting GPC Libraries to Other Languages,  Prev: Importing Libraries from Other Languages,  Up: Other Languages

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 (only) of each
     identifier, so `procedure FooBAR' must be imported as `extern void
     Foobar()' from C.

   * If you want to specify the external name explicitly, use `asmname':

          procedure FooBAR; asmname 'FooBAR';
          { Works like a `forward' declaration }
          
          procedure FooBAR;
          begin
            WriteLn ('FooBAR')
          end;

     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
            VMT = record
              ObjectSize: PtrInt;     { Size of object in bytes }
              NegObjectSize: PtrInt;  { Negated size }
              Methods: array [1 .. n] of procedure;
                { Pointers to the virtual methods. The entries are of the
                   repective procedure or function types. }
            end;

     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.

   * 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 command-line option
     `--gpc-main="GPCmain"' (see the previous subsection).



File: gpc.info,  Node: Notes for Debugging,  Next: Run Time System,  Prev: Other Languages,  Up: Programming

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' (*note asmname::) or a similar
     directive. This is to reduce name clashes with `libc.a' and other
     possible libraries.

   * All visible GPC Run Time System routines have linker names starting
     with `_p_'.

   * The linker name of the main program is `pascal_main_program'.
     This is done because ISO Standard wants to have the program name in
     a separate name space.

