			Convert C to Pascal
			===================

  This is a brief explanation about how to convert C code to Pascal.  Note that
  this document is to help to write the Allegro.pas wrapper library.

  You should read file "style.txt" too.



Content
-------

 * Allegro's API description
 * Data types
 * Enumerations
 * Parameters and return values
 * NOTES



Allegro's API description
-------------------------

  Allegro aims to define an API that is the same in any platform supported, so
  it's easer to port programs from one to another.  Since each platform has a
  different calling conventions it defines some "macros" to help to declare
  functions[1], data types and variables.

  "AL_FUNC (type, name, args)" defines a procedure (if type is "void") or
  function.  Note that "args" are a list of "type name" separated by comma.

  For example:

    AL_FUNC (void, al_set_new_bitmap_format, (int format));
    AL_FUNC (int, al_get_new_bitmap_format, (void));

  becames

    PROCEDURE al_set_new_bitmap_format (format: LONGINT); CDECL;
    FUNCTION al_get_new_bitmap_format: LONGINT; CDECL;

  The "CDECL" modifier tells the compiler that it's a C function.  It's
  necesary because C uses a different calling convention than Pascal.

  Most functions are in dll/so/dylib files so they're external.

  Some functions are "inline", and should be "INLINE" in Pascal too.  Also
  wrapper functions and procedures should be "INLINE" too.



Data types
----------

  C data types aren't very different than Pascal ones, but we should be careful
  to keep the same size to make them compatible.

  Free Pascal compiler activates some CPU exceptions to manage data
  conversions.  By default, C compilers don't activate these exceptions.  That
  results in some issues as discused in an Allegro.cc forum thread[2].

  Pointers in C are marked by "*".  "char*" is a pointer to char, and most
  cases it points to an ANSISTRING.  Used as parameter, should be ANSISTRING,
  used as returned value, should be PANSICHAR.

  C doesn't distiguish between arrays and pointers.  Actually an array is a
  pointer that points to a "non dynamic" memory space.

  "bool" is the bad guy here.  It's a recent addition to the C language
  (1999 IIRC) and not all compilers support it.  Allegro 4 defines it as
  "unsigned char" if compiler doesn't supports it.

  Enumerations are discussed in next section.

  Here you have a list of data types.  First column are C types, second are
  Pascal types.

  bool			BOOLEAN[3]

  char			ANSICHAR or SHORTINT (depending the use).
  unsigned char		BYTE
  *char			PANSICHAR or ANSISTRING

  int			LONGINT
  long int		LONGINT or INT64
  unsigned int		LONGWORD
  unsigned long int	LONGWORD or QWORD

  uint32_t		LONGWORD

  float			SINGLE
  double		DOUBLE


  Anyway, unit al5base defines some types to make it easer.  For example, C
  type "int" is "AL_INT", "unsigned int" is "AL_UINT", etcetera.


Enumerations
------------

  Enumerations are another "bad guy".  In C There are almost no differences
  between "enum" and "int".  Actually, Allegro 5 doesn't use enums as function
  parameter, it uses "int".  I think we should use enumerations.

  Free Pascal and Delphi optimizes enumerations.  Both have modifiers that
  modifies that.  AFAIK C enums are 4 bytes wide.



Parameters and return values
----------------------------

  In most functions parameters are pased "by value" with no modifications.

  In some cases they're passed as "const", so we must use the "CONST"
  modifier.  Note that "const" are not applied to some pointers, as the
  "const" affects to the direction not the actual data.

  C hasn't "VAR" nor "OUT" modifiers:  it uses pointer for this.  Both FPC and
  Delphi translate "VAR" and "OUT" to pointers, so use VAR and OUT.  If there's
  any problem, use wrapper procedures instead:

INTERFACE

  PROCEDURE WrapperProcedure (VAR Variable: AL_UINT); INLINE;

IMPLEMENTATION

  PROCEDURE _ActualFunction_ (ValuePtr: AL_UINTptr); CDECL; EXTERNAL ...;

  PROCEDURE WrapperProcedure (VAR Variable: AL_UINT);
  BEGIN
    _ActualFunction_ (@Variable);
  END;

  Note that C strings are a special case.  When passing a string as parameter,
  ANSISTRING works pretty well (or AL_STR as defined by al5base), but returning
  it doesn't.  This is because C returns a pointer to an internal string that is
  managed by Allegro, or a pointer that should be managed by the caller using the
  Allegro memory functions.  When FPC or Delphi try to manage them bad things
  happen.  So when returning, use pointers (i.e. AL_STRptr).

NOTES
-----

  [1] In C there's no difference between "function" and "procedure"; both are
      functions.  The difference is that some functions doesn't return any
      value (they're of type "void").

  [2] http://www.allegro.cc/forums/thread/602423

  [3] Not sure but it seems to work.
