Re: [fpc-pascal] Selecting Records with a variable
Am 20.12.2020 um 05:26 schrieb Jean SUZINEAU via fpc-pascal: I know you don't like objects, but maybe something like : Using modeswitch AdvancedRecords that also works with record types. And I'd suggest a case-statement as well. Anything else will only be slower or just as fragile. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] callback from c with varargs
El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: On 19/12/2020 22:35, Luca Olivetti via fpc-pascal wrote: I'm trying to use a c library where I can define a logging plugin. The c prototype for the callback is void (*log)(void *logContext, UA_LogLevel level, UA_LogCategory category, const char *msg, va_list args); however I couldn't find a way to define a suitable callback in fpc since the "array of const" construct is not allowed with cdecl without external, i.e. It is indeed not possible to implement a function with C varargs in FPC. I was afraid that's the answer :-( as an ugly workaround, I wrote a c library that vsnprintf msg and args to a buffer and then calls a pascal function with no varargs. It works but, as I said, it's ugly and I'd need to provide a .a for every platform I plan to use. Is there a better/simpler way (apart from asking the library developers to use a callback with no varargs)? Bye -- Luca ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Initialization of constant record member of pointer type
Am 14.12.2020 um 09:08 schrieb Marc Weustink via fpc-pascal: On 4-12-2020 13:01, LacaK via fpc-pascal wrote: Dňa 2.12.2020 o 16:09 Tomas Hajny via fpc-pascal napísal(a): On 2020-12-02 16:01, LacaK via fpc-pascal wrote: Dňa 2.12.2020 o 13:55 Tomas Hajny via fpc-pascal napísal(a): On 2020-12-01 11:39, Ladislav Karrach via fpc-pascal wrote: Because MyConst1 is not an *untyped* constant. Only untyped constants can be used in constant expressions (a pointer to something can be considered an untyped constant). The following might work though I did not test it: === code begin === const MyStr = 'abc' MyConst1: AnsiString = MyStr; MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); === code end === Yes it works, but I must define 2 constants (MyStr and MyConst1), which is not so nice ;-) It would be nice to have support for true constants: const MyConst1 = 'abc' ; MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); But may be that there are technical reasons why it is problematic (may be that true constants are stored in another memory locations, which can not be easy addressed) Yes, that's one of possible reasons. Regarding Length in constant value assignment - remember that Length is a function. In case of real constants, the call may be replaced by the compiler with the constant value. However typed constants may not be constant, so generic replacement throughout the source code at compile time is not possible (if it appears in the main body or some function, the length may already be changed to something else) and selective replacement may result in a behaviour not expected by the user. The only questionable case is IMHO the case of {$WRITEABLECONST OFF} - the compiler _might_ be able to perform the compile-time substition in that case (and thus allow using Length of such a constant in constant value assignment), but it doesn't do that in that case either apparently. Yes I have no problem with {$WRITEABLECONST OFF} if it will allow Length(). Somewhere I read (may be in Delphi documentation) that some intristic functions like Low(), High(), Pred() and also Length() etc. can be used in constant expressions because compiler can evaluate them if theirs arguments are also constants. Which is the case in my example. For now {$WRITEABLECONST OFF} does not help ;-) Yes, that's what I mentioned as well, but it might be changed for this particular case. You might create a ticket for that if Delphi allows to use Length that way; obviously, you might create such a ticket even if Delphi doesn't allow to do that. ;-) I checked it with older Delphi XE and it seems, that Delphi XE does not support Length() for typed constant also when {$WRITEABLECONST OFF} I do not believe that this will be accepted for FPC, so I don not open new feature request in bug tracker. On other side FPC developers read this mailing list so if they consider this as a useful/doable feature may be that someone will take look at it I just happened to write a construct like this (in Delphi): const X_0: array[0..4276] of SmallInt = (. MAP: array['0'..'9'] of TSomething = ( (Samples: @X_0; Count: Length(X_0)), ... That works, because the size of the *type* is known at compile time. String data however is not part of the type, it's content. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] callback from c with varargs
On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: > El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: >> It is indeed not possible to implement a function with C varargs in FPC. > > I was afraid that's the answer :-( > > as an ugly workaround, I wrote a c library that vsnprintf msg and args > to a buffer and then calls a pascal function with no varargs. > > It works but, as I said, it's ugly and I'd need to provide a .a for > every platform I plan to use. > > Is there a better/simpler way (apart from asking the library developers > to use a callback with no varargs)? No. Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] callback from c with varargs
On 2020-12-20 14:00, Jonas Maebe via fpc-pascal wrote: On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: It is indeed not possible to implement a function with C varargs in FPC. I was afraid that's the answer :-( as an ugly workaround, I wrote a c library that vsnprintf msg and args to a buffer and then calls a pascal function with no varargs. It works but, as I said, it's ugly and I'd need to provide a .a for every platform I plan to use. Is there a better/simpler way (apart from asking the library developers to use a callback with no varargs)? No. Not necessarily better than platform specific .a files mentioned by Luca, but the required playing with stack and registers should be still doable with a function written in assembler (inside the Pascal sources), shouldn't it? Tomas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
On 2020-12-20 11:56, Sven Barth via fpc-pascal wrote: Am 20.12.2020 um 05:26 schrieb Jean SUZINEAU via fpc-pascal: I know you don't like objects, but maybe something like : Using modeswitch AdvancedRecords that also works with record types. And I'd suggest a case-statement as well. Anything else will only be slower or just as fragile. If I understand the original case correctly, the wanted behaviour should be doable using (extended) RTTI, shouldn't it? Not that I'd know how to do that myself, but my (admittedly limited) understanding of RTTI suggests this as a possible solution, am I wrong? Tomas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] callback from c with varargs
On 20/12/2020 14:43, Tomas Hajny via fpc-pascal wrote: > On 2020-12-20 14:00, Jonas Maebe via fpc-pascal wrote: >> On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: >>> El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: It is indeed not possible to implement a function with C varargs in FPC. >>> >>> I was afraid that's the answer :-( >>> >>> as an ugly workaround, I wrote a c library that vsnprintf msg and args >>> to a buffer and then calls a pascal function with no varargs. >>> >>> It works but, as I said, it's ugly and I'd need to provide a .a for >>> every platform I plan to use. >>> >>> Is there a better/simpler way (apart from asking the library developers >>> to use a callback with no varargs)? >> >> No. > > Not necessarily better than platform specific .a files mentioned by > Luca, but the required playing with stack and registers should be still > doable with a function written in assembler (inside the Pascal sources), > shouldn't it? Yes, but you'd have to write it separately for each ABI. Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
On 12/19/20 10:02 PM, James Richters wrote: No, this is just a simplified example.. ok... The procedure will be working with dozens of records, so I need a way to call the procedure and specify which element of all the records to use... it will not be called for every element. in that case, the object (aka advanced records) form that Jean SUZINEAU presented would be what i would go for... they're great for things like this... i really enjoyed using them for BBS local message base storage formats years back... it made things so much easier... -- NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list where it belongs!* ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
Am 20.12.2020 um 14:47 schrieb Tomas Hajny via fpc-pascal: On 2020-12-20 11:56, Sven Barth via fpc-pascal wrote: Am 20.12.2020 um 05:26 schrieb Jean SUZINEAU via fpc-pascal: I know you don't like objects, but maybe something like : Using modeswitch AdvancedRecords that also works with record types. And I'd suggest a case-statement as well. Anything else will only be slower or just as fragile. If I understand the original case correctly, the wanted behaviour should be doable using (extended) RTTI, shouldn't it? Not that I'd know how to do that myself, but my (admittedly limited) understanding of RTTI suggests this as a possible solution, am I wrong? That's why I said "slower or just as fragile". The solution with the (not yet existing) extended RTTI would work, but it would be slower than the hardcoded case statement. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
What I’m hopping to accomplish isn't to get it to work... it's to consolidate a whole bunch of functions and procedures that are all exactly the same except for which axis I am working with... I have 9 possible Axis, X,Y,Z,W,L.R,A,B,C And I have Procedures: Procedure Move_X; Begin DoSomething(Variable1.X); DoAThing2; DoAThing3; ... Do more things that are the same all the time ... DoSomethingElse(Variable2.X); Variable3.X := SomeFormula(Variable4.X * ScaleFactor.X); ... 70 lines of things what work only with the .X variable ... End; Procedure Move_Y; Begin DoSomething(Variable1.Y); DoAThing2; DoAThing3; ... Do more things that are the same all the time ... DoSomethingElse(Variable2.Y); Variable3.Y := SomeFormula(Variable4.Y * ScaleFactor.Y); ... 70 lines of things what work only with the .Y variable ... End; ... Same thing 7 more times ... This is a tedious situation. If I want to change something I have to copy and paste it 9 times then go fix all the variables 9 times.. and it's easy to make a mistake. What I want is just one uncomplicated procedure: Procedure Move_It(Axis_Letter:Char); Begin DoSomething(Variable1. Axis_Letter); DoAThing2; DoAThing3; ... Do more things that are the same all the time ... DoSomethingElse(Variable2. Axis_Letter); Variable3. Axis_Letter := SomeFormula(Variable4. Axis_Letter * ScaleFactor. Axis_Letter); ... 70 lines of things what work only with the . Axis_Letter variable ... End; If I need a bunch of case statements, it's atcually worse than if I just have separate procedures. Procedure Move_It(Axis_Letter:Char); Begin Case Axis_Letter of X: Begin DoSomething(Variable1. X); End; Y: Begin DoSomething(Variable1. Y); End; ... 7 more times ... End; DoAThing2; DoAThing3; ... Do more things that are the same all the time ... Case Axis_Letter of X: Begin DoSomethingElse(Variable2. X); Variable3. X := SomeFormula(Variable4.X * ScaleFactor. X); End; Y: Begin DoSomethingElse(Variable2. Y); Variable3. Y := SomeFormula(Variable4.Y * ScaleFactor.Y); End; ... 7 more times ... ... 70 lines of things that all have a 9 case statements, sometimes I can combine them, most of the time not. ... End; James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
El 20/12/20 a les 16:02, James Richters via fpc-pascal ha escrit: What I’m hopping to accomplish isn't to get it to work... it's to consolidate a whole bunch of functions and procedures that are all exactly the same except for which axis I am working with... I have 9 possible Axis, X,Y,Z,W,L.R,A,B,C ... Same thing 7 more times ... This is a tedious situation. If I want to change something I have to copy and paste it 9 times then go fix all the variables 9 times.. and it's easy to make a mistake. Then change your data model. Instead of Axis_record = record X,Y,Z,A,B,C: Double; End; use AxisName = (X,Y,Z,A,B,C); Axis_record = array[AxisName] of double; then it's easy to do what you want. procedure DoSomething(var Axis:Axis_record; const which:AxisName); begin Axis[which]:=Axis[which]/2; end; Bye -- Luca ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
Thank you Luca, that will work much better for me! James -Original Message- From: fpc-pascal On Behalf Of Luca Olivetti via fpc-pascal Sent: Sunday, December 20, 2020 10:11 AM To: fpc-pascal@lists.freepascal.org Cc: Luca Olivetti Subject: Re: [fpc-pascal] Selecting Records with a variable El 20/12/20 a les 16:02, James Richters via fpc-pascal ha escrit: > What I’m hopping to accomplish isn't to get it to work... it's to > consolidate a whole bunch of functions and procedures that are all exactly > the same except for which axis I am working with... > > I have 9 possible Axis, X,Y,Z,W,L.R,A,B,C > ... > Same thing 7 more times > ... > > > This is a tedious situation. If I want to change something I have to copy > and paste it 9 times then go fix all the variables 9 times.. and it's easy to > make a mistake. Then change your data model. Instead of Axis_record = record X,Y,Z,A,B,C: Double; End; use AxisName = (X,Y,Z,A,B,C); Axis_record = array[AxisName] of double; then it's easy to do what you want. procedure DoSomething(var Axis:Axis_record; const which:AxisName); begin Axis[which]:=Axis[which]/2; end; Bye -- Luca ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] callback from c with varargs
El 20/12/20 a les 14:00, Jonas Maebe via fpc-pascal ha escrit: On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: It is indeed not possible to implement a function with C varargs in FPC. I was afraid that's the answer :-( as an ugly workaround, I wrote a c library that vsnprintf msg and args to a buffer and then calls a pascal function with no varargs. It works but, as I said, it's ugly and I'd need to provide a .a for every platform I plan to use. Is there a better/simpler way (apart from asking the library developers to use a callback with no varargs)? No. :-( Oh, well, that's life. Now I'm struggling to integrate my stub function under win32 (no problem with linux/64). The linker complains about Error: Undefined symbol: _vsnprintf Error: Undefined symbol: _ua_pascallog the first it's probably because it's missing some library (which?) but the second is defined in my program (and, as I said, it builds and works fine under linux/64) as: procedure ua_pascallog(logContext: Pointer; level: UA_LogLevel; category: UA_LogCategory; msg: PAnsiChar);cdecl;export; Any hint? Bye -- Luca ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
On 12/20/2020 7:11 AM, Luca Olivetti via fpc-pascal wrote: Then change your data model. Instead of Axis_record = record X,Y,Z,A,B,C : Double; End; use AxisName = (X,Y,Z,A,B,C); Axis_record = array[AxisName] of double; then it's easy to do what you want. procedure DoSomething(var Axis:Axis_record; const which:AxisName); begin Axis[which]:=Axis[which]/2; end; Bye +1 I think this is a typical example where properly thinking about a solution for a programming issue BEFORE going with what seems as the logical choice at first glance leads to a much simpler solution without coming up with all kinds of fancy workarounds... Ralf -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] TurboVision is reborn as FOSS (again)
On 12/19/20 6:35 PM, Liam Proven via fpc-pascal wrote: https://github.com/magiblot/tvision Someone enterprising could make a TurboPascal clone out of FPC. :-) Meh. FPC has had a Turbo Pascal-like console IDE for many years. It uses Free Vision, which is a pascal port of the C++ version of Turbo Vision (because Borland didn't release their Pascal version under a free/open source license). https://wiki.freepascal.org/Free_Vision#Turbo_Vision Nikolay ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
Yes, I was trying to keep my data structure, because there were thousands of occurrences .. This project has had that structure since Turbo Pascal back in the 80s when it only had 3 axis It seemed like a good way to have variables all with the same name, and back then it wasn't so bad to have repeated code, but now I have 9 axis and it's getting ridiculous.. once I realized that Arrays would allow me to simplify things greatly, it turned out to not be so bad to change it... just a bunch of global search and replaces and a little fixing here and there that actually made it cleaner, and the whole project has been changed over in a relatively short amount of time... and now I can start consolidating all those functions and procedures. It was way less work to just change it all to a better structure than it was to work around it. James >I think this is a typical example where properly thinking about a solution for >a programming issue BEFORE going with >what seems as the logical choice at first glance leads to a much simpler >solution without coming up with all kinds of fancy workarounds... ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
James, I remember going through some similar motions as you are. Looks like you are searching for a form of indexing your record fields. So many good suggestions, I had to join the fray and try something... My preferred approach would also be an ordinal type for the axes and a record variant, as already suggested. Objects and advanced records would be fine too. That way you get to keep both worlds while evolving your software to a more elegant approach along the lines of some of the suggested solutions. Here is something I tried on top of your example to make sure it actually works. program example1; Type Axis_Name=(anX,anY,anZ,anA,anB,anC); Axis_Array=array[Axis_Name] of Double; Axis_Record = Record X,Y,Z,A,B,C: Double; End; Axis_Record_variant = Record case boolean of false: (AxRec:Axis_Record); true: (AxArr:Axis_Array); End; Var AxisValueVar : Axis_Record_variant; AxisValue : Axis_Record absolute AxisValueVar.AxRec; //Instead of this: Procedure ShowAxis(Axisletter:Char); Begin If AxisLetter = 'X' Then Writeln(AxisValue.X); If AxisLetter = 'Y' Then Writeln(AxisValue.Y); If AxisLetter = 'Z' Then Writeln(AxisValue.Z); If AxisLetter = 'A' Then Writeln(AxisValue.A); If AxisLetter = 'B' Then Writeln(AxisValue.B); If AxisLetter = 'C' Then Writeln(AxisValue.C); End; //I would rather have something like this: Procedure ShowAxisVariant(AxisName:Axis_Name); Begin Writeln(AxisValueVar.AxArr[AxisName]); End; begin AxisValue.Z := 1234.5678; ShowAxis('Z'); ShowAxisVariant(anZ); end. On Sun, Dec 20, 2020 at 2:01 PM James Richters via fpc-pascal < fpc-pascal@lists.freepascal.org> wrote: > Yes, I was trying to keep my data structure, because there were thousands > of occurrences .. > This project has had that structure since Turbo Pascal back in the 80s > when it only had 3 axis > It seemed like a good way to have variables all with the same name, and > back then it wasn't so bad to have repeated code, > but now I have 9 axis and it's getting ridiculous.. once I realized that > Arrays would allow me to simplify things greatly, > it turned out to not be so bad to change it... just a bunch of global > search and replaces and a little fixing here and there that actually made > it cleaner, > and the whole project has been changed over in a relatively short amount > of time... and now I can start consolidating all those functions and > procedures. > It was way less work to just change it all to a better structure than it > was to work around it. > > James > > >I think this is a typical example where properly thinking about a > solution for a programming issue BEFORE going with > >what seems as the logical choice at first glance leads to a much simpler > solution without coming up with all kinds of fancy workarounds... > > ___ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Selecting Records with a variable
Le 20/12/2020 à 16:02, James Richters via fpc-pascal a écrit : If I need a bunch of case statements, it's atcually worse than if I just have separate procedures. No, in fact the case statement is written only once, in the implementation of TAxisRecord, and in procedure Move_It(Axis_Letter:Char); , you just use: DoSomething(Variable1.Value_from_Letter(Axis_Letter)); This said, I think that Lucas and Stefan ideas with "AxisName = (X,Y,Z,A,B,C);" are better than mine, because compilation will fail on a bad axis name, for example a typo with Axis[U]. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal