Re: [fpc-pascal] LLVM crash

2023-08-15 Thread Benito van der Zander via fpc-pascal

Hi
On which platform? When I compile the attached tt.pp file with -gw4 
-Clfsanitize=address (LLVM 13, Debian 11, x86-64) and then run it, I 
get the output in tt.txt. It includes line information.


You could try lldb instead of gdb, although gdb should also be able to 
handle debug information generated by LLVM. 


Ubuntu 22.04, LLVM 13

Nothing helps.


only some units are affected

Actually, now I see the warnings during compilation

Assembling xquery
mismatched subprogram between llvm.dbg.addr variable and !dbg attachment
inlinable function call in a function with debug info must have a !dbg 
location
  invoke void 
@"\01XQUERY$_$IXQVALUE_$__$$_$finalize$IXQVALUE"(%typ.XQUERY.IXQValue* 
%reg.1_200)

  to label %.Lj9768 unwind label %.Lj9743
.
 call void @llvm.dbg.addr(metadata %typ.SYSTEM.TRTLCriticalSection* 
%tmp.1, metadata !48637, metadata !DIExpression()), !dbg !48773

label %0
void ()* @"\01XQUERY_$$_finalize$"
!48637 = !DILocalVariable(name: "_zero_$SYSTEM_$$_TRTLCRITICALSECTION", 
scope: !48635, file: !3, line: 10567, type: !1260)
!48635 = distinct !DISubprogram(name: "XQUERY_$$_init$", scope: !3, 
file: !3, line: 3506, type: !7606, scopeLine: 10504, spFlags: 
DISPFlagDefinition, unit: !2)

!48773 = !DILocation(line: 10570, column: 1, scope: !48772)
!48772 = distinct !DISubprogram(name: "XQUERY_$$_finalize$", scope: !3, 
file: !3, line: 10570, type: !7606, scopeLine: 10570, spFlags: 
DISPFlagDefinition, unit: !2)
warning: ignoring invalid debug info in 
/home/theo/lib/fpc/x86_64-linux/xquery.ll




The first appears to be caused by my managed operator patch

Then there is the default issue 
https://gitlab.com/freepascal.org/fpc/source/-/issues/40395

(and you have fixed it while I was still writing this mail)

Then this:

https://gitlab.com/freepascal.org/fpc/source/-/issues/40280 is causing a 
stack corruption


https://gitlab.com/freepascal.org/fpc/source/-/issues/40392 is causing a 
heap corruption



Cheers,
Benito
On 11.08.23 12:57, Jonas Maebe via fpc-pascal wrote:

On 10/08/2023 23:27, Benito van der Zander via fpc-pascal wrote:

i tried to run my program under LLVM (from july fpc)  and it crashes?

Program received signal SIGSEGV, Segmentation fault.
0x0042e5f1in SYSTEM_$$_SYSGETMEM_FIXED$QWORD$$POINTER()
(gdb) bt
#0 0x0042e5f1in SYSTEM_$$_SYSGETMEM_FIXED$QWORD$$POINTER()
#1 0x0041b92ain fpc_ansistr_setlength()
#2 0x00558d52in RESETBUFFER(ABUFFER=0x7fffd560, 
BASECAPACITY=130) at bbutils.pas:1650
#3 INIT(ABUFFER=0x7fffd560, BASECAPACITY=130, AENCODING=65001) at 
bbutils.pas:1639
#4 STRDECODEHTMLENTITIES(result=0x0, P=, L=130, 
ENCODING=65001, FLAGS=...) at bbutils.pas:5527


anyone has seen sysgetmem crash before?


It suggests heap corruption.


Perhaps that is exactly the kind of things ASAN was supposed to detect.


Possibly, yes.

But with ASAN, I get an error somewhere entirely else. And I do not 
understand it, because the function is shown as ~ 5000 lines of 
assembly.


How can I see the mixed code with disassemble /rm in gdb? I tried to 
call fpc -gl, -gs and -gw, and nothing helps


On which platform? When I compile the attached tt.pp file with -gw4 
-Clfsanitize=address (LLVM 13, Debian 11, x86-64) and then run it, I 
get the output in tt.txt. It includes line information.


You could try lldb instead of gdb, although gdb should also be able to 
handle debug information generated by LLVM.



And there are a lot of weird ASAN calls for trivial movs. Like:

0x006f577c<+22204>: 48 8b bb c8 00 00 00 
movrdi,QWORDPTR[rbx+0xc8]
0x006f5783<+22211>: e8 18 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>
0x006f5788<+22216>: e8 13 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>
0x006f578d<+1>: e8 0e cc d0 ff 
call0x4023a0<__asan_report_load8@plt>
0x006f5792<+6>: e8 09 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>

0x006f5797<+22231>: 48 89 c7 movrdi,rax
0x006f579a<+22234>: e8 01 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>

0x006f579f<+22239>: 48 89 cf movrdi,rcx
0x006f57a2<+22242>: e8 09 ca d0 ff 
call0x4021b0<__asan_report_store8@plt>


Are they supposed to be there?


These are generated by LLVM's own code generator, so yes.


Jonas

___
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] LLVM LTO

2023-08-15 Thread Benito van der Zander via fpc-pascal

Hi

-Clflto -Clflto-no-system -k-fuse-ld=gold -k-plugin=/path/to/LLVMgold.so 


that helped, but I have to do it without -Clflto-no-system, or it gives 
an error


Then I could run my unit tests:

FPC alone: 25 seconds
LLVM: 21 seconds
LLVM LTO: 20 seconds

does not seem to matter much

Cheers,
Benito
On 11.08.23 12:46, Jonas Maebe via fpc-pascal wrote:

On 10/08/2023 17:06, Benito van der Zander via fpc-pascal wrote:

I tried to use the LLVM Link-Time-Optimization, -Clflto


I should update the wiki page. Under Debian 11, I can tell FPC to use 
gold with lto by specifying the following command line parameters: 
-Clflto -Clflto-no-system -k-fuse-ld=gold -k-plugin=/path/to/LLVMgold.so


Note that compiling the FPC RTL with LTO currently doesn't work under 
Linux, because LLVM does not rename local labels in pure assembler 
procedures when doing so, resulting in duplicate labels.


It works fine when compiling FPC and its units normally, and then only 
using LTO for your program.



Jonas
___
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


[fpc-pascal] LLVM LTO

2023-08-11 Thread Benito van der Zander via fpc-pascal

Hallo,

I tried to use the LLVM Link-Time-Optimization, -Clflto

I compiled/installed fpc llvm with a separate prefix, which was already 
difficult to set up


Then the default linker did not want to link it.

The wiki says to use the gold linker. I do not know how to change the 
linker in fpc.cfg. If I use -XP, it changes the prefix. But the gold 
linker is named ld.gold, so one would need an option to change the suffix.


But I called it directly with ld.gold -T link43117.res.

It says

>ld.gold: error: link43117.res:372:8: syntax error, unexpected STRING


I deleted the last line INSERT AFTER .data;. Then it says

>ld.gold: internal error in read_script_file, at ../../gold/script.cc:1638


around here: 
https://sourceware.org/git/?p=binutils-gdb.git;a=blame;f=gold/script.cc;h=d30a4d73991f083f3a1459db06ded4234959fe91;hb=HEAD#l1638



So I gave up on that and tried the llvm linker. ld.lld -T link43117.res


It links, but when I start the program, it gives

Starting program: /home/benito/tmp/a.out

Program received signal SIGSEGV, Segmentation fault.
0xin ??()
(gdb) bt
#0 0xin ??()
#1 0xin ??()




Viele Grüße,

Benito

SEARCH_DIR("/lib/x86_64-linux-gnu/")
SEARCH_DIR("/usr/lib/x86_64-linux-gnu/")
SEARCH_DIR("/lib64/")
SEARCH_DIR("/lib/")
SEARCH_DIR("/usr/lib64/")
SEARCH_DIR("/usr/lib/")
SEARCH_DIR("/usr/lib/thunderbird-addons/")
SEARCH_DIR("/usr/lib/modules/")
SEARCH_DIR("/usr/lib/maxima/")
SEARCH_DIR("/usr/lib/aspell/")
SEARCH_DIR("/usr/lib/gnome-shell/")
SEARCH_DIR("/usr/lib/binfmt-support/")
SEARCH_DIR("/usr/lib/udev/")
SEARCH_DIR("/usr/lib/gcc/")
SEARCH_DIR("/usr/lib/cups/")
SEARCH_DIR("/usr/lib/tmpfiles.d/")
SEARCH_DIR("/usr/lib/firewalld/")
SEARCH_DIR("/usr/lib/java-wrappers/")
SEARCH_DIR("/usr/lib/cryptsetup/")
SEARCH_DIR("/usr/lib/X11/")
SEARCH_DIR("/usr/lib/llvm-14/")
SEARCH_DIR("/usr/lib/cmake/")
SEARCH_DIR("/usr/lib/realmd/")
SEARCH_DIR("/usr/lib/klibc/")
SEARCH_DIR("/usr/lib/pulse-15.99.1+dfsg1/")
SEARCH_DIR("/usr/lib/sasl2/")
SEARCH_DIR("/usr/lib/git-core/")
SEARCH_DIR("/usr/lib/llvm-15/")
SEARCH_DIR("/usr/lib/girepository-1.0/")
SEARCH_DIR("/usr/lib/brltty/")
SEARCH_DIR("/usr/lib/ubiquity/")
SEARCH_DIR("/usr/lib/kernel/")
SEARCH_DIR("/usr/lib/tc/")
SEARCH_DIR("/usr/lib/linux-sound-base/")
SEARCH_DIR("/usr/lib/gcc-cross/")
SEARCH_DIR("/usr/lib/qt5/")
SEARCH_DIR("/usr/lib/bfd-plugins/")
SEARCH_DIR("/usr/lib/crda/")
SEARCH_DIR("/usr/lib/gnome-settings-daemon-42/")
SEARCH_DIR("/usr/lib/GNUstep/")
SEARCH_DIR("/usr/lib/update-notifier/")
SEARCH_DIR("/usr/lib/sysctl.d/")
SEARCH_DIR("/usr/lib/dbus-1.0/")
SEARCH_DIR("/usr/lib/ssl/")
SEARCH_DIR("/usr/lib/pam.d/")
SEARCH_DIR("/usr/lib/netplan/")
SEARCH_DIR("/usr/lib/recovery-mode/")
SEARCH_DIR("/usr/lib/valgrind/")
SEARCH_DIR("/usr/lib/lsb/")
SEARCH_DIR("/usr/lib/man-db/")
SEARCH_DIR("/usr/lib/p7zip/")
SEARCH_DIR("/usr/lib/gold-ld/")
SEARCH_DIR("/usr/lib/pppd/")
SEARCH_DIR("/usr/lib/gnome-settings-daemon-3.0/")
SEARCH_DIR("/usr/lib/hdparm/")
SEARCH_DIR("/usr/lib/binfmt.d/")
SEARCH_DIR("/usr/lib/ispell/")
SEARCH_DIR("/usr/lib/arm-none-eabi/")
SEARCH_DIR("/usr/lib/console-setup/")
SEARCH_DIR("/usr/lib/qemu/")
SEARCH_DIR("/usr/lib/rustlib/")
SEARCH_DIR("/usr/lib/dkms/")
SEARCH_DIR("/usr/lib/os-prober/")
SEARCH_DIR("/usr/lib/rhythmbox/")
SEARCH_DIR("/usr/lib/wine/")
SEARCH_DIR("/usr/lib/usrmerge/")
SEARCH_DIR("/usr/lib/openssh/")
SEARCH_DIR("/usr/lib/python2.7/")
SEARCH_DIR("/usr/lib/init/")
SEARCH_DIR("/usr/lib/locale/")
SEARCH_DIR("/usr/lib/python3.11/")
SEARCH_DIR("/usr/lib/pm-utils/")
SEARCH_DIR("/usr/lib/xserver-xorg-video-intel/")
SEARCH_DIR("/usr/lib/ipxe/")
SEARCH_DIR("/usr/lib/texinfo/")
SEARCH_DIR("/usr/lib/jellyfish1/")
SEARCH_DIR("/usr/lib/memtest86+/")
SEARCH_DIR("/usr/lib/gnupg/")
SEARCH_DIR("/usr/lib/llvm-9/")
SEARCH_DIR("/usr/lib/dpkg/")
SEARCH_DIR("/usr/lib/debug/")
SEARCH_DIR("/usr/lib/mozilla/")
SEARCH_DIR("/usr/lib/gnuplot/")
SEARCH_DIR("/usr/lib/llvm-12/")
SEARCH_DIR("/usr/lib/nvidia/")
SEARCH_DIR("/usr/lib/modules-load.d/")
SEARCH_DIR("/usr/lib/ubuntu-release-upgrader/")
SEARCH_DIR("/usr/lib/linux-boot-probes/")
SEARCH_DIR("/usr/lib/evolution-data-server/")
SEARCH_DIR("/usr/lib/firefox-addons/")
SEARCH_DIR("/usr/lib/software-properties/")
SEARCH_DIR("/usr/lib/environment.d/")
SEARCH_DIR("/usr/lib/openvpn/")
SEARCH_DIR("/usr/lib/systemd/")
SEARCH_DIR("/usr/lib/pkgconfig/")
SEARCH_DIR("/usr/lib/apparmor/")
SEARCH_DIR("/usr/lib/snapd/")
SEARCH_DIR("/usr/lib/xorg/")
SEARCH_DIR("/usr/lib/gnome-session/")
SEARCH_DIR("/usr/lib/ruby/")
SEARCH_DIR("/usr/lib/initramfs-tools/")
SEARCH_DIR("/usr/lib/python3.10/")
SEARCH_DIR("/usr/lib/GraphicsMagick-1.3.38/")
SEARCH_DIR("/usr/lib/pcmciautils/")
SEARCH_DIR("/usr/lib/apache2/")
SEARCH_DIR("/usr/lib/speech-dispatcher-modules/")
SEARCH_DIR("/usr/lib/lp_solve/")
SEARCH_DIR("/usr/lib/geeqie/")
SEARCH_DIR("/usr/lib/encfs/")
SEARCH_DIR("/usr/lib/libreoffice/")
SEARCH_DIR("/usr/lib/grub-legacy/")
SEARCH_DIR("/usr/lib/dh-elpa/")

[fpc-pascal] LLVM crash

2023-08-10 Thread Benito van der Zander via fpc-pascal

Hallo,

i tried to run my program under LLVM (from july fpc)  and it crashes?

Program received signal SIGSEGV, Segmentation fault.
0x0042e5f1in SYSTEM_$$_SYSGETMEM_FIXED$QWORD$$POINTER()
(gdb) bt
#0 0x0042e5f1in SYSTEM_$$_SYSGETMEM_FIXED$QWORD$$POINTER()
#1 0x0041b92ain fpc_ansistr_setlength()
#2 0x00558d52in RESETBUFFER(ABUFFER=0x7fffd560, 
BASECAPACITY=130) at bbutils.pas:1650
#3 INIT(ABUFFER=0x7fffd560, BASECAPACITY=130, AENCODING=65001) at 
bbutils.pas:1639
#4 STRDECODEHTMLENTITIES(result=0x0, P=, L=130, 
ENCODING=65001, FLAGS=...) at bbutils.pas:5527



anyone has seen sysgetmem crash before?


Perhaps that is exactly the kind of things ASAN was supposed to detect.

But with ASAN, I get an error somewhere entirely else. And I do not 
understand it, because the function is shown as ~ 5000 lines of assembly.


How can I see the mixed code with disassemble /rm in gdb? I tried to 
call fpc -gl, -gs and -gw, and nothing helps



And there are a lot of weird ASAN calls for trivial movs. Like:

0x006f577c<+22204>: 48 8b bb c8 00 00 00 movrdi,QWORDPTR[rbx+0xc8]
0x006f5783<+22211>: e8 18 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>
0x006f5788<+22216>: e8 13 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>
0x006f578d<+1>: e8 0e cc d0 ff 
call0x4023a0<__asan_report_load8@plt>
0x006f5792<+6>: e8 09 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>

0x006f5797<+22231>: 48 89 c7 movrdi,rax
0x006f579a<+22234>: e8 01 cc d0 ff 
call0x4023a0<__asan_report_load8@plt>

0x006f579f<+22239>: 48 89 cf movrdi,rcx
0x006f57a2<+22242>: e8 09 ca d0 ff 
call0x4021b0<__asan_report_store8@plt>



Are they supposed to be there?


Viele Grüße,

Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Freeing memory with exceptions

2023-05-25 Thread Benito van der Zander via fpc-pascal

Hi,



That 99.99% of people does use it, indicates they simply take the 
overhead because
of the advantages that the managed types offer. 


Or they simply do not know about the overhead

Like I was writing all my code on Windows 98, and never noticed any 
overhead, until I started running benchmarks on  Linux.


Bye,
Benito
On 25.05.23 07:58, Michael Van Canneyt via fpc-pascal wrote:



On Thu, 25 May 2023, Hairy Pixels via fpc-pascal wrote:




On May 24, 2023, at 10:11 PM, Sven Barth via fpc-pascal 
 wrote:


You must have $H+ on and those are AnsiStrings? Why is there 
exception handling involved with AnsiString? I guess it needs this 
just in case an exception is thrown somewhere in the call stack?


Because Ansi- and UnicodeString are managed types. *All* managed 
types managed string types, interfaces, Variants, managed records) 
must be finalized correctly even if an exception occurs.




That's a problem with exceptions then, they are baked into the language
and impose a cost on all managed types now even if we use them or 
not. Even disabling the implicit stack frames (forgot what it's 
called) doesn't

get around this right?


Why do you insist it is a problem ?

Simply don't use managed types and don't use exceptions if you don't 
like the
overhead they cause. It's still perfectly possible: avoid the sysutils 
unit

and you're all set. The system unit does not use exceptions.

That 99.99% of people does use it, indicates they simply take the 
overhead because

of the advantages that the managed types offer.

Which is not to say that FPC should not strive to minimize the overhead.
Conceivably there is some gain possible on non-windows platforms.

Michael.
___
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] Freeing memory with exceptions

2023-05-24 Thread Benito van der Zander via fpc-pascal

Hi



Then also run FPC/win32 in wine for a real comparison.



Or perhaps against modern C++ on Linux would also be a real comparison


FPC could at least inline fpc_setjmp in fpc_pushexceptaddr to make it 
only one function call.



These kinds of statements are counter-productive.


That is a very productive optimization idea



Cheers,
Benito
On 24.05.23 13:10, Marco van de Voort via fpc-pascal wrote:


On 24-5-2023 13:00, Benito van der Zander via fpc-pascal wrote:


It is weird that your code calls setjmp? Are you using a non Windows 
platform?  Comparisons with Delphi should be done on Windows where 
the exception systems match. Apples to Apples please.


It is FPC on Linux.

And Delphi 4 on Linux (in WINE)


Then also run FPC/win32 in wine for a real comparison.

 Even if it wants to do the Linux nonsense, FPC could at least inline 
fpc_setjmp in fpc_pushexceptaddr to make it only one function call.


I regret installing Linux. Everything worked better with Windows 98 
and Delphi 4


These kinds of statements are counter-productive.


___
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] Freeing memory with exceptions

2023-05-24 Thread Benito van der Zander via fpc-pascal

Hi,

It is weird that your code calls setjmp? Are you using a non Windows 
platform?  Comparisons with Delphi should be done on Windows where the 
exception systems match. Apples to Apples please.


It is FPC on Linux.

And Delphi 4 on Linux (in WINE)

Even if it wants to do the Linux nonsense, FPC could at least inline 
fpc_setjmp in fpc_pushexceptaddr to make it only one function call.



I regret installing Linux. Everything worked better with Windows 98 and 
Delphi 4



Sincerely,
Benito
On 24.05.23 10:14, Marco van de Voort via fpc-pascal wrote:


On 23-5-2023 12:44, Benito van der Zander via fpc-pascal wrote:

Hi,


Depends on your code. 



I wrote all my code in Delphi 4. From 1998 or so. I do not make new 
projects, only maintain old ones.


Delphi 4 felt much better.

Like take:

procedure test;
var s: string;
begin
  s:= 'abc';
end;



It is weird that your code calls setjmp? Are you using a non Windows 
platform?  Comparisons with Delphi should be done on Windows where the 
exception systems match. Apples to Apples please.



___
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] Freeing memory with exceptions

2023-05-22 Thread Benito van der Zander via fpc-pascal

Hi,



The compiler will do this wrapping anyway if you use ansistrings, so the
approach with e.g. a generic record will not cause a lot of overhead 
in most
cases. 


But using strings or anything similar causes a lot of overhead

It is really bad



Bye,
Benito
On 21.05.23 18:03, Michael Van Canneyt via fpc-pascal wrote:



On Sun, 21 May 2023, Hairy Pixels via fpc-pascal wrote:




On May 21, 2023, at 2:47 PM, Michael Van Canneyt via fpc-pascal 
 wrote:


Your example will leak memory in any case, even if there is no 
exception,

since you're not freeing the object anywhere..


doh, dumb example on my behalf.



Assuming the result of A is not used outside of Test, the following 
is the

only solution:

procedure Test;

var
A : TObject;
begin
 A:=TObject.Create;
 Try
   // call some code in other unit which raise an exception
   DoThis;
 finally
   A.Free
 end;
end;

You can try to use interfaces, they will be managed by the compiler.


This is what I was worried about, wrapping all functions or needing 
full ARC on all types. Very risk to opt in to this design I would 
say. I remain not a fan of exceptions. :)


They're used all over the place in the RTL and FCL, so you better take 
them

into account.

The compiler will do this wrapping anyway if you use ansistrings, so the
approach with e.g. a generic record will not cause a lot of overhead 
in most

cases.

Michael.
___
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


[fpc-pascal] pointer to char vs pchar

2023-03-24 Thread Benito van der Zander via fpc-pascal

Hallo,

why is a pointer to a char not a pchar (for type helpers)?


program Project1;
{$Mode objfpc}{$H+} {$ModeSwitch typehelpers}
type TPcharHelper = type helper for pchar
  function toString(length: integer): string;
end;

function TPcharHelper.toString(length: integer): string;
begin
  SetString(result, self, length);
end;

var c: char;
begin
  c := 'x';
  writeln((@c).toString(1)); //does not compile
  writeln(pchar(@c).toString(1));
end.

Bye,

Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Arguments gets corrupted with anonymous nested function

2022-09-07 Thread Benito van der Zander via fpc-pascal

Hi,

https://gitlab.com/freepascal.org/fpc/source/-/issues/38703 



I'm afraid that with -O4 it is by design.
-O4 enables -OoUNCERTAIN, and the documentation about -OoUNCERTAIN 
notes that:


“If uncertain optimizations are enabled, the CSE algorithm assumes that
— If something is written to a local/global register or a 
procedure/function parameter, this value doesn’t overwrite the value 
to which a pointer points.
— If something is written to memory pointed to by a pointer variable, 
this value doesn’t overwrite the value of a local/global variable or a 
procedure/function parameter.”




is it doing that? did it ever do that? It might break a lot of my code

But I cannot find any place in FPC where it is doing any OoUNCERTAIN 
optimizations


Best,
Benito
On 07.09.22 13:51, Peter B via fpc-pascal wrote:

I'm wondering if this is related to
https://gitlab.com/freepascal.org/fpc/source/-/issues/38703

That caused a parameter corruption in a standard function.
https://lists.freepascal.org/pipermail/fpc-pascal/2022-March/060361.html

Should be easy to check. Just try compiling with -O1


Cheers,
Peter
___
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] Compiler flag define or $IFOPT for optimizations

2022-06-03 Thread Benito van der Zander via fpc-pascal

Hi,
However, you can possibly solve it by always taking the options from 
an environment variable to the command line and then including 
contents of this command line to your sources. 


Unfortunately it is picking up all kinds of options from fpc.cfg and 
Lazarus.


Like in this case, I tried to disable range checking, and it is still 
enabled.



> You can introduce something like that yourself by always building all 
your sources from scratch, but then the solution outlined above should 
work for you.


I am setting up a build server that compiles the entire project from 
scratch on every commit.



Best,
Benito
On 28.05.22 14:34, Tomas Hajny via fpc-pascal wrote:

On 2022-05-28 13:44, Benito van der Zander via fpc-pascal wrote:


Hi,


I want to show how my program was compiled.

Now I have string like "FPC3.2.2 i386-Linux R+C+" from

  compiler := 'FPC' + {$INCLUDE %FPCVERSION%} + ' ' + {$INCLUDE
%FPCTargetCPU%}+'-'+{$INCLUDE %FPCTargetOS%}+ ' ' + {$IfOpt
R+}+'R+'{$endif} {$IfOpt S+}+'S+'{$endif} {$IfOpt O+}+'O+'{$endif}
{$IfOpt Q+}+'Q+'{$endif} {$IfOpt M+}+'M+'{$endif} {$IfOpt
C+}+'C+'{$endif};

But the optimization level (-O2 or -O1 ...) is missing.

Is there an IFOPT for that? Or a define with all the arguments


I don't think that there's such an option at the moment. However, you 
can possibly solve it by always taking the options from an environment 
variable to the command line and then including contents of this 
command line to your sources. I don't think that it makes much sense 
for the compiler to provide such an option, because unlike the 
compiler version, different options (including the optimization level) 
may be used for compilation of different units and there's no such a 
thing as a general optimization level valid for the complete compiled 
program from the compiler point of view. You can introduce something 
like that yourself by always building all your sources from scratch, 
but then the solution outlined above should work for you.


Tomas
___
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] Feature Announcement: Function References and Anonymous Functions

2022-05-28 Thread Benito van der Zander via fpc-pascal

Hi,


Sort((left, right) begin
 if left < right then
   result := -1
 else if left > right then
   result := 1
 else
   result := 0;
   end);


One could introduce the @ operator to get a reference to a block of code.

Sort( @(left, right) begin
if left < right then
  result := -1
else if left > right then
  result := 1
else
  result := 0;
  end);


The "result" variable is also ugly. You could make "if" an expression:

Sort( @(left, right) begin
result :=
  if left < right then -1
  else if left > right then 1
  else 0;
  end);


Then the begin end could be removed too. Make @:= an operator to turn an 
expression to a function


Sort( @(left, right) :=
   if left < right then -1
   else if left > right then 1
   else 0;
  );





Benito
On 28.05.22 08:47, Hairy Pixels via fpc-pascal wrote:

I’ve had some time to play with this now and my first piece of feedback is that 
given my experience with other languages, the most common usage of closures is 
by passing them as arguments to functions.

Compared to the other languages I’m using now I’d say that we should be 
inferring more of the context of the receiving function type and not requiring 
the programmer to type out the full function header as in the example below 
(especially in the case there are no local variables declared).

Sort(function(left, right: Double): integer
   begin
 if left < right then
   result := -1
 else if left > right then
   result := 1
 else
   result := 0;
   end);

It’s hard to say what the best policy is for Pascal but some combination of the 
function/procedure keyword, parameter type names and return type could be 
omitted or shortened in various ways.

Given we know the function type from the parameter list we could infer most of 
the information and provide a more limited set of syntax, for example like this 
(Swift like):

Sort((left, right) begin
 if left < right then
   result := -1
 else if left > right then
   result := 1
 else
   result := 0;
   end);

There is even the most limited shorthand (from Swift again) which uses token to 
represent the arguments as they are ordered.

Sort(begin
   if $0 < right then
 result := -1
   else if $0 > $1 then
 result := 1
   else
 result := 0;
 end);

Regards,
Ryan Joseph

___
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


[fpc-pascal] Compiler flag define or $IFOPT for optimizations

2022-05-28 Thread Benito van der Zander via fpc-pascal

Hallo,


I want to show how my program was compiled.

Now I have string like "FPC3.2.2 i386-Linux R+C+" from


  compiler := 'FPC' + {$INCLUDE %FPCVERSION%} + ' ' + {$INCLUDE 
%FPCTargetCPU%}+'-'+{$INCLUDE %FPCTargetOS%}+ ' ' + {$IfOpt 
R+}+'R+'{$endif} {$IfOpt S+}+'S+'{$endif} {$IfOpt O+}+'O+'{$endif} 
{$IfOpt Q+}+'Q+'{$endif} {$IfOpt M+}+'M+'{$endif} {$IfOpt C+}+'C+'{$endif};


But the optimization level (-O2 or -O1 ...) is missing.

Is there an IFOPT for that? Or a define with all the arguments


Bye,

Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] StrToInt is using ShortString buffer?

2022-01-14 Thread Benito van der Zander via fpc-pascal

Hi,


I don’t see what the problem with a shortstring buffer is.. strtoint 
could not make use of an input string longer than 256 characters 
anyway, because the output integer could not have more than 19 digits 
anyway.. so an input string longer than this would be useless… just 
convert to a shortstring and to strtoint.




the input might be


Re: [fpc-pascal] StrToInt is using ShortString buffer?

2022-01-12 Thread Benito van der Zander via fpc-pascal

Hi,



If it is correct: Can we skip using ShortString buffer and have e.g. 
'common' PChar base function for AnsiString/ShortString? 


I keep arguing for that as well

You can always create such a function yourself,  gain experience using 
it, and share the source with us.




I wrote that for you:

https://forum.lazarus.freepascal.org/index.php/topic,55472.msg414973.html#msg414973

https://github.com/benibela/bbutils/blob/master/bbutils.pas#L3446-L3601

Cheers,
Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Where can I find working code for xidel and dependencies

2022-01-11 Thread Benito van der Zander via fpc-pascal

Hi,


xquery.internals.common.pas(434,80) Fatal: Cannot find PasDblStrUtils used by
xquery.internals.common of package internettools.



that is here: github.com/bero1985/pasdblstrutils

Download src/PasDblStrUtils.pas. Do not clone the repository when you 
have a slow internet connection



It only became a dependency last week. You could look at the last 
internettools commits and undo them



And you will also need FLRE, which has a fork here: github.com/benibela/flre

Linux also requires Synapse


After trying to fix this I decided to search for binaries and found them here:
https://sourceforge.net/projects/videlibri/files/Xidel/Xidel%200.9.8/
These I believe are all for PC style CPU:s


Do not use those, they are 3 years old

The recent builds are: at 
https://sourceforge.net/projects/videlibri/files/Xidel/Xidel%20development/



Best,
Benito
On 09.01.22 18:43, Bo Berglund via fpc-pascal wrote:

On Sun, 09 Jan 2022 17:46:00 +0100, Bo Berglund via fpc-pascal
 wrote:


I have been adviced to use xidel to analyze the content of websites, so when
searcing for it I found that it is a FreePascal utility with the sources on
GitHub.
https://www.videlibri.de/xidel.html
So I tried to get it going.
Buit when I tried to compile the utility using Lazarus 2.0.12/FPC 3.2.0 it
failed to find package "internettools".
After some searching I found it on GitHub:
https://github.com/benibela/internettools

But still no luck, I get errors when trying to compile the internettools
package

UPDATE:
---
After trying to fix this I decided to search for binaries and found them here:
https://sourceforge.net/projects/videlibri/files/Xidel/Xidel%200.9.8/
These I believe are all for PC style CPU:s

So I will not need to build it myself unless I want to run it on a RaspberryPi
of course.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Traits Proposal

2021-02-18 Thread Benito van der Zander via fpc-pascal

Hi,

The problem is that, we like OOP inheritance  but when we extend classes we are 
forced into a single hierarchy.


there is another way to extend classes without inheritance: type helpers

Traits are like reverse type helpers. With the type helper you first 
declare the class and then the extending helper.


=== code begin ===
type
  TTest = class(TObject)
  public
    procedure test(a: integer);
  end;
  TTrait = class helper for TTest
    procedure test2;
  end;

procedure TTest.test(a: integer);
begin
  writeln(a);
end;

procedure TTrait.test2;
begin
  test(10);
end;
//var x: ttest2;
//x.test2

=== code end ===


With traits you could first define the extension, and then the class:

=== code begin ===
type
  TTrait = trait
    procedure test2;
  end;
  TTest = class(TObject, TTrait)
  public
    procedure test(a: integer);
  end;

procedure TTest.test(a: integer);
begin
  writeln(a);
end;

procedure TTrait.test2;
begin
  test(10); //here it needs to know the test function exist. Perhaps 
declare it in the the trait, too?

end;
//var x: ttest2;
//x.test2
=== code end ===

But otherwise, it looks exactly the same

Perhaps the type helper code could be reused for traits





Cheers,
Benito


On 18.02.21 04:37, Ryan Joseph via fpc-pascal wrote:




On Feb 17, 2021, at 9:59 AM, Adriaan van Os via fpc-pascal 
 wrote:

1. multiple inheritance is nice to have, but it has the big issue that the 
inheritance tree becomes an inheritance graph and that makes overrules 
ambiguent.
2. interfaces don't have this issue with multiple inheritance, because they 
just declare, not implement
3. but that is also the weakness of interfaces,  as we don't want to 
reimplement the same code each time
4. so, we really want an multiple-inheritance graph at the declaration level 
with clear tree-like unambigous inheritance paths at the implementation level
5. thus, the idea is to "push-in" implementation code into an interface that 
integrates fully at the declaration level but is independent at the implementation level.

I would say that's right.

The problem is that, we like OOP inheritance  but when we extend classes we are forced 
into a single hierarchy. We could use existing delegation patterns and dot-notation  like 
obj.helper.DoSomething or by breaking out entirely and using plain functions  but then we 
lose some of what makes OOP nice, which is, simply saying 
"something.DoFunction". It may be trivial in terms of typing but it's elegant 
and in my opinion clean code which is not tedious to write makes happy and more 
productive.


Here's a more practical example but there are other possibilities for 
composition patterns (I'l think of examples later). I copied this from the RTL 
and made some changes. Assume you have this hierarchy and you want to add some 
methods/data to JPEG and GIF images but not TIFF and PNG (they have some 
special compression needs or something like that). What we would do now is 
probably just dump them into TCustomBitmap (and bloat TIFF/PNG)  or make 
another subclass just to store the extra methods (which is useless besides 
being a method store for 2 specific other classes).

What I want with traits is that I can extend those 2 classes with specific 
functionality, still retain the object-orientedness of the syntax and not get 
trapped trying to inject stuff into a hierarchy where it doesn't really belong 
anyways.


TTIFFBitmap   TPNGBitmap   TJPEGBitmap   TGIFBitmap
 |
 TCustomBitmap
 |
 TRasterImage
 |
 TGraphic
 |
 TPersistent
 |
 TObject


Regards,
Ryan Joseph

___
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] interfaces and smartpointers [was Traits Proposal]

2021-02-17 Thread Benito van der Zander via fpc-pascal


On 17.02.21 21:43, Ryan Joseph via fpc-pascal wrote:

So where is your 10% performance hit coming from then?

on init:

InitInterfacePointers or TInterfacedObject.AfterConstruction?



I benchmarked it years ago, I do not remember the details.

But InitInterfacePointers was bad. Just look at it:

  procedure InitInterfacePointers(objclass: tclass;instance : pointer);

    var
  ovmt: PVmt;
  i: longint;
  intftable: pinterfacetable;
  Res: pinterfaceentry;
    begin
  ovmt := PVmt(objclass);
  while assigned(ovmt) and {$ifdef VER3_0}(ovmt^.vIntfTable <> 
@emptyintf){$else}assigned(ovmt^.vIntfTable){$endif} do

    begin
  intftable:=ovmt^.vIntfTable;
  {$ifdef VER3_0}
  if assigned(intftable) then
  {$endif VER3_0}
  begin
    i:=intftable^.EntryCount;
Res:=@intftable^.Entries[0];
    while i>0 do begin
  if Res^.IType = etStandard then
    ppointer(@(pbyte(instance)[Res^.IOffset]))^:=
  pointer(Res^.VTable);
  inc(Res);
  dec(i);
    end;
  end;
  ovmt:=ovmt^.vParent;
    end;
    end;


But reusing objects avoids calling all the functions from create. (but 
reusing is also expensive, besides the memory increase, it needs a free 
list and thread safe handling of the head of the list)




otherwise, during the wrapper function? As Sven pointed out the ref counting 
happens with records operators also. ARC is general may just be slow if you 
implement it everywhere.



The wrapper function was not included in the 10%


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] interfaces and smartpointers [was Traits Proposal]

2021-02-17 Thread Benito van der Zander via fpc-pascal

Hi,


1) Implicit cast to ITest which does a runtime lookup (but there's interface 
name so no string comparison like Supports?)


just open the disassembler window in Lazarus and single step through all 
the instructions. Then you see everything


create alone calls a bunch of methods:

TInterfacedObject.NewInstance
TObject.NewInstance
getmem
TObject.InitInstance
fillchar
InitInterfacePointers
fpc_pushexceptaddr (on linux only?)
fpc_setjmp
TInterfacedObject.AfterConstruction


(interfaces with TInterfacedObject are even worse than implementing the 
interface yourself )


The implicit casting is very fast, a single assembly instruction:

add    $0x20,%rsi

But then it also calls fpc_intf_assign for reference counting



2) calling "println" there is a call to a wrapper function (called "thunks")?


Yes. Basically the wrapper function casts the interface back to the 
class (sub    $0x20,%rdi) before calling the actual method. Because the 
class method assumes self is the class and not an interface





Bye,
Benito
On 17.02.21 17:37, Ryan Joseph via fpc-pascal wrote:



On Feb 17, 2021, at 8:27 AM, Benito van der Zander via fpc-pascal 
 wrote:

var c: ITest;
begin
   c := TTest.Create(123);
   c.println;

So this is where you're getting your performance penalties? Correct me if I'm 
wrong but two things happen here:

1) Implicit cast to ITest which does a runtime lookup (but there's interface 
name so no string comparison like Supports?)
2) calling "println" there is a call to a wrapper function (called "thunks")?

Regards,
Ryan Joseph

___
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] interfaces and smartpointers [was Traits Proposal]

2021-02-17 Thread Benito van der Zander via fpc-pascal

Hi,



(1) A record is not a pointer. So that would require some implicit 
referencing in the property


(2) If it was managed, it would be an allocation, so I don't 
understand this.



I am talking about replacing interfaces with an record.

For example this

/

type ITest = interface
  procedure println;
end;
TTest = class(TInterfacedObject, ITest)
  v: integer;
  constructor Create(av: integer);
  procedure println;
end;

constructor TTest.Create(av: integer);
begin
  v := av;
end;

procedure TTest.println;
begin
  writeln(v);
end;

var c: ITest;
begin
  c := TTest.Create(123);
  c.println;
/


would become:


/

type

TTestRec = class
  rc: Integer;
  v: integer;
  constructor Create(av: integer);
  procedure println;
end;
RTest = record
  ptr: TTestRec;
  procedure println; inline;
  class operator :=(c: TTestRec): RTest;
  class operator Initialize(var aRec: RTest);
  class operator finalize(var aRec: RTest);
  class operator AddRef(var aRec: RTest);
end;

constructor TTestRec.Create(av: integer);
begin
  v := av;
end;

procedure TTestRec.println;
begin
  writeln(v);
end;

procedure RTest.println;
begin
  ptr.println; //the wrapper function is inlined
end;

class operator RTest.:=(c: TTestRec): RTest;
begin
  result := default(RTest);
  result.ptr := c;
  if c <> nil then
    InterlockedIncrement(c.rc);
end;

class operator RTest.Initialize(var aRec: RTest);
begin
  aRec.ptr := nil;
end;

class operator RTest.finalize(var aRec: RTest);
begin
  if aRec.ptr <> nil then
    if InterlockedDecrement(aRec.ptr.rc) = 0 then
  aRec.ptr.Free;
end;

class operator RTest.AddRef(var aRec: RTest);
begin
  if aRec.ptr <> nil then
    InterlockedIncrement(aRec.ptr.rc);
end;

var
    r: RTest;
begin
  r := TTestRec.Create(123);
  r.println;
/

Or even replace the class with a record, too:


/

type
PTestRec2 = ^TTestRec2;
TTestRec2 = record
  rc: Integer;
  v: integer;
  class function Create(av: integer): PTestRec2; static;
  procedure println;
end;
RTest2 = record
  ptr: ^TTestRec2;
  procedure println; inline;
  class operator :=(c: PTestRec2): RTest2;
  class operator Initialize(var aRec: RTest2);
  class operator finalize(var aRec: RTest2);
  class operator AddRef(var aRec: RTest2);
end;

class function TTestRec2.Create(av: integer): PTestRec2;
begin
  new(result);
  result^.rc := 0;
  result^.v := av;
end;

procedure TTestRec2.println;
begin
  writeln(v);
end;

procedure RTest2.println;
begin
  ptr^.println;
end;

class operator RTest2.:=(c: PTestRec2): RTest2;
begin
  result := default(RTest2);
  result.ptr := c;
  if c <> nil then
    InterlockedIncrement(c^.rc);
end;

class operator RTest2.Initialize(var aRec: RTest2);
begin
  aRec.ptr := nil;
end;

class operator RTest2.finalize(var aRec: RTest2);
begin
  if aRec.ptr <> nil then
    if InterlockedDecrement(aRec.ptr^.rc) = 0 then
  dispose(aRec.ptr);
end;

class operator RTest2.AddRef(var aRec: RTest2);
begin
  if aRec.ptr <> nil then
    InterlockedIncrement(aRec.ptr^.rc);
end;
var
    r2: RTest2;
begin
  r2 := TTestRec2.Create(123);
  r2.println;
/




Not sure if it is actually faster. That needs to be investigated.

But it definitely helps with the memory usage:

  writeln(ttest.InstanceSize);
  writeln(ttestrec.InstanceSize);
  writeln(sizeof(ttestrec2));

40
16
8

With many small objects it should be faster just because it fits better 
in the cache.


Cheers,
Benito
On 17.02.21 14:31, Marco van de Voort via fpc-pascal wrote:


Op 2021-02-17 om 00:02 schreef Benito van der Zander via fpc-pascal:


And there often is a lot of unintentional deep copying. This is also 
why a property returning a record is fairly useless except for 
extremely small records like TPoint (and even that is not optimal no 


But a managed record to replace an interface, would only contain a 
single pointer/class ref. That can be copied fast


(1) A record is not a pointer. So that would require some implicit 
referencing in the property


(2) If it was managed, it would be an allocation, so I don't 
understand this.



___
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] Traits Proposal

2021-02-16 Thread Benito van der Zander via fpc-pascal

Hi,


And there often is a lot of unintentional deep copying. This is also 
why a property returning a record is fairly useless except for 
extremely small records like TPoint (and even that is not optimal no 


But a managed record to replace an interface, would only contain a 
single pointer/class ref. That can be copied fast




Bye,
Benito
On 16.02.21 21:49, Marco van de Voort via fpc-pascal wrote:


Op 2021-02-16 om 21:33 schreef Ryan Joseph via fpc-pascal:


On Feb 16, 2021, at 1:27 PM, Marco van de Voort via fpc-pascal 
 wrote:


And there often is a lot of unintentional deep copying. This is also 
why a property returning a record is fairly useless except for 
extremely small records like TPoint (and even that is not optimal no
deep copying? You mean from ref counted types like "array of" and 
ansistring?


No, use of TP objects and records in e.g. properties in not carefully 
crafted code. They are a lot less userfriendly.



___
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] Traits Proposal

2021-02-16 Thread Benito van der Zander via fpc-pascal

Hi,

If you need to create 1000 class instances each frame then you have a 
flaw in your logic in my opinion.



I have more like a million class instances

For my XPath stuff, and every returned value is put in a variant-like 
class. Selecting all nodes on an GB large XML, could even create almost 
a billion class instances



I once did a benchmark. It is 10% faster to reuse the class instances 
rather than recreating them, my commit log says. And I only implemented 
one interface (actually, two interfaces, since IUnknown always gets 
pulled in, too. )



Interfaces are not slow because they are are interfaces! When you call 
a interface method it has the same costs as a virtual method call! And 
the cost for reference counting that interfaces have right now would 
be there for ARC as well.



But it is not calling the method, it is calling the wrapper function

That is a additional second method call/jump for every interface method 
call.



E.g. _AddRef on TInterfacedObject as an interface, does not call 
TInterfacedObject._AddRef, it calls this:


WRPR_$SYSTEM_$$_TINTERFACEDOBJECT_$_IUNKNOWN_$_1_$_SYSTEM$_$TINTERFACEDOBJECT_$__$$__ADDREF$$LONGINT 


00424600 4883ef10 sub    $0x10,%rdi
00424604 e997f8feff   jmpq   0x413ea0 




Bye,
Benito
On 16.02.21 19:48, Sven Barth via fpc-pascal wrote:
Ryan Joseph via fpc-pascal > schrieb am Di., 16. Feb. 
2021, 19:21:


>
> There we have:
>
> * slower creation of the class, because each implemented
interface adds another VMT reference to the class which needs to
be initialized.

How bad is this? We need to make a test case we can profile. For
example if you have a game that creates 1000 classes 60 frames per
second. If adding interfaces to the classes hurts this process we
may have a deal breaker.


If you need to create 1000 class instances each frame then you have a 
flaw in your logic in my opinion.



> * slow reference counting. Especially if it is thread safe and
exception safe with the implicit exception block

It's a whole other topic but FPC needs opt-in ARC at the language
level for classes. Interfaces are not only slow but then you need
to pass around a reference to the interface instead of the class
you actually care about. It makes no sense to me whatsoever.


Interfaces are not slow because they are are interfaces! When you call 
a interface method it has the same costs as a virtual method call! And 
the cost for reference counting that interfaces have right now would 
be there for ARC as well.


Regards,
Sven


___
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] Traits Proposal

2021-02-16 Thread Benito van der Zander via fpc-pascal




There are no significant performance implications of interfaces. 
They're essentially a virtual method call, something that one is doing 
all day long with Object Pascal classes. 



Interfaces are extremely slow. Virtual method calls are also slow. I 
have been using interfaces for reference counting, and have been 
thinking to replace it all with managed records because they are so slow 
(unfortunately records can also be slow because fpc does not always keep 
them in registers even if they are pointer sized)


There we have:

* slower creation of the class, because each implemented interface adds 
another VMT reference to the class which needs to be initialized.


* slower method calling because of the wrapper function

* extremely slow casting an interface to the class. Never cast an 
interface, better add a method to the interface returning a class reference


* slow reference counting. Especially if it is thread safe and exception 
safe with the implicit exception block



On 14/02/2021 11:31, Sven Barth via fpc-pascal wrote:

Am 14.02.2021 um 01:09 schrieb Ben Grasset via fpc-pascal:
This seems possibly a *little* too similar to the existing Interface 
type in Object Pascal, however, I *would* really like to see some 
kind of functionality that basically amounts to "has the same 
capabilities as Interfaces and works on records and objects too, but 
does NOT require any kind of heap allocation".


My personal idea for this would be to allow for duck typing regarding 
interfaces: as long as the methods of the class, object or record 
satisfy those of the interface then it's possible to assign it. In 
case of objects and records one would mainly use raw interfaces (aka 
corba ones) instead of reference counted one as otherwise one would 
need to provide the methods of IInterface as well though one might not 
be able to implement them in a usable way as stack objects simply 
don't work that way.


So whether it be this, or just an improvement on the Interfaces we 
already have, I'd definitely personally be in favor of something that 
"works like Interfaces except minus the negative performance 
implications."


There are no significant performance implications of interfaces. 
They're essentially a virtual method call, something that one is doing 
all day long with Object Pascal classes.


Regards,
Sven
___
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] Question about System.Move()

2021-01-29 Thread Benito van der Zander via fpc-pascal

Hi,


Should "A" have a reference count of 1, and it is assigned a new value 
on another thread, its reference count will decrease to zero and the 
string and its descriptor are both freed. The value of "A" will be set 
to nil. 



If the reference count is 1, there is no other thread involved.

If there was another thread, there would be a reference in this thread 
and in the other thread, so the reference count would be at least 2



It is exactly as thread safe as the unoptimized function. If the 
reference count was 1, the unoptimized function would not work either, 
since the thread swap might occur just before the first instruction, and 
the strings are freed before the function can do anyhting



Bye,
Benito
On 28.01.21 08:08, Derek Edson via fpc-pascal wrote:
Your simplified code would not be thread safe. A thread swap after the 
first instruction of


        mov (%rdi), %rax

could potentially cause a problem. RAX (A) contains the pointer to the 
string descriptor, which includes the pointer to the actual string 
data and the reference count.


Should "A" have a reference count of 1, and it is assigned a new value 
on another thread, its reference count will decrease to zero and the 
string and its descriptor are both freed. The value of "A" will be set 
to nil.


RAX will not have been updated, so after

        mov %rax, (%rsi)

"B" will be pointing to an invalid location. Its content is now 
dependent on memory reallocation.


In this situation, changing "B" after the return from stringSwap 
procedure might again cause the string to be freed (assuming the 
memory was not reallocated), causing a double free error.


Use of the internal procedures to increment the string reference count 
of both strings before your code and then decrementing the reference 
counts afterwards would probably work.


The same probably applies to other reference count objects.

Derek

On Thu, Jan 28, 2021 at 11:35 AM Benito van der Zander via fpc-pascal 
<mailto:fpc-pascal@lists.freepascal.org>> wrote:


Hi,




Procedure ManagedMove(const source: T;var dest: T;count:
SizeInt);


In principle a good idea. However this is one of those cases
where you'd definitely need to use constref instead of const.



Or var, since the source might be cleared


And perhaps there could be a special attribute to mark which
kind of moving is needed, e.g..

  type [moveable] TA = record
  type [referencecounted] TA = record
  type [nonmoveable] TA = record


No, thank you.


But it could help a lot with optimizations. For moveable types it
could omit calling an assignment function and just do a memory
copy; and for refcounted tyes it could that when the number of
references does not change.



Like a simple swap function:

procedure stringSwap(var a, b: string);
var t: string;
begin
  t := a;
  a := b;
  b := t;
end;

A smart compiler could detect that it is a refcounted type and the
number of references stays the same, and thus optimize it into:

    mov    (%rdi),%rax
    mov    (%rsi),%rdx
    mov    %rdx,(%rdi)
    mov    %rax,(%rsi)
    retq

But FPC turns it into:

    begin
    push   %rbx
    push   %r12
    lea    -0x68(%rsp),%rsp
    mov    %rdi,%rbx
    mov    %rsi,%r12
    movq   $0x0,(%rsp)
    lea    0x8(%rsp),%rdx
    lea    0x20(%rsp),%rsi
    mov    $0x1,%edi
    callq  0x4324c0 
    mov    %rax,%rdi
    callq  0x41fba0 
    movslq %eax,%rdx
    mov    %rdx,0x60(%rsp)
    test   %eax,%eax
    jne    0x469191 
    t := a;
    mov    (%rbx),%rsi
    mov    %rsp,%rdi
    callq  0x428d00 
    a := b;
    mov    (%r12),%rsi
    mov    %rbx,%rdi
    callq  0x428d00 
    b := t;
    mov    (%rsp),%rsi
    mov    %r12,%rdi
    callq  0x428d00 
    callq  0x432830 
    end;
    mov    %rsp,%rdi
    callq  0x428ca0 
    mov    0x60(%rsp),%rax
    test   %rax,%rax
    je 0x4691b8 
    callq  0x4329e0 
    movq   $0x0,0x60(%rsp)
    jmp    0x469191 
    lea    0x68(%rsp),%rsp
    pop    %r12
    pop    %rbx
    retq




Then you want to simply use ismanagedtype and move(). Moving the
move() to a separate generic procedure will only lead to many
instantiations of what is basically a move() procedure.


The goal is to reduce instantiations.
If there are n generic (collection) classes, C1, C2, .., Cn, and k
types used in the collections, T1, T2, .. Tk, there are n*k
collection class instantiation C1, C1, .. C1, C2,
... Cn
If each collection class does its own Finalize-Loop/Move/Fillchar
there are also n*k of these move implementations. So like 3*n*k calls.
When any collection can call the same Manag

Re: [fpc-pascal] Question about System.Move()

2021-01-27 Thread Benito van der Zander via fpc-pascal

Hi,




Procedure ManagedMove(const source: T;var dest: T;count: SizeInt);


In principle a good idea. However this is one of those cases where 
you'd definitely need to use constref instead of const.



Or var, since the source might be cleared


And perhaps there could be a special attribute to mark which kind
of moving is needed, e.g..

  type [moveable] TA = record
  type [referencecounted] TA = record
  type [nonmoveable] TA = record


No, thank you.

But it could help a lot with optimizations. For moveable types it could 
omit calling an assignment function and just do a memory copy; and for 
refcounted tyes it could that when the number of references does not 
change.




Like a simple swap function:

procedure stringSwap(var a, b: string);
var t: string;
begin
  t := a;
  a := b;
  b := t;
end;

A smart compiler could detect that it is a refcounted type and the 
number of references stays the same, and thus optimize it into:


    mov    (%rdi),%rax
    mov    (%rsi),%rdx
    mov    %rdx,(%rdi)
    mov    %rax,(%rsi)
    retq

But FPC turns it into:

    begin
    push   %rbx
    push   %r12
    lea    -0x68(%rsp),%rsp
    mov    %rdi,%rbx
    mov    %rsi,%r12
    movq   $0x0,(%rsp)
    lea    0x8(%rsp),%rdx
    lea    0x20(%rsp),%rsi
    mov    $0x1,%edi
    callq  0x4324c0 
    mov    %rax,%rdi
    callq  0x41fba0 
    movslq %eax,%rdx
    mov    %rdx,0x60(%rsp)
    test   %eax,%eax
    jne    0x469191 
    t := a;
    mov    (%rbx),%rsi
    mov    %rsp,%rdi
    callq  0x428d00 
    a := b;
    mov    (%r12),%rsi
    mov    %rbx,%rdi
    callq  0x428d00 
    b := t;
    mov    (%rsp),%rsi
    mov    %r12,%rdi
    callq  0x428d00 
    callq  0x432830 
    end;
    mov    %rsp,%rdi
    callq  0x428ca0 
    mov    0x60(%rsp),%rax
    test   %rax,%rax
    je 0x4691b8 
    callq  0x4329e0 
    movq   $0x0,0x60(%rsp)
    jmp    0x469191 
    lea    0x68(%rsp),%rsp
    pop    %r12
    pop    %rbx
    retq




Then you want to simply use ismanagedtype and move().  Moving the 
move() to a separate generic procedure will only lead to many 
instantiations of what is basically a move() procedure.


The goal is to reduce instantiations.
If there are n generic (collection) classes, C1, C2, .., Cn, and k types 
used in the collections, T1, T2, .. Tk, there are n*k collection class 
instantiation C1, C1, .. C1, C2, ... Cn
If each collection class does its own Finalize-Loop/Move/Fillchar there 
are also n*k of these move implementations. So like 3*n*k calls.
When any collection can call the same ManagedMove, there should only be 
k ManagedMove instantiations and n*k calls to ManagedMove, which is only 
one call. So it is k + n*k calls,  which is around a third of 3*n*k


Bye,
Benito
On 11.01.21 18:51, Sven Barth via fpc-pascal wrote:
Benito van der Zander via fpc-pascal <mailto:fpc-pascal@lists.freepascal.org>> schrieb am Mo., 11. Jan. 
2021, 15:26:


Hi,

perhaps a  safe, generic function for this copying could be added
to the RTL. Like:

Procedure ManagedMove(const source: T;var dest: T;count: SizeInt);


In principle a good idea. However this is one of those cases where 
you'd definitely need to use constref instead of const.


And when you use IsManagedType, it does not distinguish standard
strings with such weird managed types.


You can additionally use GetTypeKind as well. Unlike TypeInfo it 
directly returns the TTypeKind (which for this case is enough) and is 
considered constant.


And perhaps there could be a special attribute to mark which kind
of moving is needed, e.g..

  type [moveable] TA = record
  type [referencecounted] TA = record
  type [nonmoveable] TA = record


No, thank you.

Regards,
Sven

___
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] Question about System.Move()

2021-01-11 Thread Benito van der Zander via fpc-pascal

Hi,

perhaps a  safe, generic function for this copying could be added to the 
RTL. Like:


Procedure ManagedMove(const source: T;var dest: T;count: SizeInt);


a) For non-managed types it would be the same as Move(source, dest, 
count*sizeof(T))


b) For reference counted types (like strings or interfaces or records of 
them), it would do:


1. finalize dest
2. normal Move
3. clear source, with fillchar

(for ranges where source and dest overlap, it should skip 1 and 3 for 
the overlapping elements. Like when you shift some elements in an arrays 
by two elements to the left, it only has to finalize the two overridden 
elements before the shifted elements, and clear the last two shifted 
elements. There is only one way to do that keeps the reference counts valid)


c) For user-defined managed, not reference counted types, it would just do

  for i := 0 to count - 1 do dest[i] := source[i]

Because you really want to use Move for strings, it can be vastly faster 
than updating the refcounts. But it might not work with user-defined 
types, like someone could build a managed type that cannot be moved. E.g.:


 type TA = record
  class operator Initialize(var a: TA);
  procedure dosomething;
end;

var globalPointer: ^TA;
class operator TA.Initialize(var a: TA);
begin
  globalPointer := @a;
end;
procedure TA.dosomething;
begin
  assert(globalPointer = @self)
end;




And when you use IsManagedType, it does not distinguish standard strings 
with such weird managed types.


And perhaps there could be a special attribute to mark which kind of 
moving is needed, e.g..


  type [moveable] TA = record
  type [referencecounted] TA = record
  type [nonmoveable] TA = record

Bye,
Benito
On 09.01.21 16:28, Bart via fpc-pascal wrote:

Hi,

This may be a silly question.
I use System.Move() to move items in a dynamic array, like
   Move(FData[0], FData[OldEnd], FStart*SizeOf(T));
Where T is the type of the elements in the array.
This seems to work as expected.

I have some questions though:

1. Does this depend on the alignment of the array?
2. Is it OK if the elements of the array are (or contain) managed types?
3. Are there caveats if T is a specialization of a generic type definition?

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] CP_NONE string disappearing

2020-12-27 Thread Benito van der Zander via fpc-pascal

Hello,

this code:

program Project1;
{$mode objfpc}{$H+}
var a,b, c: string;
begin
  a := 'x';
  b := 'y';
  SetCodePage(RawByteString(b), CP_NONE, false);
  c := a+b;
  writeln(c);
end.

prints x without y on win32/wine.

Is that supposed to happen?



Bye,

Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] I'm working on automated Help Output for console apps

2020-11-20 Thread Benito van der Zander via fpc-pascal

Hi,

I also made such a thing:

var optionsreader: TCommandLineReader;
begin
  optionsreader := TCommandLineReader.create;

  optionsreader.declareFile('file', 'The file to be processed');
  optionsreader.addAbbreviation('f');

  optionsreader.declareFlag('help', '');
  optionsreader.addAbbreviation('h');

  optionsreader.declareFlag('version', 'Print the version of the 
application');

  optionsreader.addAbbreviation('v');

  if optionsreader.existsProperty('help') then
     writeln(optionsreader.availableOptions);

end.


Output:

--file=  or -f    The file to be processed
--help or -h
--version or -v     Print the version of the application


You can download it at http://www.benibela.de/sources_en.html#rcmdline

Benito

On 20.11.20 01:33, Graeme Geldenhuys via fpc-pascal wrote:

Hi,

I'm working on a automated help output writer(s) for console apps.
Thus no more tedious and ugly output when you do: myapp -h

My aims:
  * I write a lot of console apps, so this would be very useful to me.
  * Ability to swap out the help formatter. It's interface based, so
custom implementations can easily be created.
  * Auto align help options and descriptions - the most annoying thing to
do manually. ;-)
  * Ability to define console width in which to format and wrap the help
output, but has a default value.
  * The idea is loosely base on the Java version found in Apache Commons.

When it's done I'll obviously shared it as open source somewhere.

With that said, below is how I currently use it. It uses the Builder design
pattern so gives it the Chain Invocations syntax. I know it's not something
often seen in Pascal programs, but it makes it very easy to read and easy
to use/type, especially with code completion editors like Lazarus IDE.

For those console programmers out there... Is there anything in console help
output that you like or wish you had. That way I could possibly add it and
make this even more useful to a wider audience.

I'm still working on AppName, Version and Usage output.

Example code:
==
var
   optionlist: TOptions;
   helpFormatter: IHelpFormatter;
   header: string;
   footer: string;
begin
   optionlist := TOptions.Create;

   optionlist.add(TOption.Builder
 .isRequired
 .withDescription('The file to be processed')
 .hasArg
 .withArgName('file')
 .withLongOpt('file')
 .build('f'));// build() always takes the mandatory short 
option.

   optionlist.add(TOption.Builder
 .withLongOpt('help')
 .withArgName('test')  // this is ignored because .hasArg was not 
specified
 .build('h'));

   optionlist.add(TOption.Builder
 .withDescription('Print the version of the application')
 .withLongOpt('version')
 .build('v'));

   header := 'Do something useful with an input file' + LineEnding;
   footer := LineEnding + 'Please report issues at http://example.com/issues';

   helpFormatter := TBasicHelpFormatter.Create();

   // sample outputs with increasing verbosity

   writeln('===   (1)');
   helpFormatter.printHelp(optionlist);

   writeln('===   (2)');
   helpFormatter.printHelp('DocView v1.0', optionlist);

   writeln('===   (3)');
   helpFormatter.printHelp('DocView v1.0', header, optionlist, footer);

   writeln('== the end =');
   optionlist.Free;
end;
==


And here is the example output for the 3 options so far:

===   (1)
* -f,--file The file to be processed
   -h,--help
   -v,--versionPrint the version of the application

* indicates required parameters
===   (2)
DocView v1.0
* -f,--file The file to be processed
   -h,--help
   -v,--versionPrint the version of the application

* indicates required parameters
===   (3)
DocView v1.0
Do something useful with an input file

* -f,--file The file to be processed
   -h,--help
   -v,--versionPrint the version of the application

* indicates required parameters

Please report issues at http://example.com/issues
== the end =



Regards,
   Graeme

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] link.res search dirs when cross compiling [solved]

2020-11-18 Thread Benito van der Zander via fpc-pascal


Some are hardcoded, and fpc.cfg might contain -Fl lines with paths too 
from parsing ld.so.conf on install

Well, I did not put them in ~/.fpc.cfg
In /etc/fpc.cfg there is

-Fl/usr/lib/gcc/x86_64-linux-gnu/10
-Fl/usr/lib/x86_64-linux-gnu/fpc/$fpcversion/lib/$FPCTARGET
-Fl/usr/lib/$fpctarget-*

The last one explains it. I actually have a directory 
/usr/lib/'${DEB_HOST_MULTIARCH}'.  Why would Ubuntu even ship such a 
directory.


$ dpkg -S DEB_HOST_MULTIARCH
libnss3:i386, libnss3:amd64: 
/usr/lib/${DEB_HOST_MULTIARCH}/libfreeblpriv3.chk
libnss3:i386, libnss3:amd64: 
/usr/lib/${DEB_HOST_MULTIARCH}/libfreeblpriv3.so

libnss3:i386, libnss3:amd64: /usr/lib/${DEB_HOST_MULTIARCH}/libfreebl3.chk
libnss3:i386, libnss3:amd64: /usr/lib/${DEB_HOST_MULTIARCH}/libfreebl3.so
libnss3:i386, libnss3:amd64: /usr/lib/${DEB_HOST_MULTIARCH}


Benito



On 18.11.20 20:33, Marco van de Voort via fpc-pascal wrote:


Op 2020-11-18 om 19:21 schreef Benito van der Zander via fpc-pascal:


where do the SEARCH_DIRs in link.res come from?


Some are hardcoded, and fpc.cfg might contain -Fl lines with paths too 
from parsing ld.so.conf on install



___
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] link.res search dirs when cross compiling

2020-11-18 Thread Benito van der Zander via fpc-pascal

How are you specifying your cross-compilation sysroot? Make sure you use
the -XR parameter for that,


I use -Fl in ~/.fpc.cfg...


When I use -XR nothing happens. The link.res is the same, except -Fl 
prepends the path to link.res and -XR just ignores it. (same for -Xr)



Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] link.res search dirs when cross compiling

2020-11-18 Thread Benito van der Zander via fpc-pascal

Hi,


where do the SEARCH_DIRs in link.res come from?

My build has started failing, after trying it on a new computer with 
"/home/benito/bin/arm-linux-androideabi-ld.bfd:android/libs/armeabi/link42815.res:17: 
ignoring invalid character `'' in expression"


link.res starts with:

SEARCH_DIR(/home/benito/opt/android/sdk/ndk-bundle/platforms/android-21/arch-arm/usr/lib/)
SEARCH_DIR(/usr/lib/thunderbird-addons/)
SEARCH_DIR(/usr/lib/modules/)
SEARCH_DIR(/usr/lib/aspell/)
SEARCH_DIR(/usr/lib/gnome-shell/)
SEARCH_DIR(/usr/lib/binfmt-support/)
SEARCH_DIR(/usr/lib/udev/)
SEARCH_DIR(/usr/lib/gcc/)
SEARCH_DIR(/usr/lib/cups/)
SEARCH_DIR(/usr/lib/tmpfiles.d/)
SEARCH_DIR(/usr/lib/firewalld/)
SEARCH_DIR(/usr/lib/X11/)
SEARCH_DIR(/usr/lib/cmake/)
SEARCH_DIR(/usr/lib/realmd/)
SEARCH_DIR(/usr/lib/klibc/)
SEARCH_DIR(/usr/lib/sasl2/)
SEARCH_DIR('/usr/lib/${DEB_HOST_MULTIARCH}/')

...


I guess '/usr/lib/${DEB_HOST_MULTIARCH}/ is the problem.  Why would it 
even add such a dir



Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Adding file to string to the RTL

2020-10-09 Thread Benito van der Zander via fpc-pascal






They cannot be used on handles that do not support FileSeek() 
(sockets, pipes, stdin/stdout etc.).



Well, it would be better if it could

You can just incrementally resize the return array, when reading 
succeeds after seeking fails.


I have a string load function doing that:

https://github.com/benibela/bbutils/blob/master/bbutils.pas#L3652





  Is it possible to extend this same set of functions to writing? 
Naturally I need to write back to the file now and the same problem

presents itself.  I have to search through other code bases to find a
function or Google and find 



Writing a file should write the data in a temporary file and then rename 
the temporary file to replace the target file. Otherwise it might 
destroy the target file, without writing the new content, when there is 
an error. Although not even renaming is always safe, some people say you 
need a filesystem-specific transaction log.




Benito

On 06.10.2020 10:12, Michael Van Canneyt via fpc-pascal wrote:




No, we don't deal in magic, only bits and bytes :-)

I added the following functions to the sysutils unit (rev 47056):

// Read raw content as bytes

Function GetFileContents(Const aFileName : RawByteString) : TBytes;
Function GetFileContents(Const aFileName : UnicodeString) : TBytes;
Function GetFileContents(Const aHandle : THandle) : TBytes;

// Read content as string

// Assume TEncoding.SystemEncoding
Function GetFileAsString(Const aFileName : RawByteString) : 
RawByteString;

// Specify encoding
Function GetFileAsString(Const aFileName : RawByteString; aEncoding : 
TEncoding) : RawByteString;

// Assume TEncoding.Unicode contents
Function GetFileAsString(Const aFileName : UnicodeString) : 
UnicodeString;

// Specify encoding, return Unicode string.
Function GetFileAsString(Const aFileName : UnicodeString; aEncoding : 
TEncoding) : UnicodeString;


These functions will raise an exception if the file cannot be opened 
or read.
They cannot be used on handles that do not support FileSeek() 
(sockets, pipes, stdin/stdout etc.).


I did some tests on encoding conversion but not extensively. If you 
find any errors, please report them through the bugtracker.


Michael.
___
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


[fpc-pascal] json parsing: detecting invalid escape sequences

2020-09-29 Thread Benito van der Zander via fpc-pascal

Hi,

I am supposed to find invalid escape sequences when parsing JSON and 
replace them with a user defined fallback. Invalid in the sense that the 
unicode codepoint is not defined or a missing surrogate, not 
syntactically invalid.


For example, any occurrence of \u and \uDEAD should be replaced by 
\u and \udead respectively. Or alternatively with  depending on 
the settings.


I think I need to change the JSON scanner to be able to do that.

I could add a callback function OnInvalidEscape: function (escapeStart: 
pchar): string; of object;
Or perhaps OnInvalidEscape: function (unicodePoint, 
previousUnicodePointSurrogate: integer): string; of object; {although 
that would be troublesome if \uDEAD and \udead are supposed to be 
replaced with a different fallback}
Or OnInvalidEscape: function (const escapedString: string[4]): string; 
of object;


The function would return the unescaped value. Alternatively, the 
current string could be passed to it as var parameter, and the function 
would append its unescaped value directly.


Or move all unescaping to a callback function, could be called 
OnUnescape or OnDecodeEscape. So the scanner does not need to decide 
which escapes are invalid. Then


  if (joUTF8 in Options) or 
(DefaultSystemCodePage=CP_UTF8) then
S:=Utf8Encode(WideString(WideChar(u1)+WideChar(u2))) // ToDo: use faster 
function

  else
    S:=String(WideChar(u1)+WideChar(u2)); // 
WideChar converts the encoding. Should it warn on loss?


could be replaced by one function call. And if the user does not set a 
callback function, the scanner would set its own callback function 
depending on the option.


Any interest in a patch that adds such a callback function? Or is there 
another way to do this?


Best,
Benito
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] json numbers with leading dots

2020-09-29 Thread Benito van der Zander via fpc-pascal

Hi,
there are also two lines in the json scanner where it tries to repair 
numbers with leading dots '.123' to '0.123':


 If (FCurTokenString[1]='.') then
  FCurTokenString:='0'+FCurTokenString;

They should probably be removed. Not only are those numbers invalid in 
json, it is also very slow to allocate a new string. And StrToFloat 
works with '.123', so it should not change anything.


Although removing them would break programs that cannot handle '.123', 
they are broken anyways, because it is not adding a zero to  '-.123'.



Best,
Benito
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] json parser line numbers

2020-09-29 Thread Benito van der Zander via fpc-pascal


here: https://bugs.freepascal.org/view.php?id=37836


On 29.09.20 10:47, Michael Van Canneyt via fpc-pascal wrote:



On Tue, 29 Sep 2020, Benito van der Zander via fpc-pascal wrote:


Hi,

the line numbering of the json parser has been changed recently.

It used to say "Error at line 1"... when there was an error in the 
first line, but now it says "Error at line 0"...


Was that on purpose, or can someone change it back?


It was not on purpose. Please file a bugreport.

Michael.
___
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


[fpc-pascal] json parser line numbers

2020-09-29 Thread Benito van der Zander via fpc-pascal

Hi,

the line numbering of the json parser has been changed recently.

It used to say "Error at line 1"... when there was an error in the first 
line, but now it says "Error at line 0"...


Was that on purpose, or can someone change it back?

Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] String literals and code page of .pas source file

2020-09-14 Thread Benito van der Zander via fpc-pascal


Hi,



I would definitely keep it that way.

As I see it: Redirection or not should not matter, the system should 
assume console output.

Things like 'tee' make this concept dubious in any case:

If you pipe output to a program, you don't expect the codepage to change
because of the redirection. 



In my projects, I set the output codepage to utf-8 when there is a 
redirection


It is platform agnostic, on identical inputs, it creates identical 
output files on Linux and Windows. No one needs OEM files on Linux


Best,
Benito

On 14.09.2020 14:51, Michael Van Canneyt via fpc-pascal wrote:



On Mon, 14 Sep 2020, Tomas Hajny via fpc-pascal wrote:


opened:
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  { if no codepage is yet assigned then assign default ansi codepage }
TextRec(t).CodePage:=TranslatePlaceholderCP(TextRec(t).CodePage);
{$else FPC_HAS_FEATURE_ANSISTRINGS}

I see no need to change this ?


Please, have a look at OpenStdIO (implemented at the end of 
text.inc). That one changes the default codepage for Input, Output 
and StdErr, but it doesn't care about possible redirection and/or 
piping to some other application (not necessarily written in FPC). 
That approach has both advantages and disadvantages. The advantage is 
that "type " will give correct results on the 
console. The disadvantage is that opening the redirected file with 
any Win32 GUI application (let's say notepad.exe) will result in 
garbage.  I don't say that it is necessarily bad, but it should be 
documented at least if we want to keep it that way.


I would definitely keep it that way.

As I see it: Redirection or not should not matter, the system should 
assume console output.

Things like 'tee' make this concept dubious in any case:

If you pipe output to a program, you don't expect the codepage to change
because of the redirection.


I think it will differ since Crt is not codepage aware. If you want 
it to
work the same you'll have to make Crt codepage (and hence unicode) 
aware.


As mentioned by me, Crt is currently more codepage aware than the 
System unit output as far as output to console is concerned, because 
Crt provides correct output even for shortstrings (unlike the System 
unit).


I would need to check the details, but that sounds more like 
accidental behaviour as opposed to intended behaviour to me :-)


Michael.
___
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] Procedural generics question

2020-08-25 Thread Benito van der Zander via fpc-pascal

Hi,

that is generating rather odd code (r40721)

project1.lpr:9    begin
00401090 55   push   %rbp
00401091 4889e5   mov    %rsp,%rbp
00401094 488d6424f0   lea -0x10(%rsp),%rsp
00401099 48895df8 mov    %rbx,-0x8(%rbp)
project1.lpr:10   if TypeInfo(T) = 
TypeInfo(Integer) then WriteLn('an integer');
0040109D 488d1584af0700   lea 0x7af84(%rip),%rdx    
# 0x47c028 
004010A4 488d057daf0700   lea 0x7af7d(%rip),%rax    
# 0x47c028 

004010AB 4839c2   cmp    %rax,%rdx
004010AE 752b jne    0x4010db 


004010B0 e8cbcf0100   callq  0x41e080 
004010B5 4889c3   mov    %rax,%rbx
004010B8 488d15412f0600   lea 0x62f41(%rip),%rdx    
# 0x464000 <_$PROJECT1$_Ld1>

004010BF 4889de   mov    %rbx,%rsi
004010C2 31ff xor    %edi,%edi
004010C4 e867d30100   callq  0x41e430 


004010C9 e8d2700100   callq  0x4181a0 
004010CE 4889df   mov    %rbx,%rdi
004010D1 e85ad20100   callq  0x41e330 
004010D6 e8c5700100   callq  0x4181a0 
project1.lpr:11   if TypeInfo(T) = 
TypeInfo(String) then WriteLn('a string');
004010DB 488d0546af0700   lea 0x7af46(%rip),%rax    
# 0x47c028 
004010E2 488d1537b20700   lea 0x7b237(%rip),%rdx    
# 0x47c320 

004010E9 4839d0   cmp    %rdx,%rax
004010EC 752b jne    0x401119 


004010EE e88dcf0100   callq  0x41e080 
004010F3 4889c3   mov    %rax,%rbx
004010F6 488d15132f0600   lea 0x62f13(%rip),%rdx    
# 0x464010 <_$PROJECT1$_Ld2>

004010FD 4889de   mov    %rbx,%rsi
00401100 31ff xor    %edi,%edi
00401102 e829d30100   callq  0x41e430 


00401107 e894700100   callq  0x4181a0 
0040110C 4889df   mov    %rbx,%rdi
0040110F e81cd20100   callq  0x41e330 
00401114 e887700100   callq  0x4181a0 
project1.lpr:12   end;

The compiler should know everything about TypeInfo(T) and optimize it 
away where possible


Cheers,
Benito
On 25.08.20 04:32, leledumbo via fpc-pascal wrote:

I remember something like this in RTTI though but can't find it in your

docs yet for generics.

{$mode objfpc}

uses
   typinfo;

generic procedure Add;
begin
if TypeInfo(T) = TypeInfo(Integer) then WriteLn('an integer');
if TypeInfo(T) = TypeInfo(String) then WriteLn('a string');
end;

begin
   specialize Add;
   specialize Add;
end.



--
Sent from: http://free-pascal-general.1045716.n5.nabble.com/
___
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] optimization for strlicomp()

2020-06-01 Thread Benito van der Zander

Hi,

I had a custom case-insensitive compare function, and it was very slow.

Then I benchmarked it and noticed, case-insensitiveness is rarely needed 
in practice.


Then I changed it to something like:


  c1:=str1[counter];
  c2:=str2[counter];
  if c1 <> c2 then begin
c1:=simplewideupcase(c1);
          c2:=simplewideupcase(c2);
  end;

and it was like 10 times faster

Best,
Benito
On 31.05.20 14:18, Alexey Tor. via fpc-pascal wrote:


function strlicomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
  var
   counter: sizeint;
   c1, c2: char;
  begin
    counter := 0;
    if l=0 then
  begin
    strlicomp := 0;
    exit;
  end;
    repeat
  c1:=simplewideupcase(str1[counter]);
  c2:=simplewideupcase(str2[counter]);
  if (c1=#0) or (c2=#0) then break;
  inc(counter);
    until (c1<>c2) or (counter>=l);
    strlicomp:=ord(c1)-ord(c2);
  end;

suggestions:

a)
  if (c1=#0) or (c2=#0) then break;
->
 if c1=#0 then break;
 if c2=#0 then break;

b)
embed upcase to avoid CALL
  c1:=simplewideupcase(str1[counter]);
  c2:=simplewideupcase(str2[counter]);
->
 c1:= str1[counter];
 c2:= str2[counter];
 if (c1>='a') and (c1<='z') then dec(c1, 32);
 if (c2>='a') and (c2<='z') then dec(c2, 32);

c) not sure..
we have 2 same diff's
c1<>c2
and
ord(c1)-ord(c2)

Alexey Torgashin

___
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] fcl-passrc errors

2019-10-15 Thread Benito van der Zander

Hi,

On 14.10.19 15:44, Ryan Joseph wrote:

var
   it: pointer;
   obj: TObject;
begin
   for it in list do
 begin
   obj := TObject(it);
   // continue on like before using “obj” instead of “it"
 end;


That’s our realistic best use case now but it requires 2 extra steps. I hope 
there’s a better solution to keep the for-in loops as easy to use as before.


you could do

var
  it: pointer;
  obj: TObject absolute it;
begin
  for it in list do
begin
  // continue on like before using “obj” instead of “it"
end;


Cheers,
Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Tests results of several pascal based JSON parsers

2019-08-31 Thread Benito van der Zander

Hi,

when I need maximal speed, I use jsonscanner of fpJSON. It should be 
vastly faster than a complete parser by not allocating memory or 
validating the json.


Although it decodes all the strings in the JSON, which require some 
allocations, even if you do not need every string.
It would be faster, if it would just set a (pchar, length) pair for each 
string. The CurTokenString property could be changed from returning the 
already decoded string to a method decoding the string only when the 
property is read.


Best,
Benito

Am 30.08.19 um 11:15 schrieb Michael Van Canneyt:



On Fri, 30 Aug 2019, Anthony Walter wrote:


I've posted a new page that tests the speed and correctness of several
pascal based JSON parsers.

https://www.getlazarus.org/json/tests/

In full disclosure I am the author of the new open source JsonTools
library, and even though my parser seems to a big improvement over the
other alternatives, my tests were not biased.


Test are always biased in the sense that they depend on the 
proficiency of
the coder. you must ask someone with sufficient knowledge to write the 
code.


The shootout benchmarks for example are dismally coded for FPC with as a
result that they perform badly.

So it could well be that the fpJSON results for example can be improved a
lot by changing the method used to a more efficient one.

Also, not every library is designed with the same goals.
fpjson could probably be made smaller if the goal was more focused.
it has a factory pattern, added on behalf of users who asked for this. 
jsontools does not have this. You can format the output. JSONTools 
does not have this.

fpJSON was designed to be pluggable wrt. parsing. JSONTools is not.

In short fpjson can do a lot more than JSONtools. Some things come at 
a price, others not.


In that sense, tests like this compare apples with pears.


If anyone would like help in replication the tests, let me know and I'll
see what I can do.

Also, to be thorough, you should read through both the article I 
posted at
the top this message, and my original page 

which has been updated with more information. Both pages took some 
time to
write, and I promise if you read through them some of your questions 
will

be answered without having to ask others for help or insight.


Can you please send me the testcode you used for your speed & 
correctness tests ?


I'm a bit surprised to see fpJSON fail in unicode correctness. It's been
tested extensively, maybe your code contains errors (or maybe fpjson 
does,

I'll need to check).

Also please explain what 'Handling duplicate key names correctly' 
means to you. Saying that a library fails a test without specifying 
what the test is, is

strange.

Michael.
___
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] CopyFile for FreePascal without Lazarus?

2019-04-18 Thread Benito van der Zander


Hi James,

I have just copied the function from Lazarus to my project.

Two days ago I even copied it in a new file: 
http://hg.benibela.de/internettools/file/f379759c52b9/data/xquery.internals.lclexcerpt.pas





Best,
Benito

On 18.04.2019 03:06, James Richters wrote:

Is there a copyfile for Freepascal I can use without installing Lazarus?

I found:
http://wiki.freepascal.org/CopyFile

but that seems to only work with Lazarus.

I just want to make a copy of a file into a different directory and maintain 
it's timestamps etc

Any suggestions?

James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Lazarus Release 2.0.2 - suggestions

2019-04-16 Thread Benito van der Zander

Hi,

since I need glasses, it is already troublesome to read a single screen.

With strong glasses just one point on the screen is really sharp and 
when the glasses shift a little, you end up seeing only on one eye properly




Cheers,
Benito

Am 16.04.19 um 22:17 schrieb Martin Wynne:

I have only 2 eyes, so I'm going to find 3 screens a problem.

Martin.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Optional param modifier

2019-04-13 Thread Benito van der Zander

Perhaps there could be the opposite modifier, so the function cannot be called 
with nil. Like

Interesting idea but I’d have to think about it more to know if this is a real 
problem I’ve ever experienced.


for example, I store some interfaces in a list, and just replaced the 
default list with a faster list that assumes all interfaces in the list 
are non-nil. (When you know the interface is non-nil, you can replace 
the automatic reference counting with a direct call to ._addref, which 
is faster. )


But then it crashed because somewhere it was used with a nil interface. 
There it would have been useful to mark the new function as only non-nil 
accepting, so that it is clear it cannot be used like the old function, 
and the compiler have made sure there is no call with nil





Well, as far as the "optional" part goes, the benefits of it will be 
fairly limited. Object variables occur in many places, and all of them 
can have the nil value, and the compiler has no idea if you did the 
check.


You pick a tiny subset of those cases, and attempt to add protection 
to it. Given the gain (or rather absence of it, according to the 
microscopic size of that subset) the effort (and chance of false 
positives) is not worth it. 


You would need to have optional or non-nil markers at every variable, 
before it becomes really useful.




Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Using TInterfaceList and casting interfaces

2019-04-13 Thread Benito van der Zander

Hi,


Or perhaps it is better to use gvector rather than TInterfaceList?


If you only store a specific interface type then using one of the 
generic containers specialized to that type would indeed be best.




 and on a closer look TInterfaceList does a lot of locking.

guess TInterfaceList should be avoided, unless you actually need 
something thread-safe. The classes unit is full of weird stuff


Best,
Benito

Am 07.04.19 um 20:24 schrieb Sven Barth via fpc-pascal:
Benito van der Zander mailto:ben...@benibela.de>> 
schrieb am So., 7. Apr. 2019, 15:34:


Writing (list.get(0) as ISomeInterface), is very slow and not
possible,
when the interface has no GUID.


This is indeed what is supposed to be used with TInterfaceList.

Or perhaps it is better to use gvector rather than TInterfaceList?


If you only store a specific interface type then using one of the 
generic containers specialized to that type would indeed be best.


Regards,
Sven

___
fpc-pascal maillist  -fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Optional param modifier

2019-04-13 Thread Benito van der Zander

Hi,

the parameter is already optional without any modifier, since you can 
always pass nil for it.


Perhaps there could be the opposite modifier, so the function cannot be 
called with nil. Like


procedure DoThis(nonnil var obj: TObject);

and then you need to check if it is nil, before calling DoThis .


Or you put it in the type. type TSomeObject = nonnil class(TObject)... 
and then it would never be allowed to be nil.

Or for pointers type PDude = nonnil ^TDude;
If you would want to use such a nonnil class as field in another class, 
you would need to initialize it in the constructor.




Bye,
Benito

Am 13.04.19 um 09:47 schrieb Sven Barth via fpc-pascal:
Marco van de Voort > schrieb am Fr., 12. Apr. 2019, 20:56:



Op 2019-04-12 om 17:23 schreef Ryan Joseph:
>
> What do you think of that? Sounds like an easy way to get some
support for nil pointers deref’s and provides self documenting code.

I think the same as when I read the suggestion for an inout
variant of
VAR. Move this out of the language syntax, and make it directives or
attribute like syntax (like we will need to get anyway for const ref).


Im definitely for new syntaxes (or the attribute one) than a 
directive. A directive can be anywhere and I'd need to go looking for 
it if I want to know whether it is set or not. Some syntax extension 
would be right at the declaration.


So, yeah, we'll probably compromise towards the attribute syntax...

Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] Using TInterfaceList and casting interfaces

2019-04-07 Thread Benito van der Zander

Hi,

how should one use TInterfaceList with other interfaces than IUnknown? 
Let's say we have a ISomeInterface derived from IUnknown.


When we have an ISomeInterface, we can add it to the list fine, because 
an ISomeInterface is an IUnknown.


But when we get it back from the list, it is an IUnknown and not an 
ISomeInterface.


Writing (list.get(0) as ISomeInterface), is very slow and not possible, 
when the interface has no GUID.


Writing ISomeInterface(list.get(0)) usually works fine, but when -CR is 
set, it does not compile.


Writing ISomeInterface(pointer(list.get(0))) appears to work, but is 
that safe, or does it confuse the reference counting?



Or perhaps it is better to use gvector rather than TInterfaceList?


Best,

Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] CLI argument parsers

2019-01-14 Thread Benito van der Zander


I wrote one, too: http://benibela.de/sources_en.html#rcmdline

Supports --linux=style and /windows style, and ' and " quotes



On 14.01.2019 10:49, Yann Mérignac wrote:
You can also try this: http://yann.merignac.free.fr/unit-cmdline.html 
It's a command line parser I wrote when I needed it a few years ago. I 
was inspired by these 2 articles: - 
https://www.adacore.com/gems/gem-138-gnatcoll.command-line - 
https://www.adacore.com/gems/gem-139-master-the-command-line-part-2


Le lun. 14 janv. 2019 à 09:41, Michael Van Canneyt 
mailto:mich...@freepascal.org>> a écrit :




On Mon, 14 Jan 2019, Martok wrote:

> I was 100% expecting that sort of answer.

My invitation to suggest improvements, you mean ?

I meant it: you're welcome to suggest improvements.

If you implement something like argpars and it can be used as
backend for
TCustomApplication, I'm willing to rework TCustomApplication to
use it.
This way we keep backwards compatibility and offer the possibility
to extend
it.

I'm not blind to the shortcomings of TCustomApplication argument
parsing.
It fully handles the unix '-a' '--aaa' scheme of doing things, but
currently
does not handle options in command form
prog --globalopts command [--commandopts] args

So, if you can offer something to keep current functionality and
allow this
as well: be my guest...

But e.g. the geptops way, which basically forces you to use a
while loop is
really not acceptable, which is why the TCustomApplication
interface is what
it is today.

Michael.
___
fpc-pascal maillist  - fpc-pascal@lists.freepascal.org

http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal



___
fpc-pascal maillist  -fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] inlining functions

2019-01-12 Thread Benito van der Zander

Hi,

 something that appears  to help is to put units in the interface uses 
rather than the implementation uses.


When the unit mentioned in the interface uses, uses the first unit in 
its implementation uses, it can inline the functions from the first 
unit. Although I would have expected it to do the opposite.


Unfortunately that does not help if the second unit needs to use types 
from the first unit in its interface


Best,
Benito

Am 12.01.19 um 13:05 schrieb denisgolovan:


12.01.2019, 14:53, "Jonas Maebe" :

Not at this time (unless you use the LLVM backend).

Could you give some hints on how to enable WPO/LTO under LLVM backend?
http://wiki.freepascal.org/LLVM does not seem to mention anything on that.


However, what you actually can do, is manually recompile all units of your 
program
multiple times. While this won't help with inline functions called
before they are parsed in those same units, it will allow inlining of
function bodies in other units that were not available during the first
compilation due to dependency cycles.

Eh.
It does not look too practical, right?
Unless there is some magical receipt for that :)

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Constants in generics

2019-01-08 Thread Benito van der Zander

Hi,

that reminds me of https://bugs.freepascal.org/view.php?id=34232



Bye,
Benito

Am 08.01.19 um 23:28 schrieb Sven Barth via fpc-pascal:
Am Di., 8. Jan. 2019, 21:01 hat Ryan Joseph 
mailto:r...@thealchemistguild.com>> 
geschrieben:


I’ve made constants respect their proper definition now so we can
do range checking but this broke some other things. For example
there’s a range check error with static arrays now because “U” has
a value of 0 so 0-1 = -1:

type
        generic TList = record
                list: array[0..U-1] of integer; // ERROR: high
value < low value (0..-1)
        end;


There’s a couple ways to resolve this:

1) Add some extra flags to nodes/syms so “U-1” can be known to
contain a generic parameter and errors can be ignored. That’s the
most complicated solution and I wasn’t able to figure that out
easily because flags need to be transferred in multiple locations.


This is the preferred solution as otherwise you'd also defeat the 
purpose of type safety and probably open another can of worms when 
constant parameters are used in more complex expressions.


The symbols should already have sp_generic_param set (if not that 
should definitely be changed so that it matches the type symbols). Now 
you only need a way to differentiate whether the symbol is an 
undefined generic parameter or not.
For type parameters it abuses the fact that the undefined defs of the 
parameters are children of the generic while the final types are never 
children of the generic. Maybe we can use something similar for the 
constants?

If not we can always add some flag to tconstsym...

Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] inlining functions

2019-01-02 Thread Benito van der Zander

Hi,


procedure TStrBuilder.append(const s: RawByteString);
begin
append(pchar(pointer(s)), length(s)); //inlinetest.pas(24,3) Note: 
Call to subroutine "procedure TStrBuilder.append(const p:PChar;const 
l:Int64);" marked as inline is not inlined
end; 


this seems to help

procedure TStrBuilder.append(const s: RawByteString);
var p: pchar;
begin
   p := pchar(pointer(s));
   append(p, length(s));
end;


I would personally be in favour of removing all of the inlining hints, 
because they are specific to a particular compiler version and mainly 
cause people to waste time on premature optimisation (or on what they 
think is an optimisation, but in many cases slows down things due to 
increased instruction cache pressure). 


After updating from 3.1 to 3.3 I only have to look at around one 
thousand hints





The one-pass thing is probably the reason it now complains about all 
inline functions in dependency cycles, unit A uses unit B that uses unit 
A. Then unit A can't inline something unit B. Any way around that?




Best,
Benito

Am 02.01.19 um 00:41 schrieb Jonas Maebe:

On 2019-01-02 00:19, Benito van der Zander wrote:


procedure TStrBuilder.append(const s: RawByteString);
begin
append(pchar(pointer(s)), length(s)); //inlinetest.pas(24,3) Note: 
Call to subroutine "procedure TStrBuilder.append(const p:PChar;const 
l:Int64);" marked as inline is not inlined

end;


The compiler does not support inlining calls with parameters that cast 
a managed type to an unmanaged type at this time.


Regarding the reason why something cannot be inlined: sometimes you 
can get more information with -vd, but not always (and even then the 
reason may be vague).


I would personally be in favour of removing all of the inlining hints, 
because they are specific to a particular compiler version and mainly 
cause people to waste time on premature optimisation (or on what they 
think is an optimisation, but in many cases slows down things due to 
increased instruction cache pressure). Especially in this case: there 
is nothing potentially wrong with such a call, nor is the method in 
general not inlinable, so there is no way to get rid of the hint other 
than by removing the inline directive altogether (or by adding a 
version of that routine with a different name that is not declared as 
"inline"). This only promotes complicating code without any potential 
improvement of productivity or clarity of the code/programmer intent.



Jonas
___
fpc-pascal maillist  - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] SetLength warnings - request

2019-01-02 Thread Benito van der Zander

Hi,



The current FPC trunk issues only a hint for the SetLength(). 



Then it is a bullshit hint  ("bullshint")





1) Dynamic arrays are initialised with nil, but that is an 
implementation detail (required by the fact that they are reference 
counted: if they would contain random data, that would cause crashes)




If there ever is a fpc version that does not initialize them with nil, 
then it could show a warning. Till then it is pointless. Everything 
without an ISO standard is an implementation detail



2) Passing a reference-counted variable as a var-parameter without 
explicitly initialising it first triggers a hint in all cases. 
Suppressing this hint specifically for SetLength would require 
treating it specially. 


SetLength has to be special, because we need it to initialize the array. 
There is no CreateArray function to initialize it with a somearray := 
CreateArray syntax, is there?


Even with the hint it is special, since at -O3 fpc warns about other 
functions, but not about SetLength anymore.




this bit from compiler/symtable.pas looks just ridiculous.

   begin
 newbuiltdefderefs:=nil;
 builtdefderefs:=nil;
 builtsymderefs:=nil;
 setlength(builtdefderefs,deflist.count);
 setlength(newbuiltdefderefs,deflist.count);
 setlength(builtsymderefs,symlist.count);


Indeed



The non-initialization of 'Result' has bitten me more than once in 
Delphi.


Me, too. Usually the solution was to add a call to SetLength.

That makes the bullshit hints especially bad.

There are so many hints about variables that are actually initialized 
that you cannot find the valid hints about places where the variable is 
actually uninitialized anymore.


Cheers,
Benito

Am 29.12.18 um 16:34 schrieb Yuriy Sydorov:

On 29.12.2018 16:19, Benito van der Zander wrote:

Hi,

even if there's closed issue 
https://bugs.freepascal.org/view.php?id=34169 I would like to ask if 
it can be reconsidered.


The subject is that SetLength now gives warning: Variable "dynamic 
array" of a managed type does not seem to be initialized


in 3.3.1 and 3.1.1 while it doesn't give any warning in stable 3.0.4



seriously that is such a bullshit warning.

SetLength is called to initialize the variable, of course the 
variable is not initialized before. If it was initialized, we might 
not even need to call SetLength


The current FPC trunk issues only a hint for the SetLength().

Yuriy.
___
fpc-pascal maillist  - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] inlining functions

2019-01-01 Thread Benito van der Zander

Hi Jonas,

That is reasonable. Perhaps the hint should mention that?

But why is this still not inlined::

type TStrBuilder = object
  procedure append(const p: pchar; const l: SizeInt); inline;
  procedure append(const s: RawByteString);
end;

implementation

procedure TStrBuilder.append(const p: pchar; const l: SizeInt); inline;
begin
end;


procedure TStrBuilder.append(const s: RawByteString);
begin
  append(pchar(pointer(s)), length(s)); //inlinetest.pas(24,3) Note: 
Call to subroutine "procedure TStrBuilder.append(const p:PChar;const 
l:Int64);" marked as inline is not inlined

end;



Best,
Benito

Am 01.01.19 um 22:41 schrieb Jonas Maebe:

On 01/01/19 22:38, Benito van der Zander wrote:
and why is it not inlining the count and append call of this string 
builder? It is not using any implementation only function


Routines can only be inlined if they are called after their 
implementation has been parsed. FPC compiles everything in a single pass.



Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] inlining functions

2019-01-01 Thread Benito van der Zander

Hi,

and why is it not inlining the count and append call of this string 
builder? It is not using any implementation only function


unit inlinetest;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils,math;

type TStrBuilder = object
protected
  next, bufferend: pchar; //next empty pchar and first pos after the string
public
  buffer: pstring;
  procedure init(abuffer:pstring);
  procedure final;
  function count: SizeInt; inline;
  procedure reserveadd(delta: SizeInt);
  procedure append(c: char); inline;
  procedure append(const s: RawByteString); inline;
  procedure append(const p: pchar; const l: SizeInt); inline;
end;

implementation

procedure TStrBuilder.init(abuffer: pstring);
begin
  buffer := abuffer;
  SetLength(buffer^, 16); //use setlength to create a new string

  next := pchar(buffer^);
  bufferend := next + length(buffer^);
end;

procedure TStrBuilder.final;
begin
  if next <> bufferend then begin
    setlength(buffer^, count);  // !!! Note: Call to subroutine 
"function TStrBuilder.count:Int64;" marked as inline is not inlined

    next := pchar(buffer^) + length(buffer^);
    bufferend := next;
  end;
end;

function TStrBuilder.count: SizeInt;
begin
  result := next - pointer(buffer^);
end;


procedure TStrBuilder.reserveadd(delta: SizeInt);
var
  oldlen: SizeInt;
begin
  if next + delta > bufferend then begin
    oldlen := count;
    SetLength(buffer^, max(2*length(buffer^), oldlen + delta));
    next := pchar(buffer^) + oldlen;
    bufferend := pchar(buffer^) + length(buffer^);
  end;
end;

procedure TStrBuilder.append(c: char);
begin
  if next >= bufferend then reserveadd(1);
  next^ := c;
  inc(next);
end;

procedure TStrBuilder.append(const s: RawByteString);
begin
  append(pchar(pointer(s)), length(s)); // !!! inlinetest.pas(71,3) 
Note: Call to subroutine "procedure TStrBuilder.append(const 
p:PChar;const l:Int64);" marked as inline is not inlined

end;



procedure TStrBuilder.append(const p: pchar; const l: SizeInt); inline;
begin
  if l <= 0 then exit;
  if next + l > bufferend then reserveadd(l);
  move(p^, next^, l);
  inc(next, l);
end;



end.



Bye,
Benito

Am 29.12.18 um 20:31 schrieb Sven Barth via fpc-pascal:
Am Sa., 29. Dez. 2018, 15:23 hat Benito van der Zander 
mailto:ben...@benibela.de>> geschrieben:


Hi,

after updating from fpc 3.1 to fpc 3.3, I am getting a lot of
"function
was not inlined" warnings, e.g. when an inline function depends on a
function not declared in the interface part like:

unit inlinetest;

{$mode objfpc}{$H+}

interface

uses
   Classes, SysUtils;


function strContains(const str, searched: string): boolean; inline;

implementation

function strContainsFrom(const str, searched: string; from: SizeInt):
boolean;
begin
   result:=Pos(searched, str, from) > 0;
end;


function strContains(const str, searched: string): boolean; inline;
begin
   result := strContainsFrom(str, searched, 1);
end;

end.



Is that supposed to happen?

Fpc 3.1 did not show any warning in this case (although now that I
investigate it, fpc 3.1 also did not seem to inline it despite not
showing the warning)


Correct. FPC 3.1.1 did neither warn nor inline in this case, 3.3.1 at 
least warns (I think 3.2 already warns as well).


Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] inlining functions depending on implementation only functions

2018-12-29 Thread Benito van der Zander

Hi,

after updating from fpc 3.1 to fpc 3.3, I am getting a lot of "function 
was not inlined" warnings, e.g. when an inline function depends on a 
function not declared in the interface part like:


unit inlinetest;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;


function strContains(const str, searched: string): boolean; inline;

implementation

function strContainsFrom(const str, searched: string; from: SizeInt): 
boolean;

begin
  result:=Pos(searched, str, from) > 0;
end;


function strContains(const str, searched: string): boolean; inline;
begin
  result := strContainsFrom(str, searched, 1);
end;

end.



Is that supposed to happen?

Fpc 3.1 did not show any warning in this case (although now that I 
investigate it, fpc 3.1 also did not seem to inline it despite not 
showing the warning)



Bye,

Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] SetLength warnings - request

2018-12-29 Thread Benito van der Zander

Hi,

even if there's closed issue 
https://bugs.freepascal.org/view.php?id=34169 I would like to ask if 
it can be reconsidered.


The subject is that SetLength now gives warning: Variable "dynamic 
array" of a managed type does not seem to be initialized


in 3.3.1 and 3.1.1 while it doesn't give any warning in stable 3.0.4



seriously that is such a bullshit warning.

SetLength is called to initialize the variable, of course the variable 
is not initialized before. If it was initialized, we might not even need 
to call SetLength


Cheers,
Benito

Am 04.09.18 um 15:53 schrieb Vojtěch Čihák:


Hello,

even if there's closed issue 
https://bugs.freepascal.org/view.php?id=34169 I would like to ask if 
it can be reconsidered.


The subject is that SetLength now gives warning: Variable "dynamic 
array" of a managed type does not seem to be initialized


in 3.3.1 and 3.1.1 while it doesn't give any warning in stable 3.0.4

As a solution is recommended do declaration: var arr: array of 
widechar = ();


But it means that initialization is in fact done twice. See assembler 
of following code:


procedure TForm1.Button1Click(Sender: TObject);

var DA: array of widechar = ();

begin

  SetLength(DA, 10);

  writeln(DA[0]);

end;

unit1.pas:30                     var DA: array of widechar = ();

004696C9 488d1538536600           lea    0x665338(%rip),%rdx  
      # 0xacea08 


004696D0 488b3529536600           mov    0x665329(%rip),%rsi  
      # 0xacea00 


004696D7 4889e7                   mov    %rsp,%rdi

004696DA e8d199fcff               callq  0x4330b0 



unit1.pas:32                     SetLength(DA, 10);

004696DF 48c74424680a00       movq   $0xa,0x68(%rsp)

004696E8 488d3519536600           lea    0x665319(%rip),%rsi  
      # 0xacea08 


004696EF 488d4c2468               lea    0x68(%rsp),%rcx

004696F4 4889e7                   mov    %rsp,%rdi

004696F7 ba0100               mov    $0x1,%edx

004696FC e8df99fcff               callq  0x4330e0 



unit1.pas:33                     writeln(DA[0]);

To avoid warning we now need four extra instructions incl. call to 
fpc_array_assign, which is obviously redundant.
As an explanation is written: Setlength uses a var parameter. This is 
no different from other cases of var parameter usage.
I disaggre here, because SetLength is not an usual procedure, it is 
fundamental part of compiler. Therefore it deserves some exception.
That's why I ask for reconsidering and make it behave like in 3.0.4 or 
change declaration from "var" to "out" as it is done in getmem().

Thanks, Vojtěch.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] with in classes/records

2018-09-25 Thread Benito van der Zander

Hi,

perhaps everything would be clearer, if the default property was 
accessed with ^  ?



var
wrapper: TWrapper;
begin
wrapper := TWrapper.Create;
wrapper^ := THelperA.Create;
end.


Cheers,
Benito



Am 14.09.2018 um 10:50 schrieb Ryan Joseph:

How should this syntax work? TWrapper needs to allow assignments of TWrapper 
for constructors but it also should accept assignments of THelperA for the 
default write property.

Is that a problem or should TWrapper be able to assign both? It looks strange 
so I thought I would ask.

==

type
THelperA = class
end;

type
TWrapper = class
objA: THelperA;
property helperA: THelperA read objA write objA; default;
end;

var
wrapper: TWrapper;
begin
wrapper := TWrapper.Create;
wrapper := THelperA.Create;
end.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Type helper for JNI pointers

2018-08-26 Thread Benito van der Zander

Hi,



I haven't used type helpers but why not change to defines like

type
  jObjectRec = record end;
  jObject= ^jObjectRec;
  jClassRec = record end;
  jClass = ^jClassRec;

or possibly simpler you could try
  jclass = type(jobject); // I believe this forces a new type and is 
not just an alias



that looks better.

Who can  change them? These jobject/jclass type definitions are part of 
fpc...






Although type is weird


type a = type (pointer);
type b = type (a);


does not compile, duplicate identifier a


type a = type (pointer);
type b = type a;


compiles, but a type helper for cannot use self as pointer. self <> nil 
=> operator is not overloaded. But you can do writeln(self);



type a = type pointer;
type b = type (a);


does not compile, duplicate identifier a


type a = type pointer;
type b = type a;


compiles, and is like a pointer, but unlike case 2, you cannot do 
writeln(self) in the type helper




type a = type (pointer);
type b = type (pointer);


does not compile, duplicate identifier


type a = type (pointer);
type b = type pointer;


does not compile, error in type definition


type a = type pointer;
type b = type (pointer);


compiles


type a = type pointer;
type b = type pointer;


compiles




Cheers,
Benito



Am 23.08.2018 um 04:23 schrieb Andrew Haines via fpc-pascal:




On 08/12/2018 07:42 AM, Benito van der Zander wrote:



But this does not work, because fpc thinks jclass and jobject are the 
same type, so there is only one type helper for both of the types 
allowed.


Because it is declared as

type
 jobject=pointer;
 jclass=jobject;


What can we do about this?


I haven't used type helpers but why not change to defines like

type
  jObjectRec = record end;
  jObject= ^jObjectRec;
  jClassRec = record end;
  jClass = ^jClassRec;

or possibly simpler you could try
  jclass = type(jobject); // I believe this forces a new type and is 
not just an alias


Regards,

Andrew



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] Type helper for JNI pointers

2018-08-12 Thread Benito van der Zander

Hi,

when you use JNI functions you always need to repeat "env" a lot:

var
  javaClass: jclass;
  javaObj: jobject;
begin
  //javaClass := ...
  javaObj := env^^.NewObject(env, javaClass)
  env^^.DeleteLocalRef(env, javaObj);
end;

So I thought you could declare type helpers for jobject and jclass,

  TjobjectHelper = type helper for jobject
     procedure DeleteLocalRef;
  end;
  TjclassHelper = type helper for jclass
 procedure NewObject;
  end;

And then just write

var
  javaClass: jclass;
  javaObj: jobject;
begin
  //javaClass := ...
  javaObj := javaClass.NewObject()
  javaObj.DeleteLocalRef;
end;


But this does not work, because fpc thinks jclass and jobject are the 
same type, so there is only one type helper for both of the types allowed.


Because it is declared as

type
 jobject=pointer;
 jclass=jobject;


What can we do about this?

Bye,

Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] testing if a float has a fractional part

2018-05-11 Thread Benito van der Zander

Hi,

after all these discussions about the frac function, what is the best 
way to test if there is a fractional part? That is the most common thing 
I use frac for


I have always used frac(x) = 0

Is that worse or better than int(x) = x  ?


Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Stack alias for ARC like memory management?

2018-04-26 Thread Benito van der Zander


Hi,

I totally agree that available libraries like the above are what 
attract (or keep existing) users to Pascal, not some minor 
syntactical  sugar.


But syntax features attract the library developers that will write those 
attractive libraries



Cheers,
Benito



On 25.04.2018 16:27, Dennis wrote:



Michael Van Canneyt wrote:


I want the same for pascal.

But I really still need to see convincing evidence that language 
features contribute to productivity.


Available libraries for common programming tasks - and I mean this on 
a high-level
level - are infinitely more important, so I don't need to get down to 
the

gory details of many tasks:

* Creating a PDF. * Creating a good-looking report from Data. * Have 
an API that reads google protocol data.

* A good ORM/OPF.
* Reading a smartcard.
* Access a Google,Facebook,Twitter, MS or what-have-you-not REST API. 
* A wizard that makes a Data entry form based on a TDataset or object.

* Classes to make a REST API.
* Classes to make/consume a SOAP service.
* Code that transforms a JSON structure to object classes plus the 
code to

* read/write the JSON.

These are things that make me win time.

I totally agree that available libraries like the above are what 
attract (or keep existing) users to Pascal, not some minor 
syntactical  sugar.

E.g.
  people new to AI will learn python just because there are ready 
libraries in AI callable by python.
  People new to statistics will learn R just because there are ready 
libraries of statistics in R.
  People new to iOS will learn swift because it allows them easily 
call all the libraries of iOS, not because swift is better than Pascal 
or Java.


It is about convenience.

Dennis

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Next language feature for pas2js...

2018-04-26 Thread Benito van der Zander


Hi,

I would like to vote for pointer support...



Cheers,
Benito



On 25.04.2018 15:20, Michael Van Canneyt wrote:


Hello,

Now that interface support has been added to the list of implemented 
language
features of pas2js, we're looking to get feedback on what best to 
tackle next.


This time, the poll is not on the forum, so you do not need to have an
account to vote.

Here is a link to the poll:

https://docs.google.com/forms/d/e/1FAIpQLScPVu6Y_X1QhOrYLWia4TVeKoZ3wiu-_PiMqJ0Zm8KW39FdCQ/viewform?usp=sf_link 



Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Scoped enums and inferred types

2018-02-21 Thread Benito van der Zander

Hi Fpc-pascal Users,

I simply rely on my IDE (Lazarus, Visual Studio)  to complete long 
identifier names for me so that I don't have to. *shrugs*



 but you still need to read the identifiers and when they are too long, 
that takes time, too




How does that look?


No idea how it looked, but it could look like this:

uses definingUnit.TTileSortingFlag;

-> you need to write TTileSortingFlag.Static

uses definingUnit.TTileSortingFlag.Static;

or

uses definingUnit.TTileSortingFlag.*;

-> you can just write Static


Alternatively:

with TTileSortingFlag do

to just write Static
Bye,
Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] fgl unit, TFPSList needs DeleteRange

2017-12-10 Thread Benito van der Zander

Hi Michael Van,


delete the elements one by one anyway, for instance for interfaces. 



that can still be speed up by range deletion.  First call _Release on 
them all, then remove them with move/fillchar.




Bye,
Benito


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Using Pascal N-IDE (Android)

2017-12-05 Thread Benito van der Zander

Hi Paul,

would it be hard to use those IDEs for other languages or can you plugin 
another interpreter?


I have an interpreter with Android support, and have been looking for 
some syntax highlighting there for a while


Cheers,
Benito



Am 05.12.2017 um 20:36 schrieb Paul Breneman:

On 12/05/2017 12:50 PM, Mattias Gaertner wrote:

On Tue, 5 Dec 2017 10:48:01 -0500
Paul Breneman  wrote:


On 12/05/2017 10:12 AM, Paul Breneman wrote:

On 12/05/2017 09:52 AM, Paul Breneman wrote:

On 12/05/2017 09:30 AM, Paul Breneman wrote:


It seems you are talking to yourself.

Mattias


Yes, and I was the *only* one talking *while* I did it!  :)

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] FPC 3.0.4 released!

2017-12-03 Thread Benito van der Zander

Hi,

 SourceForge gives checksums, too:




Cheers,
Benito



Am 30.11.2017 um 15:47 schrieb Tomas Hajny:

On Thu, November 30, 2017 15:32, kardan wrote:

Wow, both of you managed to avoid my actual question. :)

On Thu, 30 Nov 2017 13:00:07 +0100
kardan  wrote:


How can I verify those downloads with shasum or gpg fingerprints)?
(FTP and HTTP seem not to be the safest ways these days.)

Sourceforge provides HTTPS access, that should be safe enough. Apart from
that - no, checksums are not being created as part of the release process
at the moment.

Tomas


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Freepascal Floating Point Issue

2017-08-23 Thread Benito van der Zander

Btw, anyone know about a BCD math implementation for Free Pascal, like
it used to be implemented in DR CBASIC? (those were the days... ;-) )



I have one here: http://benibela.de/sources_en.html#bigdecimalmath



Am 23.08.2017 um 02:16 schrieb Paul Nance:

Turbo Pascal also had a BCD unit.

On Aug 22, 2017 6:56 PM, "Ralf Quint" > wrote:


On 8/22/2017 1:39 PM, Mark Morgan Lloyd wrote:
> On 21/08/17 22:15, Ralf Quint wrote:
>> On 8/21/2017 3:02 PM, James Richters wrote:> I am having an issue
>> with a simple floating point application.  I am setting a
variable to
>> a specific value and immediately after I set it, it is not exactly
>> what I set it to.  Here's an example>> Draw_GX_Min:=999.999;>
>> Writeln(Draw_GX_Min:3:30);>> The writeln results in
>> 999.999002 >> Why is it not
>> 999.999000  where did 0.02 come
>> from?>Out of thin air... Well, kind of. Double floating point means
>> 16 digitsof precision, so when you force a 30 digit precision
output,
>> anythingpast 16 digits is random garbage, at best...
>
> And in any event, that's probably much more precision than the
GPU is
> using to generate the final image :-)
>
Well, older GPUs (at least NVidia, pretty sure similar restrictions
apply to AMD) use(d) only 32bit "single" floats, giving a 7 digit
precision, though newer ones can also handle 64bit doubles. But there
are quite a few differences in how certain FP operations are
handled on
those GPUs, which result in even doubles only having 14 (instead
of 16)
digits of precision at best. So while NVidia keeps mentioning IEEE754,
their GPUs are in practice not 100% compliant.

As I mentioned before, if someone needs to work a lot with floating
point arithmetic, it really helps to get yourself acquainted to
the way
those works and all the possible pitfalls.

Btw, anyone know about a BCD math implementation for Free Pascal, like
it used to be implemented in DR CBASIC? (those were the days... ;-) )

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

http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal




___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] TStringList - Strange quotation mark handling

2017-08-16 Thread Benito van der Zander

Hi,

very stupid defaults indeed.

I just had a bug last week, because I was using TStringList as map and 
forgot to change it to case-sensitive




Cheers,
Benito



Am 16.08.2017 um 15:48 schrieb Gabor Boros:

2017. 08. 16. 15:21 keltezéssel, Michael Van Canneyt írta:
Because the quotes must be the first and last character of each 
string (or "cell").


As noted in another reply, set the quote character to something 
unused, and

it will disable (or circumvent) quoting altogether.


SL2.QuoteChar:=#0; solved my problem. But strange if the TStringList 
think from a starting " the string is quoted. For example if data.cvs 
contains "abc|89|0 I got the next result with my example program 
(without QuoteChar trick): 0 * abc|89|0


Gabor
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Defining sonames?

2017-08-13 Thread Benito van der Zander

Hi,

 that reminds me of Synapse.


It is always very confusing to people that they need to install 
libssl-dev to use https, and libssl does not work.
Because libssl-dev contains libssl.so or so, while libssl only has 
libssl.so.1.0.0, which is not found...


And then you tell people to install libssl-dev, and they are even more 
confused, because they cannot find it, because they are on a 
distribution where they call it devel-openssl instead.



Cheers,
Benito



On 08/12/2017 04:54 PM, Fred van Stappen wrote:

Hello Martin.

Description of libx11-dev package (in /DEBIAN/control).

Package: libx11-dev
...
Description:
This package contains the development headers for the library found in 
libx11-6.

Non-developers likely have little use for this package.
...

Afaik, fpc does not use the C headers (I did not find it) nor fpc does 
not develop/change anything inside the libX11 code.
Maybe, but I have lot of doubt, fpc could need the C headers to 
compile himself.

But the compiled fpc should not need it.

So, imho, in the case of fpc, they should not use libX11.so but 
libX11.so.6 when linking things with the binary fpc.


My 0,001 cent.


Fre;D




___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Array clearing

2017-04-13 Thread Benito van der Zander

Hi Ryan,

In the real world is anyone actually going to type that out every time? I’d bet 
most of us have an array class we use and ignore dynamic arrays all together 
because we all need basic operations like “add” and “remove”.


I, for one, have a huge list of array utility functions: 
http://hg.benibela.de/bbutils/file/tip/bbutils.inc


I use arrays rather than classes, because latter are not reference counted

Bye,
BeniBela



On 04/12/2017 04:30 PM, Ryan Joseph wrote:

On Apr 12, 2017, at 9:24 PM, Jürgen Hestermann  
wrote:

SetLength(Array,Length(Array)+1);

You will get an additional element (filled with zeros).
Then you can set

Array[High(Array)] := whateveryouwant;

Well sure, but this kind of code is exactly what programmers abstract and reuse 
so it’s a perfect candidate for a function.

SetLength(Array,Length(Array)+1);
Array[High(Array)] := …

In the real world is anyone actually going to type that out every time? I’d bet 
most of us have an array class we use and ignore dynamic arrays all together 
because we all need basic operations like “add” and “remove”.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Feature announcement: Management Operators

2017-03-04 Thread Benito van der Zander

Hi,

with a function call: http://bugs.freepascal.org/view.php?id=30333


I had benchmark runs where it spend more time in the initializing 
function than doing any calculations


Best,
Benito



On 03/04/2017 06:41 PM, Michael Van Canneyt wrote:



On Sat, 4 Mar 2017, nore...@z505.com wrote:


On 2017-02-28 14:48, Jonas Maebe wrote:

On 28/02/17 21:40, nore...@z505.com wrote:

What happens with a stack allocated record?
(no new() required, nor dispose() so is the record ever
initialized/finalized?)


Yes, just like records that contain e.g. an ansistring field.


Jonas



do records which contain ansistring fields have some special stack 
initialization system (sorry, I should really read the source code in 
this case - still interested in theory of how this works)


Yes. They are initialized.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] TProcess usage and reading program output

2017-02-28 Thread Benito van der Zander

Hi,

 how would you handle large output and large stderr?


When you read from one and it writes to the other, the read blocks. Then 
it keeps writing to the other buffer, till that is full, and then its 
write is blocked, and it is deadlocked.


Probably check NumBytesAvailable before reading?

Bye,
Benito



On 02/28/2017 05:28 PM, Michael Van Canneyt wrote:



On Tue, 28 Feb 2017, Graeme Geldenhuys wrote:


Hi,

Can anybody see if there is something wrong with the code shown below.
The code is copied from one of my earlier projects where I call the FPC
compiler and it worked just fine in that project.

In the work I'm doing now, I'm calling the Delphi Command Line Compiler,
and made a few minor tweaks to the code, but this method never seems to
return when Delphi command line compiler is called, and I don't see any
output. If I call other utilities (eg: Git etc) then I do see output and
it works as expected. It's just the Delphi Command Line Compiler that
now seems to be giving troubles.

I would really appreciate it is anybody could spare a moment. Many 
thanks.


I marked two areas with "// ???" where I am unsure if I'm doing the
right thing.


poWaitOnExit should not be needed, as this will cause Execute to wait 
for process exit...


It seems likely that this will interfere with reading from output: 
when the

output buffer is full, the executed process will block.

The rest seems fine.

Also:
It may be that Delphi somehow writes directly to the console buffer, 
in that

case you will not catch any output. But then you should see the output on
the screen (just not caught by your process)

Michael.








==
function TBuildDelphiProject.RunTProcess(const Binary: string; args:
TStrings): boolean;
const
 BufSize = 1024;
var
 p: TProcess;
 Buf: string;
 Count: integer;
 i: integer;
 LineStart: integer;
 OutputLine: string;
begin
 p := TProcess.Create(nil);
 try
   p.Executable := Binary;
   // ??? Is poWaitOnExit needed here, it is called later down the code
   p.Options := [poUsePipes, poStdErrToOutPut, poWaitOnExit];
//p.CurrentDirectory := ExtractFilePath(p.Executable);
   p.ShowWindow := swoShowNormal;  // ??? Is this needed?

   p.Parameters.Assign(args);
   DoLog(etInfo,'Running command "%s" with arguments
"%s"',[p.Executable, p.Parameters.Text]);
   p.Execute;

   { Now process the output }
   OutputLine:='';
   SetLength(Buf,BufSize);
   repeat
 if (p.Output<>nil) then
 begin
   Count:=p.Output.Read(Buf[1],Length(Buf));
 end
 else
   Count:=0;
 LineStart:=1;
 i:=1;
 while i<=Count do
 begin
   if Buf[i] in [#10,#13] then
   begin
 OutputLine:=OutputLine+Copy(Buf,LineStart,i-LineStart);
 writeln(OutputLine);
 OutputLine:='';
 if (iBuf[i+1]) then
   inc(i);
 LineStart:=i+1;
   end;
   inc(i);
 end;
 OutputLine:=Copy(Buf,LineStart,Count-LineStart+1);
   until Count=0;
   if OutputLine <> '' then
 writeln(OutputLine);
   p.WaitOnExit;
   Result := p.ExitStatus = 0;
   if Not Result then
 Writeln('Command ', p.Executable ,' failed with exit code: ',
p.ExitStatus);
 finally
   FreeAndNil(p);
 end;
end;
==


Regards,
 Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] JSON Test Suite

2016-11-07 Thread Benito van der Zander


Hi,
huh, why does the build suddenly fail?

Well, FPC 3.0.0 does not have the joStrict option.
It is only there in 3.1.1.

Perhaps there should be two fpc parser entries.

Best,
Benito


On 06.11.2016 17:34, Benito van der Zander wrote:

Hi,

it is better to use TJSONParser than GetJSON.

GetJSON is defined as:

procedure DefJSONParserHandler(AStream: TStream; const AUseUTF8: 
Boolean; out

  Data: TJSONData);

Var
  P : TJSONParser;

begin
  Data:=Nil;
  P:=TJSONParser.Create(AStream,[joUTF8]);
  try
Data:=P.Parse;
  finally
P.Free;
  end;
end;

with

procedure DefJSONParserHandler(AStream: TStream; const AUseUTF8: 
Boolean; out

  Data: TJSONData);

Var
  P : TJSONParser;

begin
  Data:=Nil;
  P:=TJSONParser.Create(AStream,[*joStrict,*joUTF8]);
  try
Data:=P.Parse;
  finally
P.Free;
  end;
end;

it should pass more


Best,

Benito





___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] JSON Test Suite

2016-11-06 Thread Benito van der Zander

Hi,

it is better to use TJSONParser than GetJSON.

GetJSON is defined as:

procedure DefJSONParserHandler(AStream: TStream; const AUseUTF8: 
Boolean; out

  Data: TJSONData);

Var
  P : TJSONParser;

begin
  Data:=Nil;
  P:=TJSONParser.Create(AStream,[joUTF8]);
  try
Data:=P.Parse;
  finally
P.Free;
  end;
end;

with

procedure DefJSONParserHandler(AStream: TStream; const AUseUTF8: 
Boolean; out

  Data: TJSONData);

Var
  P : TJSONParser;

begin
  Data:=Nil;
  P:=TJSONParser.Create(AStream,[*joStrict,*joUTF8]);
  try
Data:=P.Parse;
  finally
P.Free;
  end;
end;

it should pass more


Best,

Benito



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Re: [Bulk] Re: Namespaces Support

2013-11-03 Thread Benito van der Zander




Then the John Douglas and Douglas McKey are running into the same issue.
Both guys (while living on different parts of the world) created the 
same douglas namespace!


That's why most languages use domains as namespace
Then you would have

net.delfire.douglas.*
org.msegui.*

and no collision

On 10/29/2013 02:48 AM, Dmitry Boyarintsev wrote:
On Mon, Oct 28, 2013 at 9:27 AM, Graeme Geldenhuys 
gra...@geldenhuys.co.uk mailto:gra...@geldenhuys.co.uk wrote:


I would have thought that is exactly what namespaces will be handy
for! Or at least a popular use-case. Macros Douglas could define a
douglas namespace, and the MSEide+MSEgui project could define a
msegui namespace. Units, Classes or even lines of code should be
able to say which namespace they are referring too.


Then the John Douglas and Douglas McKey are running into the same issue.
Both guys (while living on different parts of the world) created the 
same douglas namespace!


Similar to using the same M prefix for classes unit.

What option do these three guys would have now? Elevate another the 
level of name space?

john.douglas
macros.douglas
mckey.douglas
douglas.mckey?

Is it much different than just extending the prefix M to MFP?

thanks,
Dmitry

P.S. Offtopic: I personally find it horrible to call a unit classes 
(it's fine for RTL, since it's started this way, but any other library 
- it is horrible). Nobody calls their units like functions or 
functionsandprodures (though I think I saw unit funcs one day), It 
is better to give more accurate name of the unit functionality: 
StrLists, UnicodeUtils, FileUtls, DateUtils.




___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Getting the state of a TRTLCriticalSection

2013-10-06 Thread Benito van der Zander


In the end I stuck in code to increment/decrement a counter, and 
looked for it to be explicitly 0 or 1.


Do you need to put a memory barrier around that, or does the critical 
section take care of that?




On 10/06/2013 06:55 PM, Mark Morgan Lloyd wrote:

Michael Van Canneyt wrote:

On Sun, 6 Oct 2013, Mark Morgan Lloyd wrote:

Is there a preferred way of reading back whether something 
(including the current thread) has already entered a TCriticalSection?


To my knowlede this does not exist.

The Microsoft implementation of a critical section has 
TryEnterCriticalSection, but I do not know how portable or useful 
that is.


I think that one's generally available, but it looks as though it does 
the same as TCriticalSection.TryEnter.


In the end I stuck in code to increment/decrement a counter, and 
looked for it to be explicitly 0 or 1.




___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Access site from app with login and password using http

2013-08-29 Thread Benito van der Zander
My Internet Tools (http://www.benibela.de/sources_en.html#internettools) 
are made for that.


For example:

uses simpleinternet;

var i: IXQValue;
begin
  for i in 
process(httpRequest(process('http://www.example.org/the/page/with/the/login/form', 
'form(/form, {username: '+username+', password: '+password+'})')),

   '//tr/td[2]') do
writeln(i.toString);
end.

will fill out the login form on the first page, then load the second 
page, and print the values of the second column of all table rows



On 08/28/2013 10:07 PM, Osvaldo Filho wrote:
Is there any example to access information on web site that requires 
authentication with login and password in form using http from a 
Lazarus application?



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Re: [Lazarus] Should TObject or TComponent have a Comment property?

2013-07-12 Thread Benito van der Zander


Enough digression - if considered carefully a comment about the 
purpose of an object belongs in the object definition itself.


I use Pasdoc for that

On 07/12/2013 08:07 AM, vfclists . wrote:




On 11 July 2013 23:07, Benito van der Zander ben...@benibela.de 
mailto:ben...@benibela.de wrote:


Annotations like in Java would be nice...


On 07/11/2013 10:22 PM, vfclists . wrote:

Should TObject or TComponent have a Comment property?

I think they should. One for the design itself and one for
describing the usage at design or runtime.

Smalltalk has it.

Consider it a version of the Hint property but for the developer

-- 
Frank Church


===
http://devblog.brahmancreations.com


--
___
Lazarus mailing list
laza...@lists.lazarus.freepascal.org  
mailto:laza...@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



--
___
Lazarus mailing list
laza...@lists.lazarus.freepascal.org
mailto:laza...@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



This attitude which exists in the Pascal community needs to end. I say 
Pascal not FreePascal because when I examine a lot of free Delphi 
libraries I see the same thing. Lots and lots of code and not a 
comment in sight. It makes stuff needlessly difficult. The simple fact 
is documentation is never going to happen because no one has time to 
create it with separate tools, not even the people writing the code 
themselves. Coding time is the best time for documentation because 
that is when the intent of the code is clear and fresh in the 
developers mind, and incurs minimal additional cost. After all it 
takes barely a minute or two to describe a function, and the same 
parsing tools compiling the code can pull out the comments and create 
documentation stubs if there is a need to flesh them out further, eg 
with examples etc


Even a lot of the funded open source libraries don't have the 
resources to create proper documentation. If you take Delphi for 
instance, since Turbo Pascal, Delphi 7 etc the quality of 
documentation has gone down and these are companies that are well funded.


Instead of doing the simple thing a purist attitude has been adopted 
which never does anyone any good.


It is time developers learn to treat other developers as consumers not 
people who are supposed to RTFC or RTFM. Developers are people who are 
supposed to put parts together just by examining the function 
parameters and the function descriptions rather than wade through 
loads of procedure definitions and sample code full of similar 
sounding and confusing names.


Enough digression - if considered carefully a comment about the 
purpose of an object belongs in the object definition itself. Why 
should interrogation about an object's purpose be handled by a whole 
subsystem of code which has precisely nothing to do with the object, 
ie the operating system, a help displaying program, a filename which 
is the help document, as well as a search string which is the object's 
name? Multiply that by the variety of help displaying programs for 
each operating system, then by the number of operating systems 
available then you can see how ridiculous the whole concept is. Just 
bureaucracy piled on bureaucracy and attachment to ill thought out 
convention and tradition. There is never a direct link between an 
object and the  help display programs available on the operating system.


There is a totally insane disconnect here. The Smalltalk guys got it 
right.


There can be an options to strip the comments out in the final 
deliverable just like the debugging information.


--
Frank Church

===
http://devblog.brahmancreations.com


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

[fpc-pascal] Feature proposal: function-based assignment operators

2013-03-28 Thread Benito van der Zander

Hi,
quite often you need to change a value relatively to another value.
For example:

  array1[array2[i]] := array1[array2[i]] + 42;

Luckily this can be written as

  array1[array2[i]] += 42;

Which is nice.

However, sometimes you do not need addition, but the minimum.
For example:

   array1[array2[i]] := min(array1[array2[i]], 42);

Now, you need to repeat all the array indices.

Which is very ugly.

So there should be an alternative syntax, similar to += :
I.e.:

   array1[array2[i]] min= 42;


More generally, if func is a 2-ary function, of type type(a) = type(b) 
= type(a), the syntax


a func= b

should become a := func(a, b)

(Or alternatively the syntax   a : func = b;  might be easier to parse)


Benito

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Re: Feature proposal: function-based assignment operators

2013-03-28 Thread Benito van der Zander

What's the benefit?

Same benefit as += to := ... +

You do not need to rewrite/compute the left side

How will it affect existing code?

Not at all, since old code using this, would not compile

Last but not least, will you implement it?

I can try

On 03/28/2013 04:20 PM, leledumbo wrote:

Hmm... Haskell? Or Nimrod? Or something else? What's the benefit? How will it
affect existing code? Last but not least, will you implement it?



--
View this message in context: 
http://free-pascal-general.1045716.n5.nabble.com/Feature-proposal-function-based-assignment-operators-tp5713868p5713870.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Feature proposal: function-based assignment operators

2013-03-28 Thread Benito van der Zander


There was already a discussion some time ago whether we should allow 
operators like or= and such as well and the result was simple: no. I 
consider this the same here. 


But it would be more consistent with +=

You can achieve a similar effect through type helpers in 2.7.1 though: 

looks cool, but I only have 2.6.2...




type
  TLongIntHelper = type helper for LongInt
procedure Min(aValue: LongInt);
  end;

procedure TLongIntHelper.Min(aValue: LongInt);
begin
  Self := Math.Min(Self, aValue);
end; 


Perhaps that should be defined in the rtl


On 03/28/2013 05:47 PM, Sven Barth wrote:

Am 28.03.2013 16:23, schrieb Benito van der Zander:

Hi,
quite often you need to change a value relatively to another value.
For example:

  array1[array2[i]] := array1[array2[i]] + 42;

Luckily this can be written as

  array1[array2[i]] += 42;

Which is nice.

However, sometimes you do not need addition, but the minimum.
For example:

   array1[array2[i]] := min(array1[array2[i]], 42);

Now, you need to repeat all the array indices.

Which is very ugly.

So there should be an alternative syntax, similar to += :
I.e.:

   array1[array2[i]] min= 42;


More generally, if func is a 2-ary function, of type type(a) = 
type(b) = type(a), the syntax


a func= b

should become a := func(a, b)

(Or alternatively the syntax   a : func = b;  might be easier to parse)

There was already a discussion some time ago whether we should allow 
operators like or= and such as well and the result was simple: no. I 
consider this the same here.


You can achieve a similar effect through type helpers in 2.7.1 though:

=== code begin ===

program mintest;

{$mode objfpc}

uses
  Math;

type
  TLongIntHelper = type helper for LongInt
procedure Min(aValue: LongInt);
  end;

procedure TLongIntHelper.Min(aValue: LongInt);
begin
  Self := Math.Min(Self, aValue);
end;

var
  arr: array[0..20] of LongInt;
  i: LongInt;
begin
  for i := Low(arr) to High(arr) do
arr[i] := i;

  for i := Low(arr) to High(arr) do
Write(arr[i], ' ');
  Writeln;

  arr[15].Min(10); // arr[15] is passed as Self to Min

  for i := Low(arr) to High(arr) do
Write(arr[i], ' ');
  Writeln;
end.

=== code end ===

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Feature proposal: function-based assignment operators

2013-03-28 Thread Benito van der Zander



Declare a custom function and mark it inline for efficiency. That also 
allows you to document it properly, have different implementations 
depending on the parameter types and so on. 


that's overkill if it is only an internal datastructure


our time would be better spent trying to persuade the core developers 
to tolerate extra operators like ⌊ for floor(), and then working out 
how to implement them :-) 
Or allow unicode identifier, and than defining ⌊ for ⌊= would just be a 
special case of func=



On 03/28/2013 04:45 PM, Mark Morgan Lloyd wrote:

Benito van der Zander wrote:

Hi,
quite often you need to change a value relatively to another value.
For example:

  array1[array2[i]] := array1[array2[i]] + 42;

Luckily this can be written as

  array1[array2[i]] += 42;

Which is nice.

However, sometimes you do not need addition, but the minimum.
For example:

   array1[array2[i]] := min(array1[array2[i]], 42);

Now, you need to repeat all the array indices.

Which is very ugly.

So there should be an alternative syntax, similar to += :
I.e.:

   array1[array2[i]] min= 42;


Declare a custom function and mark it inline for efficiency. That also 
allows you to document it properly, have different implementations 
depending on the parameter types and so on.


There really are limits to the extent that the underlying Pascal 
should be mangled further. Your time would be better spent trying to 
persuade the core developers to tolerate extra operators like ⌊ for 
floor(), and then working out how to implement them :-)


array1[array2[i]] := array1[array2[i]] ⌊ 42;
array1[array2[i]] ⌊= 42;


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Feature proposal: function-based assignment operators

2013-03-28 Thread Benito van der Zander


I would use Pascal (not C) and write

inc(array1[array2[i]],42);


well, that won't help with min

On 03/28/2013 06:14 PM, Jürgen Hestermann wrote:

Benito van der Zander wrote:

Luckily this can be written as
  array1[array2[i]] += 42;


I would use Pascal (not C) and write

inc(array1[array2[i]],42);

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Feature proposal: function-based assignment operators

2013-03-28 Thread Benito van der Zander
Now *that* is ugly. It would take me quite a while to find out what 
happens here.


Perhaps :min= was better?


Why making Pascal look like C instead of using C?


C also does not support this :(

And it does not have arbitrary array index ranges



In the example case I would prefer the original or write 

In the real program I ended up with



if array1[array2[i]]42 then
array1[array2[i]] := 42; 


Then you have everything twice.

And if you have to change i to j, you might forget to change one


On 03/28/2013 06:26 PM, Jürgen Hestermann wrote:

Benito van der Zander wrote:

array1[array2[i]] := min(array1[array2[i]], 42);
Now, you need to repeat all the array indices.
Which is very ugly.
So there should be an alternative syntax, similar to += :
I.e.:
   array1[array2[i]] min= 42;


Now *that* is ugly. It would take me quite a while to find out what 
happens here.

What is assigned to what and when?
Why making Pascal look like C instead of using C?
In the example case I would prefer the original or write

if array1[array2[i]]42 then
array1[array2[i]] := 42;

or if performance is realy an issue you I would use an intermediate 
pointer to the array type:


var p : ^arrayelementtype;

p := @array1[array2[i]];
p^ := min(p^,42);
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


[fpc-pascal] Re: fcl-xml

2013-03-15 Thread Benito van der Zander
Hi, 

 What is the state of XPath?
 The readme says 'Should be fairly completed' - can I assume it works for 
 simple tasks?

If you need xpath, you might also want to look at my Internet Tools ( 
(http://benibela.de/sources_en.html#internettools), they contain a basically
complete XPath 2 implementation

Benito

 dev.dliw@... writes:

 
 Hi,
 working with fcl-xml some questions came together. Every hint is appreciated.
 
 1.
 No matter what I do and which (short  valid) xml file I use - getElementById 
 is always nil (tested with trunk and latest stable 2.6.2) and the same 
 applies 
 to TXMLDocument.IDs.
 I tried with ReadXMLFile and TDOMParser with different options - but the 
 result is always the same.
 ...
 
 Many thanks for any hint,
 d.l.i.w


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal