Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2018-02

Translating a small C program to pascal (on lazarus)

8 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Carlos E. R.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I want to translate a little Linux C program (600 lines) to pascal (so that I can then add my parts in comfort). I failed to find a good automated tool in Linux. I had a look here:

<http://wiki.freepascal.org/C_to_Pascal>

I used "OpenC2Pas" but there remains quite a lot to translate.

So I have to edit a lot, but my C is rusty.

I had this, in C (simplified to the sections I'm using so far):

#define SOCKET_COUNT 4
#define KEY_LEN 8

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

typedef enum
{
EG_PROTO_V20,
EG_PROTO_V21,
EG_PROTO_WLAN
} Protocol;

typedef enum
{
ACTION_ON,
ACTION_OFF,
ACTION_TOGGLE,
ACTION_LEFT,
ACTION_INVALID
} Action;

typedef struct
{
     Action socket[SOCKET_COUNT];
} Actions;

The automatic translation did:

#define SOCKET_COUNT 4
#define KEY_LEN 8

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

typedef enum
begin
EG_PROTO_V20,
EG_PROTO_V21,
EG_PROTO_WLAN
end; Protocol;

typedef enum
begin
ACTION_ON,
ACTION_OFF,
ACTION_TOGGLE,
ACTION_LEFT,
ACTION_INVALID
end; Action;

typedef struct
begin
     Action socket[SOCKET_COUNT];
end; Actions;

As you can see, it is quite incomplete.

The manual translation goes (I'm reading at
<http://rvelthuis.de/programs/convertpack.html> for info):

const
         SOCKET_COUNT        = 4;
         KEY_LEN             = 8;
type
Protocol = (EG_PROTO_V20, EG_PROTO_V21, EG_PROTO_WLAN);
Action = (ACTION_ON, ACTION_OFF, ACTION_TOGGLE, ACTION_LEFT, ACTION_INVALID);
_Actions = record
    socket: array[0..SOCKET_COUNT] of Action;
end;
Actions = _Actions;
//      typedef struct
//      {
//          Action socket[SOCKET_COUNT];
//      } Actions;

Now, the part I have doubts (one of many) is the later. In C it is:

typedef struct
{
     Action socket[SOCKET_COUNT];
} Actions;

The question is: is my translation correct?

_Actions = record
    socket: array[1..SOCKET_COUNT] of Action;
end;
Actions = _Actions;

It confuses me that a single item, an array, is defined inside the struct or record. I also have doubts about the translation of the array itself. Is it an array of Action?

You see, it doesn't help at all that my C is rusty.

Based in the section "Structs and unions" of the "Rudy's Delphi Corner" site I linked above. He says:

typedef struct _CERT_STORE_PROV_INFO {
     DWORD               cbSize;
     DWORD               cStoreProvFunc;
     void                **rgpvStoreProvFunc;
     HCERTSTOREPROV      hStoreProv;
     DWORD               dwStoreProvFlags;
     HCRYPTOIDFUNCADDR   hStoreProvFuncAddr2;
} CERT_STORE_PROV_INFO, *PCERT_STORE_PROV_INFO;

This results in:

  PCertStoreProvInfo = ^TCertStoreProvInfo;
   {$EXTERNALSYM _CERT_STORE_PROV_INFO}
   _CERT_STORE_PROV_INFO = record
     cbSize: DWORD;
     cStoreProvFunc: DWORD;
     rgpvStoreProvFunc: PPointer;
     hStoreProv: HCERTSTOREPROV;
     dwStoreProvFlags: DWORD;
     hStoreProvFuncAddr2: HCRYPTOIDFUNCADDR;
   end;
   {$EXTERNALSYM CERT_STORE_PROV_INFO}
   CERT_STORE_PROV_INFO = _CERT_STORE_PROV_INFO;
   {$EXTERNALSYM PCERT_STORE_PROV_INFO}
   PCERT_STORE_PROV_INFO = ^_CERT_STORE_PROV_INFO;
   TCertStoreProvInfo = _CERT_STORE_PROV_INFO;

Then, the next part I'll have to translate is this:

typedef struct
{
     uint8_t octets[KEY_LEN];
} Key;
typedef struct
{
     /* since the protocol is little-endian, low word comes first */
     uint16_t loword;
     uint16_t hiword;
} __attribute__((__packed__)) Res;

First, I have to find the equivalence of uint8_t, otherwise it is very similar to the first struct. Then comes uint16_t. And then, the last line:

__attribute__((__packed__)) Res;

Probably it is just a packed record.

Maybe it will all be too complicated, and I should instead call the C program from my Pascal program in the command line so that it does its thing. It would indeed be faster to code.

- --
Cheers,
Carlos E. R.
(from openSUSE 42.3 x86_64 "Malachite" at Telcontar) -----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iEYEARECAAYFAlqTFAgACgkQtTMYHG2NR9VuYACdHUodKSCy5maqrpRk1VaGwI1m EkwAnjGHLfMsOfEB4v38adCY7grvEmij
=4pSm
-----END PGP SIGNATURE-----

Reply by email

Mark Morgan Lloyd
to Carlos E. R.
Carlos E. R. wrote 8 lines
-----BEGIN PGP SIGNED MESSAGE-----Hash: SHA1 Hi, I want to translate a little Linux C program (600 lines) to pascal (so that I can then add my parts in comfort). I failed to find a good automated tool in Linux. I had a look here: <http://wiki.freepascal.org/C_to_Pascal> I used "OpenC2Pas" but there remains quite a lot to translate.

etc. Presumably the original looks something like
https://github.com/unterwulf/egctl/blob/master/egctl.c

I've just been through a comparable exercise writing a utility to program a Logitech G600 gamer's mouse, and my suggestion would be to use Wireshark etc. to get an understanding of the messages going over the network then to transcribe the bits of the program you need into Pascal manually.

Assuming that since you're asking on the Lazarus ML you're putting together a GUI to control the device you probably won't want roughly half of the original code which is using C-style string operations to read a configuration file.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Carlos E. R.
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote
On 25/02/18 20:00, Carlos E. R. via Lazarus wrote:
Show quoted text 9 lines
> Hi, > I want to translate a little Linux C program (600 lines) to pascal (so > that I can then add my parts in comfort). I failed to find a good > automated tool in Linux. I had a look here: > <http://wiki.freepascal.org/C_to_Pascal> > I used "OpenC2Pas" but there remains quite a lot to translate. etc. Presumably the original looks something like https://github.com/unterwulf/egctl/blob/master/egctl.c

Absolutely! :-)

How did you find out that fast?

Show quoted text 5 lines
I've just been through a comparable exercise writing a utility to program a Logitech G600 gamer's mouse, and my suggestion would be to use Wireshark etc. to get an understanding of the messages going over the network then to transcribe the bits of the program you need into Pascal manually.

I don't think I have the skill set for that. I guess that the author of that code, Vitaly Sinilin, had the Windows SDK for the device (a power strip controllable and programmable via Ethernet, LAN or WAN) and did a translation to Linux of the Windows command line tool. The SDK comes with the CD when purchasing the power strip, but the box I bought on Amazon had none. Perhaps it can be downloaded for free (I did not look yet), but anyway, it is for Windows (and probably C).

Assuming that since you're asking on the Lazarus ML you're putting together a GUI to control the device you probably won't want roughly half of the original code which is using C-style string operations to read a configuration file.

No, I'm not writing a GUI, I'm attempting to write a daemon. :-)

I have a router that hangs randomly, and I can't replace it because it is ISP supplied with a complex configuration. So the idea is to ping the router and when it goes silent power cycle it. I have tested the idea, I can power a socket off from Linux using that utility, and then a programmed schedule switches it back on on the 00 seconds mark (the power strip syncs via NTP). The period can be programmed to anything, but currently it is set to every minute.

So first I have to handle that powering off some seconds before the "00" mark, then I have to add the ping, wait for router come back alive, log the event, update the dynamic dns, email me, and go back to watch.

Of course, I could do it all from a bash script, maybe easier. But I want to have a go at doing it in Pascal first. :-)

The funny thing is, I programmed for a living in C two decades ago, I was good. It seems I fave forgotten most of it. :-}

I hopped to find people here familiar with C to pas translation. I also did this type of things long ago... I translated some windows api headers to pascal back then.

Cheers / Saludos, Carlos E. R. (from 42.2 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180225/ccb742e4/attachment.sig>

Reply by email

Giuliano Colla
to Carlos E. R.: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I want to translate a little Linux C…

Il 25/02/2018 20:52, Carlos E. R. via Lazarus ha scritto:

I want to translate a little Linux C program (600 lines) to pascal (so that I can then add my parts in comfort). I failed to find a good automated tool in Linux. I had a look here:

Did you consider h2pas (which comes with fpc/Lazarus)? It's only intended to translate C headers to Pascal, but it makes a good job on this.

You can only use it to translate declarations, but once declarations are in Pascal, converting the code becomes much easier.

Giuliano

Reply by email

Carlos E. R.
to Giuliano Colla
Giuliano Colla wrote 12 lines
Il 25/02/2018 20:52, Carlos E. R. via Lazarus ha scritto: > I want to translate a little Linux C program (600 lines) to pascal (so > that I can then add my parts in comfort). I failed to find a good > automated tool in Linux. I had a look here: Did you consider h2pas (which comes with fpc/Lazarus)? It's only intended to translate C headers to Pascal, but it makes a good job on this. You can only use it to translate declarations, but once declarations are in Pascal, converting the code becomes much easier.

Ah! I didn't realize it could translate the declarations on a .c file, I thought it was only for .h files.

I just had a quick test, but... I'll have to read on it, the quick test crashes:

cer at Telcontar:~/bin/lazarus/mios/egctl> h2pas egctl.c at line 49 error : syntax error
at line 82 error : syntax error
An unhandled exception occurred at $00000000004089F2: EAccessViolation: Access violation
$00000000004089F2

cer at Telcontar:~/bin/lazarus/mios/egctl>

It did some translation, though:

-rw-r--r-- 1 cer users 0 Feb 26 03:36 ext2.tmp -rw-r--r-- 1 cer users 0 Feb 26 03:36 ext.tmp -rw-r--r-- 1 cer users 1579 Feb 26 03:36 ext3.tmp

The last file contains a translation till it crashed:

{$include <arpa/inet.h>}
...
  const
    TASK_LEN = 4;
    STATCRYP_LEN = 4;
    CTRLCRYP_LEN = 4;
    KEY_LEN = 8;
...
    SOCKET_COUNT = 4;
(* error
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
in define line 49 *)
    type
      Protocol = (EG_PROTO_V20,EG_PROTO_V21,EG_PROTO_WLAN
        );
      Action = (ACTION_ON,ACTION_OFF,ACTION_TOGGLE,ACTION_LEFT,
        ACTION_INVALID);
      Actions = record
          socket : array[0..(SOCKET_COUNT)-1] of Action;
        end;
      Key = record
          octets : array[0..(KEY_LEN)-1] of uint8_t;
        end;
    { since the protocol is little-endian, low word comes first  }

and here it crashes.

Cheers / Saludos, Carlos E. R. (from 42.2 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180226/ecf6c09c/attachment.sig>

Reply by email

Giuliano Colla
to Carlos E. R.

Il 26/02/2018 03:51, Carlos E. R. via Lazarus ha scritto:

Show quoted text 5 lines
Ah! I didn't realize it could translate the declarations on a .c file, I thought it was only for .h files. I just had a quick test, but... I'll have to read on it, the quick test crashes:

Well actually it is only for .h files, but as .h files are just declaration, it can handle a good part of the job.

Most likely it crashes because it doesn't know how to handle the code after the declarations.

What I'd do in your place would be to create a sort of .h file, by cutting away from the original source everything except the declarations, and translate it.

Then translating the code, when you have all declarations in place becomes much easier, the bulk of it being sort of:

replace all "{" with "begin"

replace all "}" with "end;"

replace all "0x" with "$"

and so on.

Giuliano

Reply by email

Carlos E. R.
to Giuliano Colla
Giuliano Colla wrote 12 lines
Il 26/02/2018 03:51, Carlos E. R. via Lazarus ha scritto: > Ah!  I didn't realize it could translate the declarations on a .c file, > I thought it was only for .h files. > > I just had a quick test, but... I'll have to read on it, the quick test > crashes: Well actually it is only for .h files, but as .h files are just declaration, it can handle a good part of the job. Most likely it crashes because it doesn't know how to handle the code after the declarations.

That can't explain a "EAccessViolation: Access violation". It could be a syntax error, yes, but never an exception. And it happens before the code part.

<https://www.freepascal.org/docs-html/rtl/sysutils/eaccessviolation.html>

Description

EAccessViolation is raised when the OS reports an Access Violation, i.e. when invalid memory is accessed.

What I'd do in your place would be to create a sort of .h file, by cutting away from the original source everything except the declarations, and translate it.

Yes, I'll do that.

Show quoted text 10 lines
Then translating the code, when you have all declarations in place becomes much easier, the bulk of it being sort of: replace all "{" with "begin" replace all "}" with "end;" replace all "0x" with "$" and so on.

Actually, the OpenC2Pas program did a lot of that :-)

Hopefully, one program translates most of the declarations, and another a good part of the code :-)

Cheers / Saludos, Carlos E. R. (from 42.3 x86_64 "Malachite" (Minas Tirith)) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 213 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180226/cf593f0c/attachment-0001.sig>

Reply by email

R0b0t1
to Carlos E. R.
Carlos E. R. wrote
Hopefully, one program translates most of the declarations, and another a good part of the code :-)

I doubt that in general a program exists to do what you want, as it would require having a front end for the C language and then something close to a decompiler for Pascal.

However, this thread did clue me in to h2pas, which I hope can be used to convert STM's header files for the embedded target project.

Cheers,
R0b0t1

Reply by email