[Lazarus] Multi-platform console application, how to handle file paths?

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

[Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
I am writing a console application intended to be portable between
Windows and Linux and it uses files on the file system for
configuration and also for processing data.

Since the path delimiter is different on Unix and Windows I believe I
have to handle this in my code, but how?

I could create all paths inside the application using Windows
delimiters and then upon usage send them to a "platform filter" like
FixPlatformPath() below, which returns the string with the proper
delimiters for the platform.
Or else I have to check wherever the paths are dealt with and put
conditionals inside the code in many places.
Either way it feels a bit convoluted.

Is there a better way?

function FixPlatformPath(PathIn: string): string;
begin
  {$ifdef UNIX}
    Result:= StringReplace(PathIn, '\', PathDelim, [rfReplaceAll]);
  {$else}
    Result:= StringReplace(PathIn, '/', PathDelim, [rfReplaceAll]);
  {$endif}
end;

This would apply to all functions where files are handled such as
reading config data, creating data files or reading data files etc...


--
Bo Berglund
Developer in Sweden

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 29/10/2019 12.25, Bo Berglund via lazarus wrote:
> I am writing a console application intended to be portable between
> Windows and Linux and it uses files on the file system for
> configuration and also for processing data.
>
> Since the path delimiter is different on Unix and Windows I believe
> I have to handle this in my code, but how?

Thinking...

Define a something case {what system} array of strings. Depending on
the system detected, you use one or the other array of (constant?)
strings, that contains the paths. Assuming they are fixed.


- --
Cheers / Saludos,

                Carlos E. R.
                (from 15.1 x86_64 at Telcontar)
-----BEGIN PGP SIGNATURE-----

iF0EARECAB0WIQQZEb51mJKK1KpcU/W1MxgcbY1H1QUCXbgi9AAKCRC1MxgcbY1H
1dj2AJ9Qoqusdw0jaoFvLDSmiblv1bhjVQCfccLWxQ0mQO926h0mtAcS4tSADUk=
=/Ojl
-----END PGP SIGNATURE-----
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list

In Windows XP , it is possible to use "/" instead of "\" . Therefore , it is NOT necessary to make two different file path representations . I am not using any Windows now , therefore I can not say anything about last Windows versions .

It is very easy to check whether "/" is usable on your Windows : Use a file path with "/" . My opinion is that it will find the related file assuming that your file path is correct other than "/" .



Mehmet Erol Sanliturk





On Tue, Oct 29, 2019 at 2:25 PM Bo Berglund via lazarus <[hidden email]> wrote:
I am writing a console application intended to be portable between
Windows and Linux and it uses files on the file system for
configuration and also for processing data.

Since the path delimiter is different on Unix and Windows I believe I
have to handle this in my code, but how?

I could create all paths inside the application using Windows
delimiters and then upon usage send them to a "platform filter" like
FixPlatformPath() below, which returns the string with the proper
delimiters for the platform.
Or else I have to check wherever the paths are dealt with and put
conditionals inside the code in many places.
Either way it feels a bit convoluted.

Is there a better way?

function FixPlatformPath(PathIn: string): string;
begin
  {$ifdef UNIX}
    Result:= StringReplace(PathIn, '\', PathDelim, [rfReplaceAll]);
  {$else}
    Result:= StringReplace(PathIn, '/', PathDelim, [rfReplaceAll]);
  {$endif}
end;

This would apply to all functions where files are handled such as
reading config data, creating data files or reading data files etc...


--
Bo Berglund
Developer in Sweden

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list


On Tue, 29 Oct 2019, Bo Berglund via lazarus wrote:

> I am writing a console application intended to be portable between
> Windows and Linux and it uses files on the file system for
> configuration and also for processing data.
>
> Since the path delimiter is different on Unix and Windows I believe I
> have to handle this in my code, but how?
>
> I could create all paths inside the application using Windows
> delimiters and then upon usage send them to a "platform filter" like
> FixPlatformPath() below, which returns the string with the proper
> delimiters for the platform.
> Or else I have to check wherever the paths are dealt with and put
> conditionals inside the code in many places.
> Either way it feels a bit convoluted.
>
> Is there a better way?
>
> function FixPlatformPath(PathIn: string): string;
> begin
>  {$ifdef UNIX}
>    Result:= StringReplace(PathIn, '\', PathDelim, [rfReplaceAll]);
>  {$else}
>    Result:= StringReplace(PathIn, '/', PathDelim, [rfReplaceAll]);
>  {$endif}
> end;
>
> This would apply to all functions where files are handled such as
> reading config data, creating data files or reading data files etc...

1. Don't hardcode '/' or '\', use the PathDelim constant instead.
    You will not need any ifdefs.

2. FPC does not care whether you use '\' or '/', and windows normally will
accept '/' as well.

3. your "fixplatformpath' exists in FPC, in 2 forms:

    https://www.freepascal.org/docs-html/current/rtl/sysutils/dodirseparators.html
    https://www.freepascal.org/docs-html/current/rtl/sysutils/setdirseparators.html

    There are many routines that handle all this transparently:

    https://www.freepascal.org/docs-html/current/rtl/sysutils/filenameroutines.html

Michael.
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On Tue, 29 Oct 2019 14:32:18 +0300, Mehmet Erol Sanliturk via lazarus
<[hidden email]> wrote:

>In Windows XP , it is possible to use "/" instead of "\" . Therefore , it
>is NOT necessary to make two different file path representations . I am not
>using any Windows now , therefore I can not say anything about last Windows
>versions .
>
>It is very easy to check whether "/" is usable on your Windows : Use a file
>path with "/" . My opinion is that it will find the related file assuming
>that your file path is correct other than "/" .
>

OK, did not know this.
Now tested on Windows 7 via Windows Explorer and the command line.
Both work fine...
So I will use forward slashes in all paths from now on.


--
Bo Berglund
Developer in Sweden

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On Tue, 29 Oct 2019 12:43:51 +0100 (CET), Michael Van Canneyt via
lazarus <[hidden email]> wrote:

>1. Don't hardcode '/' or '\', use the PathDelim constant instead.
>    You will not need any ifdefs.

The whole thing is that paths might be read from config or other data
files and so they will come in either with / or \.
I cannot use PathDelim in the target spec because that would not find
the erroneous delimiters.

That said, both you and Mehmet pointed out that Windows accepts both
delimiters, which I did not know. I have been around too long so I
remember the old days...

Anyway, given that the delimiters do not matter I will just code for
Linux (the main platform) and not bother with the Windows case.

Thanks for your information!

--
Bo Berglund
Developer in Sweden

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list


On Tue, 29 Oct 2019, Bo Berglund via lazarus wrote:

> On Tue, 29 Oct 2019 12:43:51 +0100 (CET), Michael Van Canneyt via
> lazarus <[hidden email]> wrote:
>
>> 1. Don't hardcode '/' or '\', use the PathDelim constant instead.
>>    You will not need any ifdefs.
>
> The whole thing is that paths might be read from config or other data
> files and so they will come in either with / or \.
> I cannot use PathDelim in the target spec because that would not find
> the erroneous delimiters.

Hence the setdirseparators call. As soon as you read a path from a file,
correct it with SetDirSeparators. For the rest you use PathDelim and all
will be well.

You're not the only one to have to deal with this, we've all been there :-)

Michael.
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On 29/10/2019 12:07 pm, Bo Berglund via lazarus wrote:
> I have been around too long so I
> remember the old days...

Same. Windows should get with the times and switch to Unix. ;-)

On a side note:
After all, Windows still start the drive letters with C: and considering
that no PC is the last decade or two has shipped with floppy drives,
maybe they could start from A: instead. Most of the people I work with
have NO idea why Windows starts with C: as the boot drive instead of A: :-P

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
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list

Op 2019-10-29 om 21:08 schreef Graeme Geldenhuys via lazarus:
> On 29/10/2019 12:07 pm, Bo Berglund via lazarus wrote:
>> I have been around too long so I
>> remember the old days...
> Most of the people I work with
> have NO idea why Windows starts with C: as the boot drive instead of A: :-P
I'm already happy if they can distinguish actual drive files from "most
recent used" style virtual folders.:-)
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
> maybe they could start from A:

Noooo :-)     I work offshore for a variety of clients, and using their PCs. 

I always ensure my USB key mount at B: (so I don't have to tweak paths in my fpc and Lazarus installs),
I code in an encrypted folder that I mount at A: (using Veracrypt).

The encrypted drive also holds both GIT and SVN repositories.

Been doing this for 10 years now, no conflict on any client PC anywhere :-)   I like those holes in A: and B:   It's so convenient that my system at home is the same.

Cheers

Mike

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application,&nbsp; &nbsp; &nbsp; &nbsp; how to handle file paths?

Free Pascal - Lazarus mailing list
For me A: is  always my archives and B: is my regular backup. Easy to remember!


---- On Tue, 29 Oct 2019 17:16:56 -0400 Michael Thompson via lazarus <[hidden email]> wrote ----

> maybe they could start from A:

Noooo :-)     I work offshore for a variety of clients, and using their PCs. 

I always ensure my USB key mount at B: (so I don't have to tweak paths in my fpc and Lazarus installs),
I code in an encrypted folder that I mount at A: (using Veracrypt).



--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On 29/10/2019 9:16 pm, Michael Thompson wrote:
> Been doing this for 10 years now, no conflict on any client PC
> anywhere :-) I like those holes in A: and B:

:-D  Very clever indeed! Make full use of those relics. I wonder why
Microsoft didn't think of that for USB drives.

Regards,
  Graeme
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
Graeme Geldenhuys via lazarus <[hidden email]> schrieb am Di., 29. Okt. 2019, 21:08:
On 29/10/2019 12:07 pm, Bo Berglund via lazarus wrote:
> I have been around too long so I
> remember the old days...

Same. Windows should get with the times and switch to Unix. ;-)

On a side note:
After all, Windows still start the drive letters with C: and considering
that no PC is the last decade or two has shipped with floppy drives,
maybe they could start from A: instead. Most of the people I work with
have NO idea why Windows starts with C: as the boot drive instead of A: :-P

There is still enough software out there that assumes A: and B: are floppy drives and thus either ignores them or handles them especially (I fixed such a relic in our own software just two weeks ago, because a customer had his optical drives as A: and B:, otherwise we wouldn't have noticed that... ). 

Regards, 
Sven 

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On Tue, 29 Oct 2019 13:07:50 +0100
Bo Berglund via lazarus <[hidden email]> wrote:

>[...]
> Anyway, given that the delimiters do not matter I will just code for
> Linux (the main platform) and not bother with the Windows case.

There are some differences. For example filenames are case
insensitive.
FileExists returns false under Windows for directories.
Windows allows empty names, so these are different things: 'C:\a',
'C:\a\', 'C:\a\\'.
Windows has one current directory per partition.
Windows knows specials paths starting with '\\'.
etc.

Mattias

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
On Wed, 30 Oct 2019 10:50:39 +0100, Mattias Gaertner via lazarus
<[hidden email]> wrote:

>Windows knows specials paths starting with '\\'.

But I don't! :(
What is special with these? I have noted tghat if I spell a path wrong
(copy paste or oterwise) and get two \\ instead of one it still works
fine. But maybe there is some special meaning too?

Anyway, I ran the program test on Windows now using the suggested
function:
FindAllFiles(FileList, TaskDir, '*.conf', false);
FileList shows the full path to the files but excluding the drive
letter, which is not part of the "TaskDir" variable.
It checked the dir in the current drive (where the exe file is
located).


--
Bo Berglund
Developer in Sweden

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] Multi-platform console application, how to handle file paths?

Free Pascal - Lazarus mailing list
On Wed, Oct 30, 2019 at 11:42 AM Bo Berglund via lazarus
<[hidden email]> wrote:

> >Windows knows specials paths starting with '\\'.
>
> But I don't! :(
> What is special with these?

\\?\C:\foo\bar\..\..
is not the same path as
C:\foo\bar\..\.. (which basically is C:\)

If a path starts with \\?\ like above, all characters in the path are
taken literally (so you cannot construct a relative path), or ot is
used to build a UNC path: \\?\UNC\
IIRC then also device names start with \\.\ or something the like.

See https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file

Bart



--
Bart
--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus