Recent

Author Topic: .h to .pas / .pp -translation tools ( C to Pascal ) - ideas  (Read 9187 times)

Ahi

  • New member
  • *
  • Posts: 8
.h to .pas / .pp -translation tools ( C to Pascal ) - ideas
« on: April 07, 2008, 07:29:26 pm »
I tried the h2pas utility.

It handles structures fairly well, but fails miserably with function definitions.

I tried feeding it the "xine.h", but for every function (or function type/variable) definition, it doesn't understand, it generates junk into the result file.

We will not have a total solution to this, unless  someone can find, test, and integrate into a pascal -oriented tool some well written C parser. I downloaded the Elsa/Elkhound and tried to compile it, but on KUbuntu linux 7.10 gcc just produces heaps of error messages, and I don't know how to correct those.

If anyone is interested in investigating this route, here's a link:

http://www.cs.berkeley.edu/~smcpeak/elkhound/

Then I decided to write a new tool to handle C-language function definitions typically seen in .h -files.

My new tool can convert the "C" -line to a procedure / function definition, like this: (examples are taken from "xine.h")

example 1:

<L=001006>  char **xine_get_autoplay_mrls (xine_t *self,

function xine_get_autoplay_mrls(this:Pxine_t; plugin_id:Pchar; num_mrls:Pint):PPchar; cdecl;


example 2:

<L=000157>  xine_audio_port_t *xine_open_audio_driver (xine_t *self, const char *id,

function xine_open_audio_driver(this:Pxine_t; id:Pchar; data:Pvoid):Pxine_audio_port_t; cdecl;

How does it do this ?

It produces internally a stringlist like this (for example 2):

param0Name=this
param0BaseType=xine_t
param0PtrCount=1
param1Name=id
param1BaseType=char
param1PtrCount=1
param2Name=data
param2BaseType=void
param2PtrCount=1
routineType=function
routineName=xine_open_audio_driver
routineRetBaseType=xine_audio_port_t
routineRetPtrCount=1
parameterList=xine_t *self, char *id, void *data
funcParamCount=3
routineTail= XINE_PROTECTED;

----

The line numbers are produced internally by my program,which is interactive, and has a GUI written using Lazarus.

The line numbers are also behind the "magic" that when a function declaration is so long that those, who wrote the .h -file, decided to divide it into separate lines, my program counts both "(" and ")" and when it notices, that a line terminates but there are still open parenthesis, it automatically pulls in the next line from the ".h" -file, trims the line like:

ALine := trim(ALine);

and then concatenates it to the previous line and repeats this multiple times,if necessary.

I think my  program is a good start, but it sure isn't perfect. Here's some things that need to be resolved:

1. It should have a user -modifiable list of calling convention names and macros. The standard names could be built-in, but because C has the possibility to define macros, it is impossible to know how a C language writer decides to name his calling convention macros.

Any such macros must be removed prior to processing, because they would totally screw up my "C" parsing.

2. Type name handling:

Should I make automatic conversion if anything in the unit "Baseunix" and it's include files matches the namesused in "C" header files ?

If I got it right, is the idea this:

int -> cint
*int -> pcint
uint32 -> cuint32
*uint32 -> pcuint32

?

How about other (user-defined) types ?

and, structurally, Here's a  basic idea:

The way h2pas handles things, suffers from this:

say, that you're made an automatic conversion using h2pas.

Then you manually correct everything h2pas made wrong.

Now, if either a new version of the .h -file or h2pas comes available, you either cannot use it to avoid overwriting your manual changes or else you must redo all those changes.

What I suggest, is something like this (using the xine.h as an example)

there should be a conversion definition file (the program could create it if it doesn't yet exist), like this:

[general]
sourcefile=/usr/include/xine.h
destfile=xine.pas

ManualAdditions=xine_c2pas.pas

[types]
xine_t,P1=CO_xine

; CO = "C object"

char=Ansichar
char,P1=PChar
char,P2=PPChar

int=Integer
int,P1=PInteger

----


Now, this idea would need the definition of some extra pseudo-directives
 to be used in xine_c2pas.pas, so that the conversion tool would know in what part of the xine.pas it is producing,itneeds to insert what parts in xine_c2pas.pas.

should it be something like this:

{.C2PAS: <id=1> <state=start> <target=interface>  <subtarget=uses> <position=first>}
// put here something like this:
baseunix,
{.C2PAS: <id=1> <state=stop>}

{.C2PAS: <id=2> <state=start> <target=interface>  <subtarget=uses> <position=last>}
// put here something like this:
,c2pas_helper
{.C2PAS: <id=2> <state=stop>}

{.C2PAS: <id=3> <state=start> <target=interface>  <position=last>}
// put here something like this:
procedure LogDebugMessage(AMsg:String);
{.C2PAS: <id=3> <state=stop>}

{.C2PAS: <id=4> <state=start> <target=implementation>  <position=last>}
// put here something like this:
procedure LogDebugMessage(AMsg:String);
begin
  // code of LogDebugMessage goes here.

end;
{.C2PAS: <id=4> <state=stop>}

----

Any comments and new ideas for a better .h to .pas conversion tool ?
And how should one integrate this and the h2pas ?

Vincent Snijders

  • Administrator
  • Hero Member
  • *
  • Posts: 2661
    • My Lazarus wiki user page

avra

  • Hero Member
  • *****
  • Posts: 1739
    • Additional info
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib