This is ../p/doc/info/gpcs.info, produced by makeinfo version 4.6 from
gpcs.texi.

START-INFO-DIR-ENTRY
* Pascal Coding Standards: (gpcs).      GNU Pascal Coding Standards.
END-INFO-DIR-ENTRY

   GNU Pascal Coding Standards

   Copyright (C) 2001-2004 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 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 this permission notice may be stated in a
translation approved by the copyright holders.


File: gpcs.info,  Node: Top,  Next: Preface,  Up: (dir)

Version
*******

Last updated 2004-01-01.

* Menu:

* Preface::                 About the GNU Pascal Coding Standards
* Legal Issues::            Keeping Free Software Free
* Design Advice::           General Program Design
* Program Behavior::        Program Behavior for All Programs
* Writing Pascal::          Making The Best Use of Pascal
* Documentation::           Documenting Programs
* Managing Releases::       The Release Process
* Glossary::                Glossary of words used throughout this text
* Index::


File: gpcs.info,  Node: Preface,  Next: Legal Issues,  Prev: Top,  Up: Top

About the GNU Pascal Coding Standards
*************************************

The GNU Pascal Coding Standards were designed by a group of GNU Pascal
project volunteers. The aim of this document is extending the GNU
Coding Standards with specific information relating Pascal programming.
As a matter of fact, the information contained in the GNU Coding
Standards mainly pertains to programs written in the C language. On the
other hand, they also explain many of the rules and principles that are
useful for writing portable, robust and reliable programs. Most of
those general topics could be shared with this document with just a few
specific notes, thus cross references are provided which will lead you
to the more extensive information contained in the GNU Coding Standards.

   This release of the GNU Pascal Coding Standards was last updated
2004-01-01.

   The GNU Pascal Coding Standards are available as part of the GPC
distribution - in binary distributions as info files, in source
distributions also as Texinfo files from which further formats such as
HTML, PostScript and PDF can be generated. An HTML version is also
available on GPC's home page, `http://www.gnu-pascal.de'.

   Corrections or suggestions for this document should be sent to the
GNU Pascal Compiler Documentation mailing list, <gpc-doc@gnu.de>. If
you make a suggestion, please include a suggested new wording for it;
our time is limited. A context diff to the "source" Texinfo file would
be very appreciated, if at all possible. If you can't provide the
context diff, please feel free to mail your suggestion anyway.

   These people are the tyrants who are imposing their coding style to
the community so far: Peter Gerwinski `peter(at)gerwinski.de', Frank
Heckenbach `frank(at)pascal.gnu.de', Markus Gerwinski
`markus(at)gerwinski.de', Dominik Freche `dominik.freche(at)gmx.net',
Nicola Girardi `nicola(at)g-n-u.de'.


File: gpcs.info,  Node: Legal Issues,  Next: Design Advice,  Prev: Preface,  Up: Top

Keeping Free Software Free
**************************

This chapter from the GNU Coding Standards discusses how you can make
sure that GNU software avoids legal difficulties, and other related
issues. *Note Intellectual Property: (standards)Intellectual Property.


File: gpcs.info,  Node: Design Advice,  Next: Program Behavior,  Prev: Legal Issues,  Up: Top

General Program Design
**********************

This chapter discusses some of the issues you should take into account
when designing your program.

* Menu:

* Source Language::             Which language to use
* Pascal and C::                Linking to C libraries
* Using Extensions::            Using non-standard features


File: gpcs.info,  Node: Source Language,  Next: Pascal and C,  Up: Design Advice

Which Language to Use
=====================

We support the idea that a variety of programming languages is a good
thing and that different languages are appropriate for different kinds
of tasks. Unlike the GNU Coding Standards (*note Source Language:
(standards)Source Language.), we do not try to persuade you to use C,
Pascal or any single language for everything.

   If you're reading this, you have probably already decided to use
Pascal for some project or are considering using it. This documentation
will suggest you _how_ to format your Pascal code when you do so.


File: gpcs.info,  Node: Pascal and C,  Next: Using Extensions,  Prev: Source Language,  Up: Design Advice

Linking to C libraries
======================

You can link a C library or C object code to your Pascal program or
unit. Please note the description in the GPC manual on how to do so
(*note Other Languages: (gpc)Other Languages.).

   In particular, to access C libraries, we strongly recommend using C
wrappers. This is a portability issue. There might be changes in
different versions of the library which might affect direct `external'
declarations in Pascal code. You should update the wrappers so that
Pascal programs or units work with whatever version of the library you
have.

   There are times when you deal with large packages and you can't
easily retain compatibility to different versions of the packages
themselves.  In this case, you can link directly to the library you're
going to work with, and link a supplementary C file which does nothing
but the version check. This is an example:

     #include <foo.h>
     #if FOO_MAJOR != 1 || FOO_MINOR != 2
     #error The GPC interface for libfoo was only written for libfoo-1.2.
     #error Please get libfoo-1.2 or check for a version of the GPC interface
     #error matching your version of libfoo.
     #endif

   Note the use of `!=' instead of `<' or `>', to perform a very strict
version check. Please keep in mind that this is alright if there is
only one implementation of a library, i.e., you can do this with GTK,
but you can't with libc, libm, curses etc.

   An automatic header translator is planned which would make the C
wrappers superfluous. This is a highly non-trivial job and it's not
sure that it's at all possible, so it will at least take some time to be
available.

   You can assume the GNU C Compiler is used to compile the wrappers
and, in general, any C code snippet you link to your Pascal code. The
reason for such an assumption is that only GNU C Compiler is guaranteed
to have all conventions compatible to GNU Pascal Compiler on every
platform they run on, as they share the same backend. Also, The GNU
Pascal Compiler is always built together with the GNU C Compiler, so
`gcc' can be assumed to be available wherever `gpc' is.


File: gpcs.info,  Node: Using Extensions,  Prev: Pascal and C,  Up: Design Advice

Using Non-standard Features
===========================

Many GNU Pascal facilities are provided which extend the standard Pascal
language. Whether to use these extensions in implementing your program
is a tedious question.

   On the one hand, using the extensions can make a cleaner program. On
the other hand, people will not be able to build the program unless the
GNU Pascal Compiler is available. This might cause the program not to
compile with other compilers.

   In general, it is best to retain compatibility to other compilers or
to the language standards, _if this compatibility is easy to achieve_.
In general, sadly enough, to achieve compatibility you get considerable
drawbacks. For example, you might have to add lots of `{$ifdef}'s to
cater for some non-standard compilers, which make the code harder to
read, write, test and maintain. Moreover, `{$ifdef}'s themselves are
non-standard extensions, so you don't win much this way.

   In the end, we suggest not to bother too much about compatibility.
All of the GNU Pascal Compiler interfaces (compiler and Run Time
System) are open. This means they can be implemented for other
compilers when needed or even the same sources can be used provided the
license is preserved (read more about the GNU General Public License at
`http://www.gnu.org/copyleft/gpl.html'), rather than crippling the code
by not using the extended features. A (limited) example of this
strategy is in the `gpc-bp' unit for Borland Pascal, distributed with
the GNU Pascal Compiler. You might want to look at its interface to see
what exactly it contains. It's easy to extend it by more compatibility
features when needed, though there are features that cannot easily be
emulated (in particular those that have a special syntax).

   Please do not use the following features, especially the ones that
were implemented just for backward compatibility:

   * the `(* *)' comments for old terminals where the `{' and `}'
     characters were not available

   * the `#' directives and the `//' comments, as in C/Delphi. If a
     file must also be used in C, it may use `#' directives, the C
     syntax in conditionals, and `//' comments. An example (as of this
     writing, might change in the future) is `p/rts/constants.h' in the
     GNU Pascal Compiler sources.

   * the misuse of typed constants as variables, which is a misfeature
     of Borland Pascal.

   * `^A' character constants. Use `#1' or `Chr (1)', instead.

   * `CString's (except for C interfaces, of course)

   * complicated Borland Pascal code like the following instead of using
     `WriteStr':

          Str (Foo, s);
          s := 'Hello ' + s;

   * most cases of `FillChar' and `Move', except for low-level code and
     when applied to the characters within a string. Using:

          FillChar (s, SizeOf (s), 0);

     to clear a string, is wrong in GNU Pascal and inefficient even in
     Borland Pascal, since the following could be used:

          s := '';

     This would only clear the length field of the string `s'.

   * most cases of `GetMem' and `FreeMem' - usually they are a
     work-around for missing schemata in other compilers.

   * many cases of untyped parameters

   * most hand-made file name related routines. (When written in Borland
     Pascal, they're usually only applicable to DOS, while the routines
     in the `GPC' unit provide portable alternatives for most stuff.)

   * assembler code, except in very small areas for special
     optimization, surrounded by a specific `{$ifdef}' (for example,
     for the processor type). But then, provide an equivalent plain
     Pascal version in the `{$else}' part - and test it!

   * anything that requires the `System' unit

   * assumption of type-sizes

   * assumption of endianness (some systems have higher and lower valued
     bytes in a different order than other systems; please see the
     glossary *Note Glossary::, for an explanation)

   * identifiers starting or ending with underscores or having several
     adjacent underscores

   * units only written for Borland Pascal compatibility. (*note GPC
     Units: (GPC)GPC Units.) Note, `CRT' and `Printer' are not only for
     Borland Pascal compatibility, but also for general use.


   The GNU Coding Standards have nice statements on this topic.  *Note
Using Extensions: (standards)Using Extensions.


File: gpcs.info,  Node: Program Behavior,  Next: Writing Pascal,  Prev: Design Advice,  Up: Top

Program Behavior for All Programs
*********************************

This chapter from the GNU Coding Standards describes conventions for
writing robust software. It also describes general standards for error
messages, the command line interface, and how libraries should behave.
We encourage you to read that part of the GNU Coding Standards.  *Note
Program Behavior: (standards)Program Behavior.

   Here are special notes for Pascal programming, anyway.

   The choice between signal functions, discussed in the GNU Coding
Standards, is done in the Run Time System so you needn't care about it.

   Another discrepancy with the GNU Coding Standards is the default
behavior for error checks that detect "impossible" conditions. We don't
suggest just aborting. This implies that every user can be a
programmer, but we don't believe this is realistic. Our advice is to
print a reasonable error message so that users can report bug
descriptions to programmers who didn't notice the bug themselves or
could not reproduce it.

   Also, the GNU Coding Standards suggest checking every system call
for an error return. That applies to C. In Pascal, error checking is
often automatic, thus you needn't bother with error checking. Many I/O
routines don't return a value (for example, `Reset'), but those that do
should usually be checked.

   Of course you can disable automatic error checks and see to them for
yourself. In fact, some errors might cause the program to automatically
abort with an error message. Instead, especially in units or modules,
you might want to report errors and give the user a chance to intervene
and fix things up. To do so, you must use the `{$I-}' compiler
directive, and check the value of `IOResult' (*note IOResult:
(gpc)IOResult.) or the global error variables such as `InOutRes' (*note
InOutRes: (gpc)InOutRes.). Note that I/O routines return immediately if
`InOutRes' is set, so it's not necessary to check it after each
operation, so the following is possible:

     {$local I-}
     Rewrite (f, 'bla');
     WriteLn (f, 'foo');
     WriteLn (f, 'bar');
     WriteLn (f, 'baz');
     Close (f);
     {$endlocal}
     if InOutRes <> 0 then
       begin
         WriteLn (StdErr, GetIOErrorMessage);
         ...
       end;

   However in your code you might want to also check `Rewrite' and
other opening calls, which are the most likely to fail, and you will
avoid unnecessary further calls.

   There is a set of routines in the GPC unit for naming temporary
files, configuration files and many other file name related stuff. The
advantages of using these are that they work for different kinds of
systems (for example Unix and DOS), and that future problems can be
corrected in one place in the Run Time System rather than in several
different programs or units.

   As far as libraries are concerned, we suggest that you don't put each
routine in a separate file. Hopefully someday the GNU Pascal Compiler
will do this automatically on the linker level. At the moment, we
believe that the convenience to the programmer is much more important
than binary size. We also recommend not using a name prefix, as name
conflicts will be resolved by qualified identifiers
(`UnitName.RoutineName') in the future.  Until then, please use
temporary work-arounds when conflicts arise.


File: gpcs.info,  Node: Writing Pascal,  Next: Documentation,  Prev: Program Behavior,  Up: Top

Making The Best Use of Pascal
*****************************

This chapter provides advice on how best to use the Pascal language when
writing software. Of course, the rules apply to published code only -
if you for example want to comment things out with old style comments
like `(* this one *)', you should do it temporarily and remove it
before distributing your code. But since you never know if and when you
are going to publish your code, it's a good idea to stick to the rules
from the beginning.

* Menu:

* Assorted Tips::               Assorted Pascal Programming Tips
* Consistency Checking::        Using `Assert' to abort if
                                something ``impossible'' happens.
* Formatting::                  Formatting Your Source Code
* Comments::                    Commenting Your Work
* Order::                       Order of Code Blocks
* Capitalization::              Capitalization
* Compiler Directives::         Use of Compiler Directives
* Spacing::                     How to use spaces in your code
* Line Breaks::                 Where to break your lines of code
* Strings::                     Strings
* Internationalization::        Techniques for internationalization
* MemoryMap::                   How you can safely use `MemoryMap'


File: gpcs.info,  Node: Assorted Tips,  Next: Consistency Checking,  Up: Writing Pascal

Assorted Pascal Programming Tips
================================

Pascal code file names should have the `.pas' suffix. The file name
without the suffix should usually correspond to the name of the
program/unit/module, but all in lower case. There should be only one
program/unit/module in a file.

   Code must compile with the `-Wall' flag, with and without the `-O3'
flag with no warnings. (*Note Compiler Directives::, for how to
intentionally disable certain warnings if really necessary.)

   Don't use the automatic `Result' variable in functions. If you want
one, just declare it:

     function Foo (...) = Bar: Integer;

   Use the declaration with `=', not without it, unless you want to be
strictly PXSC compatible.

   If a function returns a `Boolean' to indicate success, `True' should
mean success and `False' failure, unlike some C routines where `0'
means success.

   Avoid `goto' and similar statements, like `Exit', `Return', `Break',
`Continue'. Avoid `goto' at any price (except _possibly_ a non-local
`goto' to return from _deeply_ nested, recursive functions in case of
error). Avoid the others if this is possible with reasonable effort. If
it would require an additional `Boolean' variable, this counts as an
excuse for using those statements if you really want. Note that often,
code becomes significantly _simpler_ by not using `Break' etc. and
instead using a better loop condition or a different kind of loop.

   Never modify `for' loop counters, or rely on their value after the
loop. (Well, that's not merely a coding style, that's the definition of
Pascal. Doing such things will produce undefined results.)

   Never rely on undefined behavior. For example, that global variables
seem to be initialized to `0' at the start of the program, or perhaps
sometimes newly allocated memory seems to be initialized, or memory
after deallocation still seems to hold some values, or that `for' loop
counters seem to have a certain value after the loop - none of these is
guaranteed, and the behaviour may change when you change compiler or
its version, or when you change platform. Undefined means undefined,
and the fact that such things might seem to work on all systems you
have checked and with 42 other compilers means exactly nothing.

   In comparisons put the "more variable" expression on the left side:

     for i := 1 to 10 do
       if a[i] = Foo then
         for j := 1 to 10 do
           if b[j] = a[i] then ...

   Considering the second line of the above example, the expression on
the left (`a[i]') varies each turn, but the right side (`Foo') does
not. (In this case we assume that `Foo' is a constant or a function
which doesn't depend on `i' or some other global data. Otherwise it
might make sense to put `Foo' on the left, and perhaps use an extra
comment to point this out.)

   The last line of the above example might look strange, because
`b[j]' and `a[i]' might look as though they have the same level of
"variableness". But in fact, `j' ranges more often than `i', i.e. each
time `i' changes, `j' has already changed 10 times.

   Avoid code duplication. It is easy to copy the code, but it becomes a
maintenance nightmare to change several similar places. Use routines or
subroutines, units or modules, whatever. Plan each part of the code so
that it can be extended. Don't pull too clever tricks in places that
will likely be changed later.

   Do not surround single statements with `begin' and `end', unless you
have to avoid the dangling else problem or the single line statement
forms a whole routine body! See the following examples:

     if foo then
       begin
         if bar then
           baz
       end  { Avoid the dangling else problem. }
     else
       qux  { Single line statement. }

   Do not write empty unit initializers. This is what _not_ to do:

     ...
     
     procedure Foo;
     begin
       ...
     end;
     
     begin
     end.

   Instead, simply:

     ...
     
     procedure Foo;
     begin
       ...
     end;
     
     end.

   Do not write unused declarations, unless in interfaces which are
meant to be used by the importer.

   Remember that `Boolean's are `Boolean's. Please use `if Foo then'
instead of `if Foo = True then', and `if not Foo then' instead of `if
Foo = False then'. Also, use `until False' in place of `until 1 = 0' -
this looks smarter. Another common situation is `Foo := Expression'
instead of `if Expression then Foo := True else Foo := False'.

   Avoid duplicate global identifiers, i.e. don't overload a built-in
identifier, although the GNU Pascal Compiler allows this, and don't use
the same global identifier in several units or modules. (This feature
will be present in the GNU Pascal Compiler in the future and be called
"qualified identifiers" but still don't use it.)

   We discourage the use of global variables for non-global purposes
(e.g., the use of a variable `Counter' used as a counter in various
local routines). Declare a counter variable for each routine that needs
it, instead. In general, this also allows for better optimization of
the code generated.

   When you need an infinite loop (which may be left with `Break'), we
suggest you use a `repeat' rather than a `while' loop because it shifts
your code less to the right (at least, if there's more than one
statement in the loop). That is:

     repeat
       ...
     until False

   Instead of:

     while True do
       begin
         ...
       end


File: gpcs.info,  Node: Consistency Checking,  Next: Formatting,  Prev: Assorted Tips,  Up: Writing Pascal

Explicitly Checking Internal Consistency
========================================

As stated in the GNU C library documentation (*note Consistency
Checking: (libc)Consistency Checking.), when you're writing a program,
it's often a good idea to put in checks for violations of basic
assumptions.  Consider the following procedure in Pascal:

     procedure DoSomethingOnAPString (StrPtr: PString);

   You may implicitly assume that the above procedure will never be
called with `nil' as its argument, but it is safer to check for the
"impossible condition", i.e. check that `StrPtr' is other than `nil',
like this:

     procedure DoSomethingOnAPString (StrPtr: PString);
     begin
       Assert (StrPtr <> nil);
       ...
     end;

   When this check fails, the program produces a runtime error. You
then may infer that the code which calls this procedure is buggy (or
that you need to extend this particular routine), so this may indeed be
helpful in locating the problem. In other words, checking for basic
assumptions at the beginning of a routine body or other strategic
places is the right way to make sure a function isn't being misused.

   The GNU C library provides the `assert' macro for this kind of
checks. GNU Pascal provides a Pascal counterpart which is called
`Assert', which behaves a little differently. `Assert' won't abort your
program, but rather cause a runtime error (*note Assert: (gpc)Assert.)
which, e.g., you can catch using the `Trap' unit (*note Trap:
(gpc)Trap.).

   Once you think your program is debugged, you can disable the error
checks performed by the `Assert' routine by recompiling with the
`--no-assertions' switch. No change to the source code is needed in
order to disable these checks. Side-effects in the argument to `Assert'
are still evaluated (unlike in C), so it is alright to write:

     Assert (MyFunction (Foo, Bar) > 0)

   This will always call `MyFunction', but only make sure that its
result is positive if `--no-assertions' is not given.

   However, it is recommended that you don't disable the consistency
checks unless you can't bear the program to run a little slower.


File: gpcs.info,  Node: Formatting,  Next: Comments,  Prev: Consistency Checking,  Up: Writing Pascal

Formatting Your Source Code
===========================

First of all, avoid unnecessary spaces at the end of the lines. Also
remember not to save the file with TAB characters, as different editors
or different configurations will interpret them with a different amount
of spaces, thus breaking indentations. (If you use GNU Emacs, the
`untabify' function comes in handy; if you use VIM, the option
`expandtab' (`:set et'); in PENG, the option `Expand tabs' can be used.)

   Please avoid the use of any control characters, except newline, of
course. This means no form feed characters (`#12'), i.e. new page
characters. They are recommended in the GNU Coding Standards to
separate logical parts of a file, but don't use them at least in Pascal
code. No `SUB' character (`#26') either, misused as an end-of-file
indicator by DOS. Older DOS editors put that character at the end of
each file for no good reason, though even the FAT file system knows
about the end of a file by its own.

   We recommend a maximum line length of 68 characters, so that it can
be printed in TeX with default font on A4, or 78 characters, for
80-column wide screens. This is not a fixed rule because breaking lines
too often decreases readability of source code.

   Use empty lines between blocks. Blocks are long comments, `type',
`const', `var', `label' sections, routine bodies, unit/module
initializers/finalizers, `program', `unit', `interface',
`implementation', `module', `export', `uses', `import' lines, global
compiler directives. As far as long comments that refer to the
following declaration, put only an empty line before the comment, not
between the comment and the declaration itself. A special exception is
between blocks within the same routine - do not use empty lines there.
For example:

     procedure Short;
     var
       Foo: Integer;
       Bar: Char;
     begin
       ...
     end;

   But remember to use empty lines to separate subroutines, like the
following:

     procedure Long;
     const
       ...
     var
       variables used by Sub ...
     
       procedure Sub;
       var
         ...
       begin
         ...
       end;
     
     var
       variables not used by Sub ...
     begin
       ...
     end;

   Note that you shouldn't put an empty line after the main routine
declaration, unless a subroutine declaration immediately follows.
Otherwise the main routine declaration would look like a forward
declaration.

   Notice that in the code snippet above we separated local variables
(or constants) before and after the subroutine - this is not mandatory.

   Of course, what we said for subroutines is also valid for
sub-subroutines at any depth.

   An empty line should be put between declarations of the same type,
where appropriate, to separate them logically. In case there is a
comment before the declaration, the empty line must be before the
comment.  Otherwise, the empty line goes before the declaration.

   Empty lines can be used in long comments to separate paragraphs.

   No empty lines at the beginning or ending of a file, only one
newline at the ending. No multiple empty lines.


File: gpcs.info,  Node: Comments,  Next: Order,  Prev: Formatting,  Up: Writing Pascal

Commenting Your Work
====================

The comments should be placed in braces like this:

     { This is a nice comment. }

   Do not use the old style comment between brackets and asterisks, like
this:

     (* This is an ugly comment. One you mustn't write. *)

   Also, do not use comments introduced by the double slash:

     // Another kind of comment not to write.

   Although ISO Pascal explicitly allows for mixed comments, the GNU
Pascal Compiler doesn't even accept it unless you turn it on the option
with the appropriate compiler directive `{$mixed-comments}' - but you
don't want to do it. Here are a couple of examples of mixed comments,
which you should not follow:

     (* This ... }
     { ... and that. *)

   Also, try to avoid nested comments, like `{ { This one } }'.  These
are alright if you want to put some TeX in a comment or something more
exotic. Whatever reason you have to use nested comments, you need to
turn on the option with the appropriate compiler switch, which is
`{$nested-comments}'. Do not use the `--nested-comments' command line
option. Put all such options in the source, so that someone else trying
to compile it doesn't have to figure out what command line switches are
needed, and because command line options would affect _all_ source
files, e.g. when compiling a project with multiple units/modules.

   Please write the comments in your program in English, because
English is the one language that nearly all programmers in all
countries can read.  If you do not write English well, please write
comments in English as well as you can, then ask other people to help
rewrite them. If you can't write comments in English, please find
someone to work with you and translate your comments into English.

   You should adopt "French Spacing", i.e. only one space at the end of
a sentence. This way, you can't use GNU Emacs `M-a' and `M-e' key
combination to move through sentences. We hope that you can live
without that. Also, please put just one space after the comment opening
brace and before the closing brace.

   If a comment regards only one line of code, possibly write it after
the line of code, in the same line, separated from the code with two
spaces.  This is also allowed for the interface section of a unit and
for global variables. Most often you are likely to write this sort of
comment beside record/object fields. In other cases, comments go in one
or more lines of their own, like this:

     { foo bar baz }

   Or longer:

     { foo bar
        baz }

   Or with paragraphs:

     { foo bar
        baz
     
        qux }

   The comments need to be placed before the code they describe, and
they need to get the same indentation level. This example should make
this clear:

     { My types. }
     type
       ...
     
     type
       { My first types. }
       Foo = Integer;
       ...
     
     begin
       { My first statement. }
       Bla;
       { Start of loop. }
       repeat
         { Body of loop. }
         ...
       { Finish when Something happens. }
       until Something
     end;

   Note the position for the comment to `until'.

   Comments describing a global declaration should be on one or more
lines of their own, immediately before the declaration. For example:

     { This is Foo. It does this and that. }
     procedure Foo;

   Do not write "trivial" comments, like the ones listed in the examples
above. You should avoid comments by writing clear code. Linus Torvalds
points this out strongly in the Kernel Coding Style:

     Comments are good, but there is also a danger of over-commenting.
     *Never* try to explain *how* your code works in a comment: it's
     much better to write the code so that the _working_ is obvious,
     and it's a waste of time to explain badly written code.
     Generally, you want your comments to tell *what* your code does,
     not *how*.

   (Note that we otherwise deviate quite a bit from Linus's coding
style.)

   "Tricky" code is worth being commented. We define "tricky" the code
that does non-obvious things, relies on non-obvious assumptions, has
non-obvious implications, there is anything to note when changing it, is
not what it looks at first sight, there is a side effect, or requires
other parts of the source file to be changed simultaneously with it.
Tricky code should be used very sparingly.

   In the case that a comment refers to some other place in the code,
either in the same file or in a different file, please refer to it not
by line number (this will change too often) but by routine name or
context. Also, think whether it is useful to put a comment in the other
place pointing back. (Not always, but sometimes this has proved useful
to us.)

   To comment out parts of code that should not be compiled, you need to
surround it with `{$if False} ... {$endif}' rather than using a comment.

   To separate logical parts within big modules or units, you can use a
special comment - we suggest this fixed pattern as it's easily
searchable:

     {@section Name of the section}
     {@subsection Name of the subsection}

   Note that no space follows the opening brace nor predeces the closing
brace in this case.

   A module or unit or library should have a comment for each of its
interface declarations, so that the interface part of the source file is
a reliable source of documentation. This is optional for any
declarations introduced only in the implementation section or in
`program's. Of course, several related declarations (e.g., groups of
constants) can share a comment.

   A utility called `pas2texi' will be written to build Texinfo files
from Pascal comments. This will allow certain kinds of markup within
comments. They will be described in the documentation of `pas2texi'
and/or in future versions of this document.

   You can use "fixme" comments, to point out things to be fixed in the
code, or in a library (or module, or unit, or compiler used) which
directly affect the code, requiring a work-around. These comments are
prepended by at least two `@' - add as many `@' as the urgency of the
issue increases.

   These comments may contain more or less obscure details about the
problem, especially if the root of the problem is elsewhere. For
example, the comment `{ @@fjf226 }' declares the following code a
work-around to a GNU Pascal Compiler problem which is demonstrated by
the GNU Pascal Compiler test program `fjf226.pas'. (It is a file you
can find in the GNU Pascal Compiler source package.)

   "Fixme" comments should not be mixed with ordinary comments. If you
need both kinds, use them separately, even if directly after each
other. They can be used everywhere, even within statements, since they
are temporary in nature. Most normally they happen to fall in the body,
unless they influence interfaces. In particular, interfaces that are
likely to be changed should have a `@@' comment immediately before
their description comment.


File: gpcs.info,  Node: Order,  Next: Capitalization,  Prev: Comments,  Up: Writing Pascal

Order of Code Blocks
====================

Please start each file with a comment containing, in this order:

   * a short description telling what the code in the source file does

   * a long description going into detail about the code and specifying
     sources of information or code

   * a copyright notification held by authors of the code

   * the license - of course you want to use the GNU General Public
     License or Lesser General Public License for your programs and
     units, don't you?

   In general, you should follow this order for declaration blocks:

   * `const' declarations

   * `type' declarations

   * `var' declarations

   * `label' declarations

   * routines

   You may deviate from this order when it is necessary or makes the
code more readable. This is an example where the order can't be
respected:

     type
       TSomething = record
         This, That: Integer
       end;
     
     const
       SomeConst = SizeOf (TSomething);

   The rules above apply to declaration blocks within routines, too.

   When there are several, more or less independent parts, especially
in a large unit or module, you may apply this order within each part.
Do not put, for example, constants of all parts together. You have to
keep the code readable.

   Variables that are used only in the main program must be declared
globally in Pascal, although GNU Pascal offers an extension for
declaring variables at arbitrary places in the code (*note var:
(gpc)var.). In this case, in contrast to the previous general rule, it
is often better to put their declaration just before the main program's
`begin', after all routines etc., especially when there are more than a
few such variables and the size of the source file is not small. Thus,
the variable declaration block is easier to see and change for the
programmer when editing the main program, and you make sure that
routines don't use them accidentally.

   When you declare a type together with its pointer type, declare the
pointer first. It is easier to recognize especially if the type is a
long record or object. Also, it makes possible using recursive
structures (i.e., using pointers to a type within this type). You
should prepend a `T' to the type name and a `P' to the associated
pointer type. See the example:

     type
       PMyInt = ^TMyInt;
       TMyInt = Integer;
     
       PStrList = ^TStrList;
       TStrList = record
         Next: PStrList;
         s: TString
       end;

   Note that the `Next' field is specified first. We suggest always
putting it as the first field in recursive types, as it allows some
generic list routines and may be a little more efficient to walk the
list, i.e. no offsets.

   We suggest putting all pointer types within each `type' declaration
first, although we don't consider this mandatory. This is an example:

     type
       { Pointer types }
       PFoo = ^TFoo;
       PBar = ^TBar;
       PBaz = ^TBaz;
     
       { Some custom integer types }
       TFoo = Integer attribute (Size = 16);
       TBar = Cardinal attribute (Size = 16);
       TBaz = Cardinal attribute (Size = 32);

   Within object types you can have three declaration areas. There are
three reserved words for introducing these areas: `public',
`protected', `private'. Within each of these areas follow this order:

   * fields

   * constructors

   * destructor (there should be only one)

   * methods

   In the object implementation part, put the routine bodies in the same
order in which they appear in the declaration in the interface. This
also applies to units and modules, in which the implementation should
reflect the interface declarations.

   Do not use the trailing `;' at the end of a block, i.e. before
`end', `until', etc. except `case' - the last branch before the `else'
branch (or the last branch if there is no `else' branch) _should_ have
a `;', to avoid problems like:

     case ...
       Foo:
         if Bar then  { later inserted }
           begin
             ...
           end  { if there's no semicolon here ... }
       else  { ... this will be mistaken as the `then''s `else' }
         ...

   (Same if the `if' was there for longer and the `else' branch of the
`case' is later inserted.)

   In an object, it may look strange to omit the `;' after the last
item which is most often a method. Therefore we allow it, and for
consistency also in records.


File: gpcs.info,  Node: Capitalization,  Next: Compiler Directives,  Prev: Order,  Up: Writing Pascal

Capitalization
==============

Reserved words should be all lower case, including directives, i.e.
words that are reserved only in some contexts, like `protected'. If you
use directives as identifiers (which is likely to cause you pain)
outside of their contexts, write them like identifiers.

   As a special exception, you can use capitalized `File' when used as
a type of its own, i.e. an untyped file, unlike `file of Char'.  The
same can't be said for `procedure' as a type (Borland Pascal style)
since `File' can be a proper type, while `procedure' is a type
constructor, i.e.:

     procedure Foo (var a: File);  { This works. }
     procedure Foo (var a: procedure);  { This doesn't. }

   Next issue is capitalization of identifiers. There's no difference
between built-in and user-defined identifiers. Only the first letter
should be capital, or, if there are concatenated words or acronyms, the
first letter of each word should be capital - do not use underscores.
Acronyms that have become part of the natural language can be written
like that. For example, `Dos' or `DOS'; but always `GPC', not `Gpc'.
Here are some examples of identifiers: `Copy', `Reset', `SubStr',
`BlockRead', `IOResult', `WriteLn', `Sqr', `SqRt', `EOF', `EOLn'.

   These rules apply to constants identifiers, too, unlike C macros.

   Also note that very small identifiers can be written lower case,
like `i' or `s1' or `xx'. Such short identifiers should be used only
locally. They can be used for parameters of global routines, because
the scope of such parameters is local as well, and their names in fact
don't matter at all to the caller. The use of such identifiers in a
global context should be avoided, especially in units or modules or
libraries (because the author doesn't know in which contexts they will
be used).

   Please be consistent with your capitalization. You know that Pascal
will not hurt you if you change capitalization for an identifier
throughout the code, but please stick to the same capitalization.

   For identifiers for the values of enumeration types and for blocks
of constants, i.e. places where you introduce a lot of identifiers, it
can be useful to use a two-letter lower-case prefix and `_', in
contrast to the previous rules:

     type
       TFooBar = (fb_Foo, fb_Bar, fb_Baz, fb_Qux);

     { My Foos }
     const
       mf_Foo = 1;
       mf_Bar = 3;
       mf_Baz = 42;

   In object oriented code (especially in constructors), there is often
the need to have a parameter correspond to an object field (e.g., to
pass a value with which to initialize the field). Since both can't be
called the same, the field should have the "natural" name since it's
usually used in more routines, and the parameter name should be
"mangled". FIXME: We haven't found a really satisfactory rule for
mangling yet (some use `a' as a prefix), and if you have any good idea,
let us know.

   As far as macros are concerned, we strongly recommend that you do not
use them. Please, do not use macros in your programs. Try to avoid
using macros in your programs, because they are evil. We believe you
must not use macros in your code. Said that, if you still dare to use a
macro, write it capitalized entirely and separate words with
underscores. Since macros do not follow Pascal's scoping, it makes
sense to write them differently. This applies to conditionals, too.


File: gpcs.info,  Node: Compiler Directives,  Next: Spacing,  Prev: Capitalization,  Up: Writing Pascal

Use of Compiler Directives
==========================

We generally suggest using as few compiler directives as reasonably
possible, because they make the code harder to understand (e.g., when
checking for side-effects) and to modify (e.g., when moving parts of
code into or out of the scope of compiler directives). The directives
should be invoked like in the example:

     {$your-compiler-directive}

   Definitely not this way (*note Comments::):

     (*$do-not-use-such-a-compiler-directive*)

   Also, definitely not this way, which is dependent on line breaks,
unlike Pascal normally is:

     #your-compiler-directive

   Same goes for macro definitions:

     {$define ...}

   This also saves the ending backslash before line breaks, in contrast
to `#define'. But you will not use macros, will you?  (*note
Capitalization::)

   As far as spacing is concerned, don't type a space before the closing
brace, as there can't be one after the opening brace. If you
concatenate many directives together, don't put a space between each of
them, a single comma is enough.

   No comments should be inserted within the directives. Write them
separately, instead, like this:

     {$X+}  { We need extended syntax. }

   Borland Pascal allows mixing comments with directives, but it's
really a misuse.

   Short forms for calling the directives are alright, but long forms
are at least as good, not to say preferred. Short forms must be written
in caps, while long forms in lower case (except for case-sensitive
arguments like messages and file names - of course, file names must
always be treated as case-sensitive, even on DOS, to preserve code
portability).

   You can combine several directives, also mixing short and long ones,
in a single call, for example like the following:

     {$gnu-pascal,I-,X+}

   Any unit or module should have `{$gnu-pascal,I-}' or
`{$gnu-pascal,I+}' near the beginning (after the head comment with
description and license). `{$gnu-pascal}' lets the unit be compiled
without dialect options even if the main program is compiled with some.
`{$I-}' or `{$I+}' indicates to the user (even though one of them is
the default) whether the unit handles/returns input/output errors or
lets them cause runtime errors. The former is preferable for most
units. For programs, this item is optional. Routines that return
input/output errors should have the attribute `iocritical' (*note
attribute: (gpc)attribute.):

     procedure CriticalRoutine; attribute (iocritical);

   `{$W-}' (no warnings) must only be used locally and must have a
"fixme" comment (*note Comments::) because it indicates a problem with
the code or the compiler.

   Please, don't disable warnings when you're just too lazy to write the
code that does not produce warnings.

   Any compiler flags that are not set globally (for example, together
with `{$gnu-pascal}', see above) should be set with `{$local ...}'. In
other words, not this way:

     {$I-} Reset (f); {$I+}

   But this way:

     {$local I-} Reset (f); {$endlocal}

   The former is wrong if `{$I-}' was set already. Even if a programmer
might know and take into account which is the global setting, this
might be changed sometime, or part of the code may be copied or moved.
The latter form is safer in these cases.

   To make it even clearer, from the last two rules it follows:

     {$local W-} Foo; {$endlocal}  { @ GPC produces a superfluous warning }

   Again, try to avoid local directives. `{$I-}' is sometimes needed.
`{$X+}' might be used if _really_, _really_ necessary (as locally as
possible): avoid pointer arithmetics.

   Don't use `{$X+}' to ignore function results, don't use
`{$ignore-function-results}', either. It is too easy to ignore a result
one should not ignore. Sometimes, especially when linking to a foreign
C library, you might have to deal with functions which have a
superfluous result, which you probably don't want to check. You can
declare such functions with the `ignorable' attribute, so that their
results are silently ignored.

   Also use dummy variables if you want to ignore the result of a
particular call to a function whose result should in general not be
ignored. But in such cases check carefully whether the result can
really be ignored safely. If, however, an unexpected result would
indicate an "impossible" situation, it's usually better to check the
result and print a warning or abort in the unexpected case, at least if
`DEBUG' is defined (*note Compiler Directives::).

   Linker directives, i.e. `{$L}' for libraries and C (or other
language) source files should be put near the start in programs and
shortly after the `implementation' line in units or modules.  Several
libraries and C source files in one directive are possible when they
belong logically together (for example, a library and its C wrappers),
but not for separate things. This directive should not be mixed with
other directives (which doesn't even work if `L' comes first - the
other way around it might work, but shouldn't be used). The external
declaration of the library or C routines should immediately follow the
directive (except in a unit or module for those that go in the
interface). Using `{$L}' in programs is often not a good idea, making a
unit is often better for abstraction and reuse.

   Conditional compilation might be useful sometimes, but you should
use as few `{$ifdef}''s as possible, as they decrease readability. When
conditionals are used for differences between systems, check for
features (for example, `__BYTES_LITTLE_ENDIAN__') or groups of systems
(for example, `__OS_DOS__') rather than individual systems, to better
cater for systems you don't know or that may not even exist yet.

   If possible (this might not be available), use the predefined
constants (for example, `BytesBigEndian', `OSDosFlag') rather than
defines - for code that is possible (the "always false" branch will be
optimized away, but you still get its syntax checked as an additional
benefit besides not using the preprocessor); for type declarations it
is usually not possible and you have to use the defines. A good example
is the declaration of `TWindowXY' in the CRT unit. See:

     TWindowXYInternalCard8 = Cardinal attribute (Size = 8);
     TWindowXYInternalFill = Integer attribute (Size = BitSizeOf (Word) - 16);
     TWindowXY = packed record
       {$ifdef __BYTES_BIG_ENDIAN__}
       Fill: TWindowXYInternalFill;
       y, x: TWindowXYInternalCard8
       {$elif defined (__BYTES_LITTLE_ENDIAN__)}
       x, y: TWindowXYInternalCard8;
       Fill: TWindowXYInternalFill
       {$else}
       {$error Endianness is not defined!}
       {$endif}
     end;

   The `DEBUG' flag should be used for (and only for) code to help
debugging, i.e. code which doesn't change the real functionality.
Programs must compile with and without setting `DEBUG'. The latter may
run slower and may produce useful additional messages in a suitable
form, i.e. clearly marked as debug messages, for example prefixed with
`DEBUG: ', and _may_ abort when it detects erroneous or dubious
conditions.

   Conditionals can also be used to make different versions of some
code, for example, using GMP numbers if a condition is satisfied and
using normal integers or reals otherwise (GMP is a library for working
with arbitrarily large numbers). In this case, the name and meaning of
all such defines used in a file must be explained in a comment near the
top. (For examples, see the `__BP_TYPE_SIZES__', `__BP_RANDOM__' and
`__BP_PARAMSTR_0__' in the System unit.) The code must compile with any
combination of those conditionals set, which means you have to test
exponentially many cases - here is a good reason to keep their number
as small as possible.

   Another similar use of conditionals is to select between different
implementations. You should adopt this strategy _only_ if all of the
implementations are really supported or planned to be supported.
Otherwise, you'd better move the old implementations into your "museum"
and keep the code clean. The notes about code compilation of the
previous rule apply here as well.

   When you need to deal with complicated conditionals use Pascal
syntax, i.e. format the conditionals according to the rules for Pascal
code, rather than C syntax. This is a silly example:

     {$if defined (Foo) or False}

   Instead, this is an example not to follow:

     {$if defined (Foo) || 0}

   Or even worse:

     #if defined (Foo) || 0

   A special conditional can be used to comment out code temporarily.
Here's the appropriate syntax:

     {$if False} ... {$endif}

   A standard conditional statement should be used in programs or units
or modules you distribute to make sure that the appropriate version of
the GNU Pascal Compiler is used. You can follow this template:

     {$if __GPC_RELEASE__ < 20020510}
     {$error This unit requires GPC release 20020510 or newer.}
     {$endif}


File: gpcs.info,  Node: Spacing,  Next: Line Breaks,  Prev: Compiler Directives,  Up: Writing Pascal

How to use spaces in your code
==============================

In general, no multiple spaces should be used except for indentation and
as indicated below.

   A single space goes before and after operators, and `:=' and `..' as
well as `:' in `Write', `WriteLn' and `WriteStr'; after the comma and
other `:'. This example ought to make it clearer:

     var
       Foo: Integer;
       ...
     begin
       Foo := 42;
       WriteLn (Foo + 3 : 5, ' bar')
     end;

   No space should go before unary `-'. In fact, these are the correct
forms: `x - 1', `-x', `-1'.

   A space must go before the opening parenthesis (`(') and after the
closing parenthesis (`)'), unless adjacent to further parentheses,
brackets, `^', `;', `,'. In other words, a space goes between
identifiers or keywords and the opening brace (`('). (All the other
spaces in this example are implied by the previous rule already.) See:

     Foo (Bar^(Baz[Qux * (i + 2)]), Fred (i) + 3);

   For indexing arrays actually don't use a space before the opening
bracket, i.e. `Foo[42]' rather than `Foo [42]'. However, insert a space
before the opening bracket in array declarations, like:

     Foo: array [1 .. 42] of Integer;

   A space goes before the opening bracket of a set constructor in some
situations - those brackets should be treated like parentheses, unlike
the brackets used in array indexing. For example:

     x := [0, 2 .. n];

   But:

     Foo ([1, 2, 3]);

   No spaces for `.' and `^':

     Rec.List^.Next^.Field := Foo

   As we already pointed out, a single space goes after the opening
brace and before the closing brace in comments, but not in compiler
directives. Also, and we said this already too somewhere in the manual,
two spaces go before comments after a line of code. For example:

     Inc (x);  { Increment x. }

   Optionally use additional spaces to make "tabular" code. In our
opinion, this increases readability a lot because the human eye and
brain is trained to recognize such structures, and similiarities and
differences between the lines can be easier seen, and when changing the
code, it's easier to find related places. An application of this
principle can be seen in interface declarations (not so much applicable
when separated by comments, but, for example, when described by a shared
comment above them all):

     function Pos             (const SubString, s: String): Integer;
     function LastPos         (const SubString, s: String): Integer;
     function PosCase         (const SubString, s: String): Integer;
     function LastPosCase     (const SubString, s: String): Integer;
     function CharPos         (const Chars: CharSet; const s: String): Integer;
     function LastCharPos     (const Chars: CharSet; const s: String): Integer;
     function PosFrom         (const SubString, s: String; From: Integer): Integer;
     function LastPosTill     (const SubString, s: String; Till: Integer): Integer;
     function PosFromCase     (const SubString, s: String; From: Integer): Integer;
     function LastPosTillCase (const SubString, s: String; Till: Integer): Integer;

   Also possible:

     procedure Foo;
     function  Bar ...;
     procedure Baz;

   And, of course:

     const
       FooBar = 1;
       Baz    = 2;
       Quux   = 3;

   The same "tabular" strategy used in interfaces and const declarations
can be used in initializers:

     const
       Foo: TBarArray =
         (('Foo'    ,  3),
          ('Bar baz', 42),
          (''       , -1));

   And in `case' statements:

     case ReadKeyWord of
       kbLeft    : if s[n] > l    then Dec (s[n]) else s[n] := m[n];
       kbRight   : if s[n] < m[n] then Inc (s[n]) else s[n] := l;
       kbUp      : if n > 1 then Dec (n) else n := 5;
       kbDown    : if n < 5 then Inc (n) else n := 1;
       kbHome    : s[n] := l;
       kbEnd     : s[n] := m[n];
       kbPgUp,
       kbCtrlPgUp: n := 1;
       kbPgDn,
       kbCtrlPgDn: n := 5;
       kbCR      : Done := True;
     end

   And optionally in other code:

     WriteCharAt (1, 1, 1,     Frame[1], TextAttr);
     WriteCharAt (2, 1, w - 2, Frame[2], TextAttr);
     WriteCharAt (w, 1, 1,     Frame[3], TextAttr);


File: gpcs.info,  Node: Line Breaks,  Next: Strings,  Prev: Spacing,  Up: Writing Pascal

Where to break your lines of code
=================================

A line break is optional after _local_ `const', `type', `var'
declarations if they contain only a single declaration (but it is
possible to have multiple identifiers in a single line).

     procedure Baz;
     var Foo, Bar: Integer;
     begin
       ...
     end;

   Of course, this is also accepted:

     procedure Baz;
     var
       Foo, Bar: Integer;
     begin
       ...
     end;

   But don't follow this example:

     procedure Baz;
     var Foo, Bar: Integer;
         Qux: Real;
     begin
       ...
     end;

   If you have many declarations you can break lines several ways. The
following is the preferred form for `var' declarations:

     var
       Foo, Bar, Baz, Qux, Quux, Corge, Grault, Garply, Waldo, Fred,
         Plugh, Xyzzy, Thud: Integer;

   or:

     var
       Foo, Bar, Baz, Qux, Quux, Corge, Grault, Garply, Waldo: Integer;
       Fred, Plugh, Xyzzy, Thud: Integer;

   This one, instead, is more suitable to `record' and public `object'
fields, especially if there's a comment for many or each of them:

     var
       Foo,
       Bar,
       Baz,
       Qux: Integer;

   No line break after `var' declarations within statement blocks,
because they allow only one declaration, and doing a line break would
look like further ones were allowed.

     Foo := Bar;
     var Baz: array [1 .. Foo] of Integer;

   As they are a GNU Pascal extension, use these declarations sparingly,
for example for variables whose size depends on values computed within
the routine, or for variables within unit or module initializers or
finalizers to avoid global variables, although you might want to think
about using a subroutine.

   Do not insert a line break after `label'. This is how you should
declare labels:

     label Foo, Bar, Baz;

   And, for completeness, here's how not to do it:

     label
       Foo,
       Bar,
       Baz;

   Several declarations in different lines don't even work:

     label
       Foo;
       Bar;
       Baz;

   Here's an example on how to use line breaks within a case statement.

     case
       foo:
         begin
           ...
         end;
       bar,
       baz .. qux:
         ...
       else
         ...
     end;

   Or ("tabular"):

     case
       foo:        begin
                     ...
                   end;
       bar,
       baz .. qux: ...
       else        ...
     end;

   Long statements or declarations should be broken either always before
operators or always after them (where the extent of always is at least
one routine) or after a comma, with indentation such as to make the
meaning clear:

     if (x = y)
        and (foo
             or (bar
                 and (baz or qux))
             or fred) then

   or:

     if (x = y) and
        (foo or
         (bar and
          (baz or qux)) or
         fred) then

   Here's how to use line breaks within if-then-else statements. Another
use for it is where you would use a `case' statement if it was
possible, but it isn't possible (for example because the types are not
ordinal, or the values to be compared to are not constant, or the
comparison involves a function (`StrEqualCase', or there are additional
conditions).

     if ... then
       a
     else if ... then
       b
     else
       c

   If `a' and non-`a' are main cases, and `b' and `c' are sub-cases of
non-`a', use the following (the distinction might be a matter of taste
sometimes):

     if ... then
       a
     else
       if ... then
         b
       else
         c

   The following (biologically quite incomplete) example contains a
mixture of both forms which we consider reasonable:

     if Habitat = 'Water' then
       { Animals living in water }
       WriteLn ('Is it a fish?')
     else if Habitat = 'Air' then
       { Animals living in air }
       WriteLn ('Is it a bird?')
     else
       { Animals living on land }
       if Legs = 8 then
         WriteLn ('Is it a spider?')
       else
         WriteLn ('Is it a gnu?')

   The main cases are determined by the habitat, and the number of legs
determines some sub-cases.

   For normal control loops here's a brief list of possibilities:

     for ... do
       ...

     while ... do
       ...

     repeat
       ...
     until ...

   If there is only one command after the `if' clause, or in a `for' or
`while' loop, or between `repeat' and `until', and if that command is
short enough, you can put the statement on one line only, like this:

     if ... then ...

     for ... do ...

     while ... do ...

     repeat ... until ...

   Here's how to behave when `begin' and `end' are involved.

     if ... then
       begin
         ...
       end

     for ... do
       begin
         ...
       end

     while ... do
       begin
         ...
       end

   The indentation is 2 characters wide, for each `begin', `then',
`else', `case', `do' (`for', `while', `with', `to begin', `to end'),
`repeat', `record', `object', `type', `const', `var', `label'.

   The bodies and local variables etc. of global routines must not be
indented, just like global variables etc. Each subroutine (header and
body) and its declarations, on the contrary, must be indented.

     program Prog;
     
     var
       GlobalVar: Integer;
     
     procedure GlobalProc;
     var LocalVar: Integer;
     
       procedure LocalProc;
       var LocalLocalVar: Integer;
       begin
         WriteLn ('This is a local procedure.')
       end;
     
     begin
       WriteLn ('This is a global procedure.')
     end;
     
     begin
       WriteLn ('This is the main program.')
     end.

   Variant records should be indented as follows:

     type
       Foo = record
         NonVariant: Foo;
       case Discriminant: Bar of
         Val1: (Variant1: Baz;
                Variant2: Qux);
         Val2: (Variant3: Fred)
       end;
     
     var
       Foo: record
         [ as above ]
       end = [ initializer ]

   Bigger indentation, i.e. more than 2 characters wide, can be used to
break statements or declarations or to get a "tabular" code.

   Conditionals (`{$ifdef}') should be on the same indentation level as
the code they affect:

     begin
       {$ifdef DEBUG}
       WriteLn ('Debugging version');
       {$endif}
       ...
     end;

   Short conditionals which affect only an expression can be written
within a single line:

     Foo := {$ifdef DEBUG} 'debug' {$else} 'release' {$endif};

   If they are intentionally used in a way contrary to normal syntactic
rules, put them where they seem to fit best and write a comment:

     begin
       { Do the code unconditionally if debugging }
       {$ifndef DEBUG}
       if SomeCondition then
       {$endif}
         begin
           ...
         end
     end;

   Most times you will find a nicer and not less efficient way of
writing the same statements. In this case, it can be done this way:

     begin
       if {$ifdef DEBUG} True {$else} SomeCondition {$endif} then
         begin
           ...
         end
     end;

   Or better yet:

     { globally }
     const
       DebugFlag = {$ifdef DEBUG} True {$else} False {$endif};
     
     begin
       if DebugFlag or SomeCondition then
         begin
           ...
         end
     end;


File: gpcs.info,  Node: Strings,  Next: Internationalization,  Prev: Line Breaks,  Up: Writing Pascal

Strings
=======

Most rules we have covered so far do not apply within strings. In
general, messages contained in strings should follow the GNU Coding
Standards, for example, put quoted names within ``' and `'', although
this means you have to double the `'' in a Pascal string.  *Note
Errors: (standards)Errors, for more information.

   Normally you should use strings enclosed in single quotes, like
`'this nice string that you are reading''. Use strings in double quotes
when you need C style escape sequences like `"\t"'. Note that `NewLine'
(`"\n"') is predefined, so using `NewLine' is preferable unless you
have to use a C style string for other purposes.

   You can use multiline strings like the following:

     WriteLn ('Hello
     world')

   or (perhaps preferable, especially if the text in the string contains
paragraphs and/or indentation itself):

     WriteLn (
     'Hello
     world')

   However, it is also possible to use:

     WriteLn ('Hello' + NewLine + 'world')

   (Note that the above example won't compile without using the `GPC'
unit.)

   Or, of course:

     WriteLn ('Hello');
     WriteLn ('world')

   When you want to check if a string is empty, use this syntax:

     if s = '' then
       ...

   The GNU Pascal Compiler will eventually optimize it to the following
more efficient test, hence you can use the previous, shorter one with
no regret:

     if Length (s) = 0 then
       ...

   The same applies for `<>', of course, and even for assignments where
`s := ''' is the recommended form and will be optimized by GPC to
`SetLength (s, 0)'.


File: gpcs.info,  Node: Internationalization,  Next: MemoryMap,  Prev: Strings,  Up: Writing Pascal

Techniques for internationalization
===================================

Please note the description in the GPC manual on how to do so (*note
I18N: (gpc)I18N.).


File: gpcs.info,  Node: MemoryMap,  Prev: Internationalization,  Up: Writing Pascal

MemoryMap
=========

This section of the GNU Coding Standards also applies to GNU Pascal.
Remember that `mmap' actually means `MemoryMap' in this context. *Note
Mmap: (standards)Mmap.


File: gpcs.info,  Node: Documentation,  Next: Managing Releases,  Prev: Writing Pascal,  Up: Top

Documenting Programs
********************

We recommend reading the respective section in the GNU Coding Standards,
as it applies to this context, too. *Note Documentation:
(standards)Documentation. There are some notes worth writing here,
though.

   As far as man pages are concerned, it would be nice to have a man
page referring to the Info documentation. There is a GNU program,
called `help2man', which generates a man page based on the `--help' and
`--version' outputs of a program. It works well, except that it always
prints `FSF' which is not correct for all programs compiled with the
GNU Pascal Compiler, but the output can easily be changed (for example,
automatically using `sed').

   However, don't put too much effort in man pages. They might be
feasible initially, but keeping them up to date together with the
Texinfo files means a lot of work. On top of that, if you don't keep
them updated, they are likely to cause more confusion than they help.

   On the one hand, if man pages are shortened too much they are likely
to miss important information. On the other hand, if not shortened, they
get hard to navigate.

   In other words, devote to Info (i.e., Texinfo) documentation.


File: gpcs.info,  Node: Managing Releases,  Next: Glossary,  Prev: Documentation,  Up: Top

The Release Process
*******************

Please read the respective chapter in the GNU Coding Standards.  Note
that the huge auto-tools effort of C is not needed for normal GNU
Pascal programs. Also Makefiles are often not necessary in GNU Pascal.
*Note Managing Releases: (standards)Managing Releases.

* Menu:

* Makefile Conventions::           Makefile Conventions


File: gpcs.info,  Node: Makefile Conventions,  Up: Managing Releases

Makefile Conventions
====================

For your Pascal project you probably won't need large `Makefile's and
you won't need to use `autoconf' or `automake'. You can give the
`--automake' to the GNU Pascal Compiler so that it takes care of
dependencies for you. (As of this writing, the GNU Pascal Compiler's
`automake' feature has some slight bugs, but they will be fixed. Also,
there is a plan for a utility called `gp', which is now under
development, which will simplify the compilation process a lot more.
Stay tuned. In any case, you usually don't need to write complex
`Makefile's yourself.)

   A _simple_ Makefile may be in order, like:

     GPC_FLAGS=-O2
     
     all: foo
     
     foo: foo.pas unit1.pas
     	gpc --automake $(GPC_FLAGS) foo.pas
     
     mostlyclean:
     	-rm -f *.o *.gpi *.gpd core
     
     clean: mostlyclean
     	-rm -f foo
     
     distclean: clean
     
     extraclean: distclean
     	-rm -f *~*
     
     maintainer-clean: extraclean

   You may, however, want to put other rules into a `Makefile' to build
documentation, data files, making distributions or whatever.  Such
things are outside of the scope of this text. You can usually do the
Pascal compilations with a single `gpc --automake' call per program.


File: gpcs.info,  Node: Glossary,  Next: Index,  Prev: Managing Releases,  Up: Top

Glossary of words used throughout this text
*******************************************

Routines are `procedure's, `function's, `constructor's, `destructor's
or (user-defined) operators.

   Declarations are those parts of a program that "announce" the
existence and properties of certain objects like constants, types,
variables, routines, units, modules and the program.

   Statements are those parts of a program that actually "do"
something. A single statement is an assignment, a procedure call, a
jumping statement (`goto', `Exit', `Return', `Break', `Continue'), an
assembler statement, or a compound statement (`begin' ... `end', `if',
`case', `repeat', `while', `for', `with') which in turn may contain one
or several statements.

   Identifiers are those language elements that give names to objects
like routines, constants, types, variables, units, modules. They can be
(locally) redefined, unlike keywords which are part of fixed syntactic
constructs (for example `if' ... `then' ...  `else') and cannot be
redefined. Macros are no language elements at all since they are
expanded by the preprocessor and never seen by the compiler.

   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. (*note Endianness: (gpc)Endianness.)

   _Note:_ Other items may be inserted here when it appears useful. If
you'd like a definition of some other term, let us know.


File: gpcs.info,  Node: Index,  Prev: Glossary,  Up: Top

Index
*****

* Menu:

* assert:                                Consistency Checking.
* assorted tips:                         Assorted Tips.
* blanks:                                Formatting.
* booleans:                              Assorted Tips.
* breaking long lines:                   Line Breaks.
* C code compilation:                    Pascal and C.
* capitalization:                        Capitalization.
* case and line breaks:                  Line Breaks.
* commenting:                            Comments.
* commenting out:                        Comments.
* commenting out code:                   Compiler Directives.
* comments about non-obvious code:       Comments.
* comments and directives:               Compiler Directives.
* comments for separating logical parts: Comments.
* comments language:                     Comments.
* comments placement:                    Comments.
* comments spacing:                      Comments.
* comments to external sources:          Comments.
* comments with markup:                  Comments.
* compiler directives:                   Compiler Directives.
* complicated conditionals:              Compiler Directives.
* conditional compilation:               Compiler Directives.
* conditionals and different implementations: Compiler Directives.
* conditionals and different versions:   Compiler Directives.
* conditionals and GPC version:          Compiler Directives.
* consistency checking:                  Consistency Checking.
* constants:                             Capitalization.
* constants capitalization:              Capitalization.
* contributions to this manual:          Preface.
* control characters:                    Formatting.
* control loops:                         Line Breaks.
* debug flag:                            Compiler Directives.
* declaration blocks:                    Order.
* declarations within object types:      Order.
* declarations within type declarations: Order.
* descriptive comments:                  Comments.
* directives spacing:                    Compiler Directives.
* documentation:                         Documentation.
* downloading the coding standards:      Preface.
* empty lines:                           Formatting.
* enum types:                            Capitalization.
* error checks:                          Program Behavior.
* feedback:                              Preface.
* fixme comments:                        Comments.
* formatting source code:                Formatting.
* global variables:                      Assorted Tips.
* glossary:                              Glossary.
* header translator:                     Pascal and C.
* identifiers capitalization:            Capitalization.
* if then else statements and line breaks: Line Breaks.
* implementation order:                  Order.
* indentation:                           Line Breaks.
* infinite loops:                        Assorted Tips.
* internationalization:                  Internationalization.
* label spacing:                         Line Breaks.
* legal aspects:                         Legal Issues.
* line breaks:                           Line Breaks.
* line length:                           Formatting.
* linker directives:                     Compiler Directives.
* linking to C libraries:                Pascal and C.
* local directives:                      Compiler Directives.
* macros capitalization:                 Capitalization.
* makefile conventions:                  Makefile Conventions.
* MemoryMap:                             MemoryMap.
* nested comments:                       Comments.
* no-warning directive:                  Compiler Directives.
* non-standard extensions:               Using Extensions.
* OOP:                                   Capitalization.
* order:                                 Order.
* Pascal and C:                          Pascal and C.
* program design:                        Design Advice.
* programming languages:                 Source Language.
* releasing:                             Managing Releases.
* return checks:                         Compiler Directives.
* signal functions:                      Program Behavior.
* silly comments:                        Comments.
* spaces:                                Formatting.
* spacing, tabular code:                 Spacing.
* standard directives:                   Compiler Directives.
* strings:                               Strings.
* tabular code, spacing:                 Spacing.
* tricky comments:                       Comments.
* trivial comments:                      Comments.
* variable declaration:                  Order.
* where to obtain the GPCS:              Preface.
* wrappers:                              Pascal and C.



Tag Table:
Node: Top951
Node: Preface1534
Node: Legal Issues3513
Node: Design Advice3866
Node: Source Language4290
Node: Pascal and C4950
Node: Using Extensions7184
Node: Program Behavior11644
Node: Writing Pascal15052
Node: Assorted Tips16431
Node: Consistency Checking21987
Node: Formatting24232
Node: Comments27469
Node: Order34510
Node: Capitalization39015
Node: Compiler Directives42497
Node: Spacing51529
Node: Line Breaks55810
Node: Strings63200
Node: Internationalization64894
Node: MemoryMap65159
Node: Documentation65431
Node: Managing Releases66734
Node: Makefile Conventions67198
Node: Glossary68537
Node: Index70154

End Tag Table
