Recent

Author Topic: how to translate this from c  (Read 613 times)

Key-Real

  • Sr. Member
  • ****
  • Posts: 372
how to translate this from c
« on: October 07, 2024, 10:11:20 am »
Code: C  [Select][+][-]
  1. #define __va_rounded_size(TYPE)  \
  2.   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
  3.  
  4. #define va_start(AP, LASTARG)                                           \
  5.  (AP = ((char *)&(LASTARG) + __va_rounded_size(LASTARG)))
  6.  
  7. #define va_end(AP) AP = (char *)NULL
  8.  
  9. #define va_arg(AP, TYPE)                                                \
  10.  (AP = ((char *) (AP)) += __va_rounded_size (TYPE),                     \
  11.   *((TYPE *) ((char *) (AP) - __va_rounded_size (TYPE))))
  12.  
  13.  

Thaddy

  • Hero Member
  • *****
  • Posts: 16138
  • Censorship about opinions does not belong here.
Re: how to translate this from c
« Reply #1 on: October 07, 2024, 04:22:32 pm »
These are preprocessor macros with parameters.
Hard to translate without seeing how they are used.
preprocessor macros are typeless so to translate them into a typed pascal function depends on which type it is actually used.
I usually succeed on code for myself, but then I have all code so I can lookup how they are used.
IOW: not enough information.
« Last Edit: October 07, 2024, 04:24:27 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8000
Re: how to translate this from c
« Reply #2 on: October 07, 2024, 04:42:06 pm »
These are preprocessor macros with parameters.
Hard to translate without seeing how they are used.
preprocessor macros are typeless so to translate them into a typed pascal function depends on which type it is actually used.
I usually succeed on code for myself, but then I have all code so I can lookup how they are used.
IOW: not enough information.

This looks uncomfortably like low-level C varargs handling, in which case the older thread at https://forum.lazarus.freepascal.org/index.php/topic,53348.msg394506.html#msg394506 contains some pithy comments from Sven.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Seenkao

  • Hero Member
  • *****
  • Posts: 610
    • New ZenGL.
Re: how to translate this from c
« Reply #3 on: October 07, 2024, 07:00:32 pm »
Code: Pascal  [Select][+][-]
  1. function __va_rounded_size(_TYPE: longint): longint;
  2. begin
  3.   Result := (((SizeOf(_TYPE) + SizeOf(LongInt) - 1) / SizeOf(LongInt)) * SizeOf(LongInt));
  4. end;
  5.  
  6. procedure va_start(AP: PLongInt; LASTARG: function);
  7. begin
  8.   AP := (PChar(@LASTARG) + __va_rounded_size(LASTARG));
  9. end;
  10.  
  11. procedure va_end(AP: PLongInt);
  12. begin
  13.   AP := nil;
  14. end;
  15.  
  16. function va_arg(var AP: Pointer; var AType): Pointer;
  17. begin
  18.   AP := Pointer(Integer(AP) + __va_rounded_size(AType));
  19.   Result := Pointer(Integer(AP) - __va_rounded_size(AType));
  20. end;
  21.  

The translation is approximate. Errors are possible.

The last function was not translated by me.

And most likely, there should be functions everywhere, not procedures.

Code: Pascal  [Select][+][-]
  1. function va_start(AP: PLongInt; LASTARG: LongInt): LongInt;    // boolean???
  2. begin
  3.   Result : = (AP = (PChar(@LASTARG) + __va_rounded_size(LASTARG)));
  4. end;
  5.  
  6. function va_end(AP: PLongInt): LongInt;    // boolean???
  7. begin
  8.   result := AP = nil;
  9. end;
« Last Edit: October 07, 2024, 07:11:22 pm by Seenkao »
Rus: Стремлюсь к созданию минимальных и достаточно быстрых приложений.

Eng: I strive to create applications that are minimal and reasonably fast.
Working on ZenGL

440bx

  • Hero Member
  • *****
  • Posts: 4727
Re: how to translate this from c
« Reply #4 on: October 07, 2024, 07:23:39 pm »
There are no equivalent translations in Pascal for those macros, particularly considering that they are bitness dependent, i.e, sizeof(TYPE) can easily be a different size dependent on bitness.

In FPC to duplicate what those macros do requires taking a pointer to the first parameter and using pointer arithmetic to access the remaining parameters.  Actually, the code is fairly straightforward, the only "concern" is not accessing more parameters than there really are.  IOW, the called function must have a way of determining how many parameters were passed to it (if the number of parameters is variable, which isn't a problem in the case of "const" arrays in Pascal but can be a problem for a cdecl function.)

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16138
  • Censorship about opinions does not belong here.
Re: how to translate this from c
« Reply #5 on: October 07, 2024, 08:22:56 pm »
which isn't a problem in the case of "const" arrays in Pascal but can be a problem for a cdecl function.)
If the code is external that does not really matter, you can use varargs interchangeably with array of const parameters, only the call signature changes.(In Delphi this is not possible).
See https://www.freepascal.org/docs-html/ref/refsu97.html#:~:text=14.9.26%20varargs.%20This%20modifier%20can%20only%20be%20usedIt is even documented..  :D 8-)

You can use it with pascal too. Wll write and add short example later.
« Last Edit: October 07, 2024, 08:26:35 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5750
  • Compiler Developer
Re: how to translate this from c
« Reply #6 on: October 07, 2024, 09:07:29 pm »
Code: C  [Select][+][-]
  1. #define __va_rounded_size(TYPE)  \
  2.   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
  3.  
  4. #define va_start(AP, LASTARG)                                           \
  5.  (AP = ((char *)&(LASTARG) + __va_rounded_size(LASTARG)))
  6.  
  7. #define va_end(AP) AP = (char *)NULL
  8.  
  9. #define va_arg(AP, TYPE)                                                \
  10.  (AP = ((char *) (AP)) += __va_rounded_size (TYPE),                     \
  11.   *((TYPE *) ((char *) (AP) - __va_rounded_size (TYPE))))
  12.  
  13.  

Considering that these macros are for variable arguments (aka “varargs”) handling: it is not considered supported to implement C-style functions that handle varargs. And if you have to declare functions that take varargs then there should normally also be a variant of that C-style function that simply takes variant arguments and then you can simply implement as a function with cdecl; varargs; directives. If there isn't such a function then you're essentially out of luck.

Warfley

  • Hero Member
  • *****
  • Posts: 1734
Re: how to translate this from c
« Reply #7 on: October 07, 2024, 09:13:59 pm »
You can handle this with generics:
Code: Pascal  [Select][+][-]
  1. generic function __va_rounded_size<T>: SizeInt;inline;
  2. begin
  3.   Result := ((sizeof(T) + sizeof (cint) - 1) div sizeof (cint)) * sizeof (cint)
  4. end;
  5.  
  6. generic procedure va_start<T>(out AP: Pointer; var LastArg: T);inline;
  7. begin
  8.   AP := Pointer(@LastArg) + specialize __va_rounded_size<T>;
  9. end;
  10.  
  11. procedure va_end(out AP: Pointer);inline;
  12. begin
  13.   AP := nil;
  14. end;
  15.  
  16. generic function va_arg<T>(var AP: Pointer):T;inline;
  17. type
  18.   PT=^T;
  19. begin
  20.   Result := PT(AP)^;
  21.   Inc(AP, specialize __va_rounded_size<T>);
  22. end;
« Last Edit: October 07, 2024, 09:17:21 pm by Warfley »

MarkMLl

  • Hero Member
  • *****
  • Posts: 8000
Re: how to translate this from c
« Reply #8 on: October 07, 2024, 09:44:57 pm »
Thanks for that example @Warfley, useful. Which FPC versions support generics outside classes?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Warfley

  • Hero Member
  • *****
  • Posts: 1734
Re: how to translate this from c
« Reply #9 on: October 07, 2024, 09:47:00 pm »
Generic functions are supported since 3.2 I guess.

Thaddy

  • Hero Member
  • *****
  • Posts: 16138
  • Censorship about opinions does not belong here.
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8000
Re: how to translate this from c
« Reply #11 on: October 07, 2024, 10:03:27 pm »
Thanks, or possibly 3.2.0 as I think Thaddy is trying to say. I've been baiting Sven with a particular bit of language abuse for the last ten years or so and I think this gives me another excuse... >:-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018