Difference between revisions of "H2O"

From BlackBox Framework Wiki
Jump to navigation Jump to search
(→‎Linux: removed /usr/bin from calling oo2c and added sudo (did not work on a recent Debian 9 otherwise))
 
(30 intermediate revisions by 2 users not shown)
Line 1: Line 1:
H2O — is the tool for making [[Oberon]] and [[Component Pascal]] import modules from C header files.
H2O — is the tool for making [[Oberon]] and [[Component Pascal]] import modules from C header files.


== Installation ==
= Intro and Credits =


H2O sources distributed with [[oo2c]] compiler.
H2O (Header to Oberon) is a tool for creating Oberon interface modules from C-Header files for foreign libraries. It has been created by Stewart Greenhill around 2001 for use with the Optimizing Oberon Compiler OOC/oo2c, which in turn has been created by Michael van Acken end of the 1990. Ability to create interface modules for Component Pascal has been implemented by Bernhard Treutwein end of 2006 and fed back into the cvs tree at sourceforge by Stewart Greenhill in March, 2007.


=== Linux ===
= Installation =


1. Download sources from: https://github.com/AlexIljin/oo2c
The H2O sources are distributed with [[oo2c]] compiler. The oo2c compiler is/must be used for building H2O.


git clone https://github.com/AlexIljin/oo2c.git
== Linux ==


2. Compilation of [[oo2c]]:
1. Download binary distribution and install it: https://sourceforge.net/projects/ooc/files/ooc2/2.1.11/
 
./configure
sudo make install
 
2. Download last sources from: https://github.com/Spirit-of-Oberon/oo2c
 
git clone https://github.com/Spirit-of-Oberon/oo2c
 
3. Compile last version of '''oo2c''' from repository:


  cd oo2c
  cd oo2c
  export LDFLAGS="-lm"
  make cvsclean
  chmod +x configure
  ./configure
  ./configure --prefix /usr
  . ENV
  make
make $OOC_DEV_ROOT/oo2crc-install.xml
  sudo make install
  oo2c -M --config oo2crc-install.xml oo2c
  sudo make install BOOTSTRAP_COMPILER=bin/oo2c


3. Compilation of H2O
4. Compilation of H2O


  oo2c -M src/TestH2O.Mod
  oo2c -M src/TestH2O.Mod
sudo cp bin/TestH2O /usr/bin/TestH2O


=== Windows ===
== Windows ==


H2O can be run on windows with [https://www.cygwin.com/ Cygwin]. The example you can download [http://forum.oberoncore.ru/viewtopic.php?f=34&t=661&p=86819&hilit=H2O#p68484 here].
H2O can be run on windows with [http://www.cygwin.com/ Cygwin].


== Usage ==
The example of built distribution you can find [http://forum.oberoncore.ru/viewtopic.php?f=34&t=661&p=86819&hilit=H2O#p68484 here].


There are a couple of modes in which it can work.
[http://forum.oberoncore.ru/download/file.php?id=2847 Download]


= Usage =
There are a couple of modes in which H2O can work.
* With arguments "-cp" it is producing Component Pascal output.
* With arguments "--preprocess" it just preprocesses source, outputting tokenised symbols (not very useful).
* With arguments "--preprocess" it just preprocesses source, outputting tokenised symbols (not very useful).
* With arguments "--preprocess --text" it preprocesses source, outputting  text.
* With arguments "--preprocess --text" it preprocesses source, outputting  text.
* Without arguments, it translates "C" definitions, producing Oberon-2 output.
* Without arguments, it translates "C" definitions, producing Oberon-2 output.


=== Processing C source code ===


== Processing C source code ==


There are few C files ready for trial usage in the folder with [[oo2c]] sources.


cd tests/h2o
  TestH2O misc/test.c
  TestH2O misc/test.c


=== Processing with outer H2O directive ===
The results will be two files: '''mod.Mod''' and '''test.Mod'''.


You have to tell H2O the name of the top level file. Normally, this file will include a H2O section with options and module definitions and finish with a #include directive that includes the actual source files that you want to translate.
{| class="wikitable" style="width: 100%; text-valign: top"
! Name
! C (sources)
! Oberon-2 (output)
|- valign="top"
| width="6%" | mod.h
| width="47%" |
typedef int T;
typedef int * pT;
| width="47%" |
MODULE mod [ INTERFACE "C" ];
IMPORT SYSTEM;
TYPE
  T* = LONGINT;
  pT* = POINTER TO ARRAY OF LONGINT;
END mod.
|- valign="top"
| test.c
|
#include "mod.h"
typedef T t1;
pT pt1;
int i1;
short int i2;
long int i3;
unsigned int i4;
unsigned short int i5;
unsigned long int i6;
unsigned u;
short s;
long l;
char c;
int * pi;
int ** ppi;
int f1(int x, int y);
int * f2(int x, int y);
int (* f3)(int x, int y);
void f4 (void);
void f5 (int, int, ...);
int ai [];
int * aai1 [3][3];
int (* aai2) [3][3];
struct A {
  int a:1;
  int b;
} sA1;
struct A sA2;
struct A * psA;
struct A * (* next)(struct A * p);
enum B { a=1, b, c } e1;
typedef unsigned long long I;
I i7;
volatile I i8;
volatile I i9, * const i10;
int a[sizeof(int)];
|
MODULE test [ INTERFACE "C" ];
IMPORT SYSTEM, mod;
CONST
  (* Constants occurring in enumeration 'B' *)
  a* = 1;
  b* = 2;
  c* = 3;
TYPE
  A_tag* = RECORD
    a* : LONGINT;
    b* : LONGINT;
  END;
  B_tag* = LONGINT (* enumerated type *);
  AutoPtrA_tag* = POINTER TO A_tag;
  t1* = mod.T;
  I* = HUGEINT;
VAR
  pt1* : mod.pT;
  i1* : LONGINT;
  i2* : INTEGER;
  i3* : LONGINT;
  i4* : LONGINT;
  i5* : INTEGER;
  i6* : LONGINT;
  u* : LONGINT;
  s* : INTEGER;
  l* : LONGINT;
  c* : CHAR;
  pi* : POINTER TO ARRAY OF LONGINT;
  ppi* : POINTER TO ARRAY OF POINTER TO ARRAY OF LONGINT;
  f3* : PROCEDURE(x : LONGINT; y : LONGINT) : LONGINT;
  ai* : ARRAY OF LONGINT;
  aai1* : ARRAY 3 OF ARRAY 3 OF POINTER TO ARRAY OF LONGINT;
  aai2* : POINTER TO ARRAY 3 OF ARRAY 3 OF LONGINT;
  sA1* : A_tag;
  sA2* : A_tag;
  psA* : POINTER TO A_tag;
  next* : PROCEDURE(p : AutoPtrA_tag) : AutoPtrA_tag;
  e1* : B_tag;
  i7* : I;
  i8* : I;
  i9* : I;
  i10* : POINTER TO ARRAY OF I;
  a* : ARRAY 4 OF LONGINT;
  PROCEDURE f1* (x : LONGINT; y : LONGINT) : LONGINT;
  PROCEDURE f2* (x : LONGINT; y : LONGINT) : mod.pT;
  PROCEDURE f4* ();
  PROCEDURE f5* (p0 : LONGINT; p1 : LONGINT);
END test.
|}


So if you want to translate test.c, you would make test.h2o that looks like this:
== Processing with outer H2O directive ==
 
Directive file have structure:


  H2O {
  H2O {
   ... translation options here ...
   ... translation options here ...
}
#include "topLevelFile"
If we want to translate '''test.c''' from previous example we would make '''test.h2o''' that looks like this:
H2O {
  OPTIONS {
    MapChar = "SHORTCHAR";
    MapShort = "SHORTINT";
    MapLong = "INTEGER";
    MapLongLong = "LONGINT";
    MapFloat = "SHORTREAL";
    MapDouble = "REAL";
    MapPointer = "ANYPTR";
  }
  MODULE "test" {
      LinkLib = "libtest.so";
  }
  MODULE "mod" {
      LinkLib = "libmod.so";
  }
  }
  }
  #include "test.c"
  #include "test.c"


To initiate the translation you would do:
To initiate the translation you would do:


  TestH2O test.h2o
  TestH2O misc/test.h2o
 
For making of Component Pascal import modules we can use key '''-cp'''.
 
TestH2O -cp misc/test.h2o
 
{| class="wikitable" style="width: 100%; text-valign: top"
! Name
! C (sources)
! Component Pascal (output)
|- valign="top"
| width="6%" | mod.h
| width="47%" |
typedef int T;
typedef int * pT;
| width="47%" |
MODULE mod [ "libmod.so" ];
IMPORT SYSTEM;
TYPE
  T* = INTEGER;
  pT* = POINTER TO ARRAY [untagged] OF INTEGER;
END mod.
|- valign="top"
| test.c
|
#include "mod.h"
typedef T t1;
pT pt1;
int i1;
short int i2;
long int i3;
unsigned int i4;
unsigned short int i5;
unsigned long int i6;
unsigned u;
short s;
long l;
char c;
int * pi;
int ** ppi;
int f1(int x, int y);
int * f2(int x, int y);
int (* f3)(int x, int y);
void f4 (void);
void f5 (int, int, ...);
int ai [];
int * aai1 [3][3];
int (* aai2) [3][3];
struct A {
  int a:1;
  int b;
} sA1;
struct A sA2;
struct A * psA;
struct A * (* next)(struct A * p);
enum B { a=1, b, c } e1;
typedef unsigned long long I;
I i7;
volatile I i8;
volatile I i9, * const i10;
int a[sizeof(int)];
|
MODULE test [ "libtest.so" ];
IMPORT SYSTEM, mod;
CONST
  (* Constants occurring in enumeration 'B' *)
  a* = 1;
  b* = 2;
  c* = 3;
TYPE
  A_tag* = RECORD [untagged]
    a* : INTEGER;
    b* : INTEGER;
  END;
  B_tag* = INTEGER (* enumerated type *);
  AutoPtrA_tag* = POINTER TO A_tag;
  t1* = mod.T;
  I* = HUGEINT;
VAR
  pt1* : mod.pT;
  i1* : INTEGER;
  i2* : SHORTINT;
  i3* : INTEGER;
  i4* : INTEGER;
  i5* : INTEGER;
  i6* : INTEGER;
  u* : INTEGER;
  s* : SHORTINT;
  l* : INTEGER;
  c* : SHORTCHAR;
  pi* : POINTER TO ARRAY [untagged] OF INTEGER;
  ppi* : POINTER TO ARRAY [untagged] OF
      POINTER TO ARRAY [untagged] OF INTEGER;
  f3* : PROCEDURE(x : INTEGER; y : INTEGER) : INTEGER;
  ai* : ARRAY [untagged] OF INTEGER;
  aai1* : ARRAY [untagged] 3 OF ARRAY [untagged] 3 OF
      POINTER TO ARRAY [untagged] OF INTEGER;
  aai2* : POINTER TO ARRAY [untagged] 3 OF
      ARRAY [untagged] 3 OF INTEGER;
  sA1* : A_tag;
  sA2* : A_tag;
  psA* : POINTER TO A_tag;
  next* : PROCEDURE(p : AutoPtrA_tag) : AutoPtrA_tag;
  e1* : B_tag;
  i7* : I;
  i8* : I;
  i9* : I;
  i10* : POINTER TO ARRAY [untagged] OF I;
  a* : ARRAY [untagged] 4 OF INTEGER;
  PROCEDURE f1* (x : INTEGER; y : INTEGER) : INTEGER;
  PROCEDURE f2* (x : INTEGER; y : INTEGER) : mod.pT;
  PROCEDURE f4* ();
  PROCEDURE f5* (p0 : INTEGER; p1 : INTEGER);
END test.
|}


For included modules, the behaviour depends on the type of include. If you do:
 
For included modules, the behavior depends on the type of include. If you do:
   #include <mod.h>
   #include <mod.h>
it looks in the search path specified by the Include option. If you do:
it looks in the search path specified by the Include option. If you do:
Line 105: Line 396:


Each "VARIANT" directive specifies how to translate particular symbols. As you would know, there are many ways of interpreting C declarations, and the default rules don't always work. For example:
Each "VARIANT" directive specifies how to translate particular symbols. As you would know, there are many ways of interpreting C declarations, and the default rules don't always work. For example:
  f(char * arg);
f(char * arg);
could be:
could be:
  PROCEDURE f (arg : POINTER TO ARRAY OF CHAR);
PROCEDURE f (arg : POINTER TO ARRAY OF CHAR);
  PROCEDURE f (arg : ARRAY OF CHAR);
PROCEDURE f (arg : ARRAY OF CHAR);
  PROCEDURE f (VAR arg : ARRAY OF CHAR);
PROCEDURE f (VAR arg : ARRAY OF CHAR);
  PROCEDURE f (VAR arg : CHAR);
PROCEDURE f (VAR arg : CHAR);


So VARIANT directives allow you to place particular interpretations on  the "C" declarations. Normally, you can see some specific patterns, but  it varies from API to API.
So VARIANT directives allow you to place particular interpretations on  the "C" declarations. Normally, you can see some specific patterns, but  it varies from API to API.
Line 122: Line 413:
Strings or symbols use OOC's regexp string format. Basically, ".*"  matches an string of characters, "$" matches the end of a string, and  "[]" matches one of a set of characters.
Strings or symbols use OOC's regexp string format. Basically, ".*"  matches an string of characters, "$" matches the end of a string, and  "[]" matches one of a set of characters.


Examples:
===Examples:===


  "gl.*v$".params : ARRAY;
"gl.*v$".params : ARRAY;
This means any symbol (here, procedure) starting with "gl" and ending  with "v" has its "params" parameter interpreted as an array.
This means any symbol (here, procedure) starting with "gl" and ending  with "v" has its "params" parameter interpreted as an array.


  "gl.*Matrix[fd]$"[0] : ARRAY;
"gl.*Matrix[fd]$"[0] : ARRAY;
This means any symbol starting with "gl" and ending with "Matrixf" or  "Matrixd" has its first parameter interpreted as an array.
This means any symbol starting with "gl" and ending with "Matrixf" or  "Matrixd" has its first parameter interpreted as an array.


  "String$" : CSTRING POINTER;
"String$" : CSTRING POINTER;
This means that the type "String" is to be interpreted as a POINTER to a  C string (in OOC, it assigns the "CSTRING" attribute to the pointer,  which means that you can use a string literal or CHAR array for this type).
This means that the type "String" is to be interpreted as a POINTER to a  C string (in OOC, it assigns the "CSTRING" attribute to the pointer,  which means that you can use a string literal or CHAR array for this type).


  "glutInit$".argcp : VAR;
"glutInit$".argcp : VAR;
This means that the "argcp" parameter of function "glutInit" is to be  treated as a VAR parameter.
This means that the "argcp" parameter of function "glutInit" is to be  treated as a VAR parameter.


  "cvRelease[^D].*$"[0] : VAR;
"cvRelease[^D].*$"[0] : VAR;
This means that symbols starting "cvRelease" followed by any character  EXCEPT "D" has its first parameter interpreted as a VAR parameter.
This means that symbols starting "cvRelease" followed by any character  EXCEPT "D" has its first parameter interpreted as a VAR parameter.
== Complex examples ==
[[Media:Interfaces.tar.gz]]

Latest revision as of 16:26, 5 November 2019

H2O — is the tool for making Oberon and Component Pascal import modules from C header files.

Intro and Credits

H2O (Header to Oberon) is a tool for creating Oberon interface modules from C-Header files for foreign libraries. It has been created by Stewart Greenhill around 2001 for use with the Optimizing Oberon Compiler OOC/oo2c, which in turn has been created by Michael van Acken end of the 1990. Ability to create interface modules for Component Pascal has been implemented by Bernhard Treutwein end of 2006 and fed back into the cvs tree at sourceforge by Stewart Greenhill in March, 2007.

Installation

The H2O sources are distributed with oo2c compiler. The oo2c compiler is/must be used for building H2O.

Linux

1. Download binary distribution and install it: https://sourceforge.net/projects/ooc/files/ooc2/2.1.11/

./configure
sudo make install

2. Download last sources from: https://github.com/Spirit-of-Oberon/oo2c

git clone https://github.com/Spirit-of-Oberon/oo2c

3. Compile last version of oo2c from repository:

cd oo2c
make cvsclean
./configure
. ENV
make $OOC_DEV_ROOT/oo2crc-install.xml
oo2c -M --config oo2crc-install.xml oo2c
sudo make install BOOTSTRAP_COMPILER=bin/oo2c

4. Compilation of H2O

oo2c -M src/TestH2O.Mod
sudo cp bin/TestH2O /usr/bin/TestH2O

Windows

H2O can be run on windows with Cygwin.

The example of built distribution you can find here.

Download

Usage

There are a couple of modes in which H2O can work.

  • With arguments "-cp" it is producing Component Pascal output.
  • With arguments "--preprocess" it just preprocesses source, outputting tokenised symbols (not very useful).
  • With arguments "--preprocess --text" it preprocesses source, outputting text.
  • Without arguments, it translates "C" definitions, producing Oberon-2 output.


Processing C source code

There are few C files ready for trial usage in the folder with oo2c sources.

cd tests/h2o
TestH2O misc/test.c

The results will be two files: mod.Mod and test.Mod.

Name C (sources) Oberon-2 (output)
mod.h
typedef int T;
typedef int * pT;
MODULE mod [ INTERFACE "C" ];

IMPORT SYSTEM;
TYPE
  T* = LONGINT;
  pT* = POINTER TO ARRAY OF LONGINT;
END mod.
test.c
#include "mod.h"

typedef T t1;
pT pt1;

int i1;
short int i2;
long int i3;
unsigned int i4;
unsigned short int i5;
unsigned long int i6;

unsigned u;
short s;
long l;
char c;

int * pi;
int ** ppi;

int f1(int x, int y);
int * f2(int x, int y);
int (* f3)(int x, int y);
void f4 (void);
void f5 (int, int, ...);

int ai [];
int * aai1 [3][3];
int (* aai2) [3][3];

struct A {
  int a:1;
  int b;
} sA1;

struct A sA2;
struct A * psA;

struct A * (* next)(struct A * p);

enum B { a=1, b, c } e1;

typedef unsigned long long I;

I i7;
volatile I i8;
volatile I i9, * const i10;
int a[sizeof(int)];
MODULE test [ INTERFACE "C" ];

IMPORT SYSTEM, mod;
CONST
  (* Constants occurring in enumeration 'B' *)
  a* = 1;
  b* = 2;
  c* = 3;
TYPE
  A_tag* = RECORD 
    a* : LONGINT;
    b* : LONGINT;
  END;
  B_tag* = LONGINT (* enumerated type *);
  AutoPtrA_tag* = POINTER TO A_tag;
  t1* = mod.T;
  I* = HUGEINT;
VAR
  pt1* : mod.pT;
  i1* : LONGINT;
  i2* : INTEGER;
  i3* : LONGINT;
  i4* : LONGINT;
  i5* : INTEGER;
  i6* : LONGINT;
  u* : LONGINT;
  s* : INTEGER;
  l* : LONGINT;
  c* : CHAR;
  pi* : POINTER TO ARRAY OF LONGINT;
  ppi* : POINTER TO ARRAY OF POINTER TO ARRAY OF LONGINT;
  f3* : PROCEDURE(x : LONGINT; y : LONGINT) : LONGINT;
  ai* : ARRAY OF LONGINT;
  aai1* : ARRAY 3 OF ARRAY 3 OF POINTER TO ARRAY OF LONGINT;
  aai2* : POINTER TO ARRAY 3 OF ARRAY 3 OF LONGINT;
  sA1* : A_tag;
  sA2* : A_tag;
  psA* : POINTER TO A_tag;
  next* : PROCEDURE(p : AutoPtrA_tag) : AutoPtrA_tag;
  e1* : B_tag;
  i7* : I;
  i8* : I;
  i9* : I;
  i10* : POINTER TO ARRAY OF I;
  a* : ARRAY 4 OF LONGINT;
  PROCEDURE f1* (x : LONGINT; y : LONGINT) : LONGINT;
  PROCEDURE f2* (x : LONGINT; y : LONGINT) : mod.pT;
  PROCEDURE f4* ();
  PROCEDURE f5* (p0 : LONGINT; p1 : LONGINT);
END test.

Processing with outer H2O directive

Directive file have structure:

H2O {
  ... translation options here ...
}
#include "topLevelFile"

If we want to translate test.c from previous example we would make test.h2o that looks like this:

H2O {
  OPTIONS {
    MapChar = "SHORTCHAR";
    MapShort = "SHORTINT";
    MapLong = "INTEGER";
    MapLongLong = "LONGINT";
    MapFloat = "SHORTREAL";
    MapDouble = "REAL";
    MapPointer = "ANYPTR";
  }

  MODULE "test" {
      LinkLib = "libtest.so";
  }

  MODULE "mod" {
      LinkLib = "libmod.so";
  }
}
#include "test.c"


To initiate the translation you would do:

TestH2O misc/test.h2o

For making of Component Pascal import modules we can use key -cp.

TestH2O -cp misc/test.h2o
Name C (sources) Component Pascal (output)
mod.h
typedef int T;
typedef int * pT;
MODULE mod [ "libmod.so" ];

IMPORT SYSTEM;
TYPE
  T* = INTEGER;
  pT* = POINTER TO ARRAY [untagged] OF INTEGER;
END mod.
test.c
#include "mod.h"

typedef T t1;
pT pt1;

int i1;
short int i2;
long int i3;
unsigned int i4;
unsigned short int i5;
unsigned long int i6;

unsigned u;
short s;
long l;
char c;

int * pi;
int ** ppi;

int f1(int x, int y);
int * f2(int x, int y);
int (* f3)(int x, int y);
void f4 (void);
void f5 (int, int, ...);

int ai [];
int * aai1 [3][3];
int (* aai2) [3][3];

struct A {
  int a:1;
  int b;
} sA1;

struct A sA2;
struct A * psA;

struct A * (* next)(struct A * p);

enum B { a=1, b, c } e1;

typedef unsigned long long I;

I i7;
volatile I i8;
volatile I i9, * const i10;
int a[sizeof(int)];
MODULE test [ "libtest.so" ];

IMPORT SYSTEM, mod;
CONST
  (* Constants occurring in enumeration 'B' *)
  a* = 1;
  b* = 2;
  c* = 3;
TYPE
  A_tag* = RECORD [untagged] 
    a* : INTEGER;
    b* : INTEGER;
  END;
  B_tag* = INTEGER (* enumerated type *);
  AutoPtrA_tag* = POINTER TO A_tag;
  t1* = mod.T;
  I* = HUGEINT;
VAR
  pt1* : mod.pT;
  i1* : INTEGER;
  i2* : SHORTINT;
  i3* : INTEGER;
  i4* : INTEGER;
  i5* : INTEGER;
  i6* : INTEGER;
  u* : INTEGER;
  s* : SHORTINT;
  l* : INTEGER;
  c* : SHORTCHAR;
  pi* : POINTER TO ARRAY [untagged] OF INTEGER;
  ppi* : POINTER TO ARRAY [untagged] OF
     POINTER TO ARRAY [untagged] OF INTEGER;
  f3* : PROCEDURE(x : INTEGER; y : INTEGER) : INTEGER;
  ai* : ARRAY [untagged] OF INTEGER;
  aai1* : ARRAY [untagged] 3 OF ARRAY [untagged] 3 OF
     POINTER TO ARRAY [untagged] OF INTEGER;
  aai2* : POINTER TO ARRAY [untagged] 3 OF
     ARRAY [untagged] 3 OF INTEGER;
  sA1* : A_tag;
  sA2* : A_tag;
  psA* : POINTER TO A_tag;
  next* : PROCEDURE(p : AutoPtrA_tag) : AutoPtrA_tag;
  e1* : B_tag;
  i7* : I;
  i8* : I;
  i9* : I;
  i10* : POINTER TO ARRAY [untagged] OF I;
  a* : ARRAY [untagged] 4 OF INTEGER;
  PROCEDURE f1* (x : INTEGER; y : INTEGER) : INTEGER;
  PROCEDURE f2* (x : INTEGER; y : INTEGER) : mod.pT;
  PROCEDURE f4* ();
  PROCEDURE f5* (p0 : INTEGER; p1 : INTEGER);
END test.


For included modules, the behavior depends on the type of include. If you do:

 #include <mod.h>

it looks in the search path specified by the Include option. If you do:

 #include "mod.h"

it looks in the same directory as the file that does the #include.


The "OPTIONS" directive is global to the translation, and includes things like:

  • OutputDirectory — where to put the generated module files
  • Include — list of paths to get include files
  • Exclude — list of files to not include (#include ignored)
  • AutoPrefix — prefix for auto-generated type names (default "Auto")
  • TagSuffix — suffix to be added to structure tags (default "_tag")
  • RenameProcedures — when set to "1" (the default) renames procedures using module "StripPrefix" specification.
  • RenameVariables — when set to "1" (default is "0", since this is unsupported in OOC V2) renames variables using module "StripPrefix" specification.
  • ModuleSuffix — suffix for module file names (default "Mod").

In this section, you can also specify the type mappings for scalar types:

  OPTION symbol          C type                Default output type
  ----------------------------------------------------------------
  MapChar                "char"                "CHAR"
  MapUnsignedChar        "unsigned char"       "CHAR"
  MapShort               "short"               "INTEGER"
  MapUnsignedShort       "unsigned short"      "INTEGER"
  MapLong                "long"                "LONGINT"
  MapUnsignedLong        "unsigned long"       "LONGINT"
  MapLongLong            "long long"           "HUGEINT"
  MapUnsignedLongLong    "unsigned long long"  "HUGEINT"
  MapFloat               "float"               "REAL"
  MapDouble              "double"              "LONGREAL"
  MapLongDouble          "long double"         "LONGDOUBLE"
  MapPointer             "void *"              "SYSTEM.PTR"
  MapEnum                "enum ..."            "LONGINT"
  MapVoid                "void"                "C_VOID"

Each "MODULE" directive controls how to treat the named module. The base module name comes from the name of the corresponding ".h" file. Options per module include:

  • OutputName — Output name for this module (defaults to header name)
  • StripPrefix — list of prefixes to be removed from symbol names
  • LinkLib, LinkFile, LinkFramework — specifies libraries, files and frameworks to link to this module (OOC-specific directive)
  • Prolog — "C" definitions to be processed at the start of this module
  • Epilog — "C" definitions to be processed at the end of this module
  • Merge — when set to "1", causes all files included by this module to be declared within this module, rather than in separate modules.

Each "VARIANT" directive specifies how to translate particular symbols. As you would know, there are many ways of interpreting C declarations, and the default rules don't always work. For example:

f(char * arg);

could be:

PROCEDURE f (arg : POINTER TO ARRAY OF CHAR);
PROCEDURE f (arg : ARRAY OF CHAR);
PROCEDURE f (VAR arg : ARRAY OF CHAR);
PROCEDURE f (VAR arg : CHAR);

So VARIANT directives allow you to place particular interpretations on the "C" declarations. Normally, you can see some specific patterns, but it varies from API to API.

The format of variants is a form of designator. The designators are composed of:

  • strings — which match the names of globally declared objects
  • [n] — which matches item <n> in a compound type or parameter list
  • ^ — which matches the item referenced by a pointer type
  • .symbol — which matches a named item in a type or paramter list

Strings or symbols use OOC's regexp string format. Basically, ".*" matches an string of characters, "$" matches the end of a string, and "[]" matches one of a set of characters.

Examples:

"gl.*v$".params : ARRAY;

This means any symbol (here, procedure) starting with "gl" and ending with "v" has its "params" parameter interpreted as an array.

"gl.*Matrix[fd]$"[0] : ARRAY;

This means any symbol starting with "gl" and ending with "Matrixf" or "Matrixd" has its first parameter interpreted as an array.

"String$" : CSTRING POINTER;

This means that the type "String" is to be interpreted as a POINTER to a C string (in OOC, it assigns the "CSTRING" attribute to the pointer, which means that you can use a string literal or CHAR array for this type).

"glutInit$".argcp : VAR;

This means that the "argcp" parameter of function "glutInit" is to be treated as a VAR parameter.

"cvRelease[^D].*$"[0] : VAR;

This means that symbols starting "cvRelease" followed by any character EXCEPT "D" has its first parameter interpreted as a VAR parameter.


Complex examples

Media:Interfaces.tar.gz