[fpc-devel] Tail recursion optimization
Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). It isn't enabled yet because it still needs some fine tuning. The question is however when should it be enabled? With -OoTAILREC? -O3? Something different? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Op Tue, 10 Oct 2006, schreef Florian Klaempfl: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). Wow! It isn't enabled yet because it still needs some fine tuning. The question is however when should it be enabled? With -OoTAILREC? -O3? Something different? If the optimization needs significant processing power, -O3. If it doesn't but is debug safe, -O1, if it is not debug safe, -O2. A separate option -OoTAILREC is IMHO not necessary. Daniël___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
On 10 okt 2006, at 10:05, Daniël Mantione wrote: If the optimization needs significant processing power, -O3. If it doesn't but is debug safe, -O1, if it is not debug safe, -O2. It's definitely not debug safe, since it messes up stack information. A separate option -OoTAILREC is IMHO not necessary. All possible optimizations have their -Oo-switch for individual enabling disabling (like regvars, peepholeopt, asmcse, stackframe, loopunroll). It's both useful for debugging the individual optimizations and in case a user's program is incompatible with a particular optimization (either due to a bug in the optimization or an inherent requirement -- e.g., we could add -Oonostackframe at the end of the compiler switches for the RTL's object unit when compiling for x86). Jonas___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Florian Klaempfl wrote: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). It isn't enabled yet because it still needs some fine tuning. The question is however when should it be enabled? With -OoTAILREC? -O3? Something different? It doesn't always improve performance ? It takes much more code ? Micha ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Daniël Mantione wrote: Op Tue, 10 Oct 2006, schreef Florian Klaempfl: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). Wow! Well, it's use for real world applications is limited but for the typical recursive useless benchmark stuff it's nice to have and it wasn't much work. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Jonas Maebe wrote: On 10 okt 2006, at 10:05, Daniël Mantione wrote: If the optimization needs significant processing power, -O3. If it doesn't but is debug safe, -O1, if it is not debug safe, -O2. It's definitely not debug safe, since it messes up stack information. Not really. I didn't try it yet but it shouldn't mess up much. The optimziation is done completely on the node level, the pascal code would look like http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=156 except that there are temps involved to calculate the new parameters because calculating one parameter could require the original value of another one. A separate option -OoTAILREC is IMHO not necessary. All possible optimizations have their -Oo-switch for individual enabling disabling (like regvars, peepholeopt, asmcse, stackframe, loopunroll). It's both useful for debugging the individual optimizations and in case a user's program is incompatible with a particular optimization (either due to a bug in the optimization or an inherent requirement -- So it will probably -OoTAILREC and automatically included in -O2. e.g., we could add -Oonostackframe at the end of the compiler switches for the RTL's object unit when compiling for x86). What we still need are switches in the sources to enable particular optimizations. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
On Tuesday 10 October 2006 08:29, Florian Klaempfl wrote: Daniël Mantione wrote: Op Tue, 10 Oct 2006, schreef Florian Klaempfl: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). Wow! Well, it's use for real world applications is limited Limited to what? Binary tree data structures only? ;) Vinzent. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Micha Nelissen wrote: Florian Klaempfl wrote: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). It isn't enabled yet because it still needs some fine tuning. The question is however when should it be enabled? With -OoTAILREC? -O3? Something different? It doesn't always improve performance ? It takes much more code ? ? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Vinzent Hoefler wrote: On Tuesday 10 October 2006 08:29, Florian Klaempfl wrote: Daniël Mantione wrote: Op Tue, 10 Oct 2006, schreef Florian Klaempfl: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). Wow! Well, it's use for real world applications is limited Limited to what? Binary tree data structures only? ;) Well, real world binary trees are usually limited by memory latencies because of their random access patterns so some tail recursion optimziation helps little. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Florian Klaempfl wrote: -OoTAILREC? -O3? Something different? It doesn't always improve performance ? It takes much more code ? ? I thought the difference between -O2 and -O3 is that -O3 is not actually guaranteed to improve global performance, for example due to the code expanding a lot. So therefore the question: does it always improve performance ? Does it blow up code size a lot ? Micha ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
On 10 okt 2006, at 10:34, Florian Klaempfl wrote: Not really. I didn't try it yet but it shouldn't mess up much. The optimziation is done completely on the node level, the pascal code would look like http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=156 except that there are temps involved to calculate the new parameters because calculating one parameter could require the original value of another one. Which means that the parameter values cannot be properly seen in the debugger, no? Also, do you actually insert goto/label nodes? That would degrade the performance of the register variable assignment because of the current limitations concerning flow analysis (i.e., for sufficiently complex routines, the tail recursion optimization may currently result in performance degradation rather than improvement compared to using regvars without it). e.g., we could add -Oonostackframe at the end of the compiler switches for the RTL's object unit when compiling for x86). What we still need are switches in the sources to enable particular optimizations. {$optimization nostackframe} should work. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Op Tue, 10 Oct 2006, schreef Micha Nelissen: Florian Klaempfl wrote: Yesterday, I've implemented tail recursion optimization (http://svn.freepascal.org/svn/fpc/trunk/compiler/opttail.pas resulting in http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=158 pp11 is the new compiler, fpc11 the old, both are 2.1.1). It isn't enabled yet because it still needs some fine tuning. The question is however when should it be enabled? With -OoTAILREC? -O3? Something different? It doesn't always improve performance ? It takes much more code ? I don't think so, because for tail recursion optimization you assign the parameters to the local variables (should not be larger than pushing them) and then jump to the start of the procedure (should not be larger than calling). Daniël___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Jonas Maebe wrote: On 10 okt 2006, at 10:34, Florian Klaempfl wrote: Not really. I didn't try it yet but it shouldn't mess up much. The optimziation is done completely on the node level, the pascal code would look like http://www.hu.freepascal.org/fpcircbot/cgipastebin?msgid=156 except that there are temps involved to calculate the new parameters because calculating one parameter could require the original value of another one. Which means that the parameter values cannot be properly seen in the debugger, no? This is a hidden step, but the callstack window isn't done properly, that's true. Also, do you actually insert goto/label nodes? That would degrade the performance of the register variable assignment because of the current limitations concerning flow analysis (i.e., for sufficiently complex routines, the tail recursion optimization may currently result in performance degradation rather than improvement compared to using regvars without it). The recursive call is usually inside an if anyways so the ssa optimizer is lost anyways, no? But as I said, for the usual benchmark case it works great (the code is almost on pair with gcc after a quick look at it): .balign 16,0x90 .globl P$ACKERMAN_ACK$LONGINT$LONGINT$$LONGINT P$ACKERMAN_ACK$LONGINT$LONGINT$$LONGINT: # Temps allocated between esp+0 and esp+16 # [ackermann.pp] # [8] begin subl$16,%esp # Var M located in register ebx # Var N located in register esi # Var $result located in register edi movl%ebx,(%esp) movl%esi,4(%esp) movl%edi,8(%esp) movl%eax,%ebx movl%edx,%esi .Lj5: # [9] if M = 0 then Ack := N+1 testl %ebx,%ebx jne .Lj7 movl%esi,%eax incl%eax movl%eax,%edi jmp .Lj10 .Lj7: # [10] else if N = 0 then Ack := Ack(M-1, 1) testl %esi,%esi jne .Lj12 movl$1,%edx decl%ebx movl%edx,%esi jmp .Lj5 .Lj12: # [11] else Ack := Ack(M-1, Ack(M, N-1)); movl%esi,%edx decl%edx movl%ebx,%eax callP$ACKERMAN_ACK$LONGINT$LONGINT$$LONGINT decl%ebx movl%eax,%esi jmp .Lj5 .Lj21: .Lj10: # [12] end; movl%edi,%eax movl(%esp),%ebx movl4(%esp),%esi movl8(%esp),%edi addl$16,%esp ret BTW: Does the assembler optimizer track flag usage? Then we could remove some of the movl%esi,%eax incl%eax like pairs. e.g., we could add -Oonostackframe at the end of the compiler switches for the RTL's object unit when compiling for x86). What we still need are switches in the sources to enable particular optimizations. {$optimization nostackframe} should work. Didn't know about it :) ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
On 10 okt 2006, at 11:09, Florian Klaempfl wrote: Also, do you actually insert goto/label nodes? That would degrade the performance of the register variable assignment because of the current limitations concerning flow analysis (i.e., for sufficiently complex routines, the tail recursion optimization may currently result in performance degradation rather than improvement compared to using regvars without it). The recursive call is usually inside an if anyways so the ssa optimizer is lost anyways, no? For the part inside the if: yes. But not for the part coming before it. What's more important however is that goto/label not only removes the usage of SSA, it also means that all register variables are allocated at the start of the function and only freed at the end. Without goto/label, register variables are only allocated between their first and last use (usage in a loop means allocation until the end of that loop). BTW: Does the assembler optimizer track flag usage? Then we could remove some of the movl%esi,%eax incl%eax like pairs. There's a FlagsUsed field in the ttaiprop record which is set to true if the flags result of that instruction is used. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Recompilation optimization patch
Hi, I'm trying to reduce the number of recompilation needed of units. Currently compiler very often recompiles due to possibility of changed inlined functions being present. Attached patch tries store this info in ppu (whether inlined functions are present). Is this a good patch ? Btw, question: is po_inline set for a pd's procoptions when optimizations are disabled (so functions are not inlined anyway, I assume?) Micha Index: symdef.pas === --- symdef.pas (revision 4846) +++ symdef.pas (working copy) @@ -3135,6 +3135,8 @@ ppufile.putbyte(sizeof(funcretloc[callerside])); ppufile.putdata(funcretloc[callerside],sizeof(funcretloc[callerside])); end; +if (po_inline in procoptions) then + ppufile.header.flags := ppufile.header.flags or uf_has_inline; end; Index: fppu.pas === --- fppu.pas(revision 4846) +++ fppu.pas(working copy) @@ -1232,6 +1232,7 @@ if (pu.u.interface_crcpu.interface_checksum) or ( ((ppufile.header.flags and uf_release)=0) and + ((ppufile.header.flags and uf_has_inline)0) and (pu.u.crcpu.checksum) ) then begin Index: ppu.pas === --- ppu.pas (revision 4846) +++ ppu.pas (working copy) @@ -147,6 +147,7 @@ uf_uses_variants = $4; { this unit uses variants } uf_has_resourcefiles = $8; { this unit has external resources (using $R directive)} uf_has_exports = $10; { this module or a used unit has exports } + uf_has_inline = $20; { this unit exports inlined functions } type ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Jonas Maebe wrote: The recursive call is usually inside an if anyways so the ssa optimizer is lost anyways, no? For the part inside the if: yes. But not for the part coming before it. What's more important however is that goto/label not only removes the usage of SSA, it also means that all register variables are allocated at the start of the function and only freed at the end. Without goto/label, register variables are only allocated between their first and last use (usage in a loop means allocation until the end of that loop). Practical argument: the assembler code _is_ better for the code I tested and up to as twice as fast as the original one. Theoretical argument: - using the tail goto you've one function with one set of variables being active across the the whole function - using a recursive call you've at least two sets of variables: the caller and the callee ones. Though one set is only active at a limited part of the function, the set of the caller is still in use while the callee is called though they (the caller variables) are spilled. BTW: Does the assembler optimizer track flag usage? Then we could remove some of the movl%esi,%eax incl%eax like pairs. There's a FlagsUsed field in the ttaiprop record which is set to true if the flags result of that instruction is used. I guess it could be used to change to code above to leal 1(%esi),%eax ? Or is this slower on some CPUs? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Op Tue, 10 Oct 2006, schreef Florian Klaempfl: There's a FlagsUsed field in the ttaiprop record which is set to true if the flags result of that instruction is used. I guess it could be used to change to code above to leal 1(%esi),%eax ? Or is this slower on some CPUs? In the worst case, as fast. Some cpu's use an extra clock cycle through the ALU to calculate the effective address (Pentium 1 if I recall well). RISC86 cpus (k6..opteron) use their load/store unit to calculate this, so it might speed up because one extra ALU is free, or slow down because the load/store unit is occupied by another instruction. Daniël___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
On 10 okt 2006, at 13:46, Florian Klaempfl wrote: Practical argument: the assembler code _is_ better for the code I tested and up to as twice as fast as the original one. That's indeed true for an extremely small function with so few local variables/parameters that even on an i386 it doesn't need spilling in the absence of register allocation optimizations. That's why I said it *may* currently degrade performance in more complex functions (it also may not, I really don't know, it was just a remark). Theoretical argument: - using the tail goto you've one function with one set of variables being active across the the whole function - using a recursive call you've at least two sets of variables: the caller and the callee ones. Though one set is only active at a limited part of the function, the set of the caller is still in use while the callee is called though they (the caller variables) are spilled. The first point is just as much a downside as an upside in the current situation, because parameters/variables which are used without being destroyed by some function call can normally be put in a (reusable) volatile register. Now they need a non-volatile register during the entire function. The fact that you get such a speedup is in my view mainly an indication of the fact that the function barely does anything, and that almost half the time is spent in setting up and tearing down stack frames. So it's logical that register allocation has little influence and that optimizations which remove this stack frame logic help a lot. I guess it could be used to change to code above to leal 1(%esi),%eax ? Yes. Or is this slower on some CPUs? I don't know. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tail recursion optimization
Jonas Maebe wrote: [...] Well, basically I agree with all your points ;) That's why I said the optimization is almost useless for real world programs. Nevertheless it helps for the benchmarks and gcc does it to. I'll try to find out the influence on the compiler/rtl, there are some examples where it applies (from ftl\inc\objpas.inc): class function TObject.getinterfaceentry(const iid : tguid) : pinterfaceentry; var i: integer; intftable: pinterfacetable; Res: pinterfaceentry; begin getinterfaceentry:=nil; intftable:=pinterfacetable((pointer(Self)+vmtIntfTable)^); if assigned(intftable) then begin i:=intftable^.EntryCount; Res:[EMAIL PROTECTED]; while (i0) and not (assigned(Res^.iid) and IsGUIDEqual(Res^.iid^,iid)) do begin inc(Res); dec(i); end; if (i0) then getinterfaceentry:=Res; end; if (getinterfaceentry=nil)and not(classparent=nil) then getinterfaceentry:=classparent.getinterfaceentry(iid) end; ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Default strings encoding
Hello, If I have a ansistring, and cast that to a WideString, fpc is converting from which encoding to which encoding? ansistring can hold utf-8 also, not only iso. I'm not sure what WideString holds. Maybe UTF-16? Or a limited UTF-16 with only 2 bytes characters. thanks, -- Felipe Monteiro de Carvalho ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Default strings encoding
Op Tue, 10 Oct 2006, schreef Felipe Monteiro de Carvalho: Hello, If I have a ansistring, and cast that to a WideString, fpc is converting from which encoding to which encoding? Without widestring manager, it converts iso-8859-1 to UCS-2. ansistring can hold utf-8 also, not only iso. Yes, but in that case, declare it as UTF8string. There exist functions UTF8encode and UTF8decode to convert between an UTF8string and a widestring. I'm not sure what WideString holds. Maybe UTF-16? Or a limited UTF-16 with only 2 bytes characters. UCS-2. Basically this is UTF-16 with only 2-byte characters, allthough there are small differences in the high regions; UCS-2 is code points $0..$, while UTF-16 has facilities to allow for multiword characters. Daniël___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Recompilation optimization patch
Hi, I'm trying to reduce the number of recompilation needed of units. Currently compiler very often recompiles due to possibility of changed inlined functions being present. Attached patch tries store this info in ppu (whether inlined functions are present). Is this a good patch ? Btw, question: is po_inline set for a pd's procoptions when optimizations are disabled (so functions are not inlined anyway, I assume?) This is not correct. Also other things like calling conventions can change in delphi mode. In ppu.pas at line 33 you can enable {$define INTFPPU} then a ppu.intf will be generated that contains the info from the interface only. A rewrite of the unit handling is planned, but that will be a 2.3 todo. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Recompilation optimization patch
Peter Vreman wrote: This is not correct. Also other things like calling conventions can change in delphi mode. In ppu.pas at line 33 you can enable {$define INTFPPU} Because the calling convention is only specified in the implementation ? Micha ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
RE: [fpc-devel] Default strings encoding
I'm not sure what WideString holds. Maybe UTF-16? Or a limited UTF-16 with only 2 bytes characters. UCS-2. Basically this is UTF-16 with only 2-byte characters, allthough there are small differences in the high regions; UCS-2 is code points $0..$, while UTF-16 has facilities to allow for multiword characters. there is nothing intrinsic about how widestring is implemented that stops it holding UTF-16 multiword characters, its just a matter of whether the routines its passed to do (on windows i belive surrogate support depends on a registry setting and is disabled by default on western editions). ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] FindFirst
Hi, Can the FindFirst optimization in 2.1.1 for unix/sysutils.pp be merged to 2.0.5 ? Revision 4772. Not only is it more efficient, it also fixes a bug: I cannot find a single directory with FindFirst in 2.0.5. Furthermore, attached is a patch for another optimization: do not allocate a record in case user is requesting info for a single file. Apply in rtl/unix please. Thanks, Micha Index: sysutils.pp === --- sysutils.pp (revision 4823) +++ sysutils.pp (working copy) @@ -424,9 +424,9 @@ if not fpstat(s,st)=0 then exit; WinAttr:=LinuxToWinAttr(PChar(s),st); - If ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then + If (f.FindHandle = nil) or ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then Begin - f.Name:=Copy(s,PUnixFindData(f.FindHandle)^.NamePos+1,Length(s)); + f.Name:=ExtractFileName(s); f.Attr:=WinAttr; f.Size:=st.st_Size; f.Mode:=st.st_mode; @@ -503,26 +503,27 @@ fillchar(Rslt,sizeof(Rslt),0); if Path='' then exit; - { Allocate UnixFindData } - New(UnixFindData); - FillChar(UnixFindData^,sizeof(UnixFindData^),0); - Rslt.FindHandle:=UnixFindData; - {Create Info} - UnixFindData^.SearchSpec := Path; - {We always also search for readonly and archive, regardless of Attr:} - UnixFindData^.SearchAttr := Attr or faarchive or fareadonly; - UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec); - while (UnixFindData^.NamePos0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]'/') do - dec(UnixFindData^.NamePos); {Wildcards?} if (Pos('?',Path)=0) and (Pos('*',Path)=0) then begin if FindGetFileInfo(Path,Rslt) then Result:=0; - UnixFindData^.SearchType:=1; end - else -Result:=FindNext(Rslt); + else + begin +{ Allocate UnixFindData } +New(UnixFindData); +FillChar(UnixFindData^,sizeof(UnixFindData^),0); +Rslt.FindHandle:=UnixFindData; +{Create Info} +UnixFindData^.SearchSpec := Path; +{We always also search for readonly and archive, regardless of Attr:} +UnixFindData^.SearchAttr := Attr or faarchive or fareadonly; +UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec); +while (UnixFindData^.NamePos0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]'/') do + dec(UnixFindData^.NamePos); + Result:=FindNext(Rslt); + end; End; ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel