Writing portable code

[prev] [prev-tail] [tail] [up]

### 7.4 Writing portable code

Free Pascal is designed to be cross-platform. This means that the basic RTL units are usable on all platforms, and the compiler behaves the same on all platforms (as far as possible). The Object Pascal language is the same on all platforms. Nevertheless, FPC comes with a lot of units that are not portable, but provide access to all possibilities that a platform provides.

The following are some guidelines to consider when writing portable code:

- Avoid system-specific units. The system unit, the objects and classes units and the SysUtils unit are guaranteed to work on all systems. So is the DOS unit, but that is deprecated.
- Avoid direct hardware access. Limited, console-like hardware access is available for most platforms in the Video, Mouse and Keyboard units.
- Do not use hard-coded filename conventions. See below for more information on this.
- Make no assumptions on the internal representation of types. Various processors store information in different ways (’endianness’).
- If system-specific functionality is needed, it is best to separate this out in a single unit. Porting efforts will then be limited to re-implementing this unit for the new platform.
- Don’t use assembler, unless you have to. Assembler is processor specific. Some instructions will not work even on the same processor family.
- Do not assume that pointers and integers have the same size. They do on an Intel 32-bit processor, but not necessarily on other processors. The PtrInt type is an alias for the integer type that has the same size as a pointer. SizeInt is used for all size-related issues.

The system unit contains some constants which describe file access on a system:

AllFilesMask
  a file mask that will return all files in a directory. This is * on Unix-like platforms, and *.* on dos and windows like platforms.
LineEnding
  A character or string which describes the end-of-line marker used on the current platform. Commonly, this is one of #10, #13#10 or #13.
LFNSupport
  A boolean that indicates whether the system supports long filenames (i.e. is not limited to MS-DOS 8.3 filenames).
DirectorySeparator
  The character which acts as a separator between directory parts of a path.
DriveSeparator
  For systems that support drive letters, this is the character that is used to separate the drive indication from the path.
PathSeparator
  The character used to separate items in a list (notably, a PATH).
maxExitCode
  The maximum value for a process exitcode.
MaxPathLen
  The maximum length of a filename, including a path.
FileNameCaseSensitive
  A boolean that indicates whether filenames are handled case sensitively.
FileNameCasePreserving
  A boolean that indicates whether case in filenames is preserved on creation or rename.
UnusedHandle
  A value used to indicate an unused/invalid file handle.
StdInputHandle
  The value of the standard input file handle. This is not always 0 (zero), as is commonly the case on Unices.
StdOutputHandle
  The value of the standard output file handle. This is not always 1, as is commonly the case on Unices.
StdErrorHandle
  The value of the standard diagnostics output file handle. This is not always 2, as is commonly the case on Unices.
CtrlZMarksEOF
  A boolean that indicates whether the #26 character marks the end of a file (an old MS-DOS convention).

To ease writing portable file system code, the Free Pascal file routines in the system unit and sysutils unit treat the common directory separator characters (/ and \) as equivalent. That means that if you use / on a Windows system, it will be transformed to a backslash, and vice versa.

This feature is controlled by 2 (pre-initialized) variables in the system unit:

AllowDirectorySeparators
  A set of characters which, when used in filenames, are treated as directory separators. They are transformed to the DirectorySeparator character.
AllowDriveSeparators
  A set of characters which, when used in filenames, are treated as drive separator characters. They are transformed to the DriveSeparator character.

[prev] [prev-tail] [front] [up]