FreeBASIC file paths

General discussion for topics related to the FreeBASIC project or its community.
Berkeley
Posts: 64
Joined: Jun 08, 2024 15:03

FreeBASIC file paths

Post by Berkeley »

FreeBASIC should platform-independently support some "system folder" paths, e.g. "%HOME%" ("%HOME%/user.cfg") to access the user's home folder. Among other things there should be a central FreeBASIC folder containing data files used by libraries or similiar - whereever FinalBASIC is "installed". The real path is depending on the destination platform, a programmer shouldn't worry about and especially not goofying around with #IF Defined(__FB_WIN32__) and such stuff.

Some other suggestions:
%SHARED% resp. %SHAREDHOME% - home "all users" ?
%APPDATA%/myprogram/ - app data/configurations/preferences of local user
%SHAREDAPPDATA% - all users
%DOCUMENTS%
%SHAREDDOCUMENTS%
perhaps %GAMEDATA% - e.g. "%DOCUMENTS%/games/" for save files - Microsoft hides the "AppData" path... Because of this some games are putting their stuff directly in the documents folder, which makes a big mess (like the config files in a Linux' home folder)
%PICTURES%
%MUSIC%
%COLLECTION:PICTURES% - "meta folders" ?
... ?
%SYSTEM% => "Windows" folder for example might not make much sense.
%APPPATH% - "Program files" for programming installers ?

If the destination platform doesn't have a corresponding scheme, it will get one.
Berkeley
Posts: 64
Joined: Jun 08, 2024 15:03

Re: FreeBASIC file paths

Post by Berkeley »

There should be a central path for FreeBASIC data, for all programs using special FreeBASIC functions resp. used by FreeBASIC libraries.

But where ? Suggestions !

All Users/App Data ? Program Files/FreeBASIC.rsc/ ? - It's ment for static data, might be updated/complemented, but not for saving preferences or something.

/opt/FreeBASIC.rsc/ in Unix ?
paul doe
Moderator
Posts: 1793
Joined: Jul 25, 2017 17:22
Location: Argentina
Contact:

Re: FreeBASIC file paths

Post by paul doe »

Berkeley wrote: Sep 16, 2024 20:09 There should be a central path for FreeBASIC data, for all programs using special FreeBASIC functions resp. used by FreeBASIC libraries.
What are you faffing about now? Which 'FreeBasic data' are you talking about? Executables are standalone, unless you use a library. And where those need to go is OS specific.

Other than that, it's up to the app to manage its own data. As it should be.
shakirabelva
Posts: 2
Joined: Sep 17, 2024 6:33
Location: India
Contact:

Re: FreeBASIC file paths

Post by shakirabelva »

Share more info about this!
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC file paths

Post by dodicat »

You can somewhat automate using crt.bi

Code: Select all


#include "crt.bi"
#include "file.bi"
dim as string file =*_tempnam(NULL, "MyTestfile.txt")

Shell("echo Hello from: "+chr(34)+file+chr(34)+" >> " +file) 'chr(34)="

Var f=Freefile,txt=""
    Open file For Binary As #f
    var L=Lof(f)
    If L>0 Then 
        txt = String(L,0)
        Get #f, , txt
    End If
    Close #f

print txt

print fileexists(file)
kill file
print fileexists(file)
sleep

 
But I see no real benefit in doing this, and I use Windows for this.
UEZ
Posts: 1006
Joined: May 05, 2017 19:59
Location: Germany

Re: FreeBASIC file paths

Post by UEZ »

Windows API:

Code: Select all

'Coded by UEZ build 2024-09-17
#include "windows.bi"

Function _WinAPI_GetEnvironmentVariable(sEnvVar As String) As String
	Dim As ULong l = GetEnvironmentVariable(sEnvVar, 0, 0)
	If l < 1 Then Return ""
	Dim As ZString Ptr pEnvDir = CAllocate(l)
	Dim As String sEnvPath = ""
	If GetEnvironmentVariable(sEnvVar, pEnvDir, l) <> 0 Then sEnvPath = pEnvDir[0] 
	Deallocate(pEnvDir)
	Return sEnvPath
End Function

? _WinAPI_GetEnvironmentVariable("APPDATA")
Sleep
Berkeley
Posts: 64
Joined: Jun 08, 2024 15:03

Re: FreeBASIC file paths

Post by Berkeley »

FreeBASIC should be platform independent. Therefore it should be not the job of the programmer to determine correct paths. BASIC should be easy, not cryptic like "#ifdef __WIN_32 #include "windows.bi" RegExPath path=GetRegEx... " just to determine the home folder. You may understand that "OPEN "%HOME%/..." FOR ..." would be much easier. Especially, if this works for Windows, Linux, BSD and Mac OS perfectly...

Nowadays, applications are typically no longer standalone - only in their one own folder, and this makes sense anyway. You want to save your work for instance and backup this, not a copy of your whole office suite. Same applies for savegames. And normally you can't write in the folder where the program files are, other users shouldn't access your work but use the application. But every platform has its own concept and naming where to put files.

Such like this "FreeBASIC" folder would contain shareable data like stringtables, fonts, icons and bitmaps. There should be a clear agreement for it, so you don't get a big mess because everyone uses his own path convention.
srvaldez
Posts: 3505
Joined: Sep 25, 2005 21:54

Re: FreeBASIC file paths

Post by srvaldez »

Berkeley
if you are so unhappy with the way FreeBAsic does things then why bother using it?
use a language that you like and be happy instead of complaining all the time
Jattenalle
Posts: 50
Joined: Nov 17, 2023 14:41
Contact:

Re: FreeBASIC file paths

Post by Jattenalle »

UEZ wrote: Sep 17, 2024 12:12 Windows API:

Code: Select all

'Coded by UEZ build 2024-09-17
#include "windows.bi"

Function _WinAPI_GetEnvironmentVariable(sEnvVar As String) As String
	Dim As ULong l = GetEnvironmentVariable(sEnvVar, 0, 0)
	If l < 1 Then Return ""
	Dim As ZString Ptr pEnvDir = CAllocate(l)
	Dim As String sEnvPath = ""
	If GetEnvironmentVariable(sEnvVar, pEnvDir, l) <> 0 Then sEnvPath = pEnvDir[0] 
	Deallocate(pEnvDir)
	Return sEnvPath
End Function

? _WinAPI_GetEnvironmentVariable("APPDATA")
Sleep
You can also use the native FB Environ command:

Code: Select all

print Environ("APPDATA")
Which already contains a list of all the environment values.
UEZ
Posts: 1006
Joined: May 05, 2017 19:59
Location: Germany

Re: FreeBASIC file paths

Post by UEZ »

Jattenalle wrote: Sep 17, 2024 19:28
UEZ wrote: Sep 17, 2024 12:12 Windows API:

Code: Select all

'Coded by UEZ build 2024-09-17
#include "windows.bi"

Function _WinAPI_GetEnvironmentVariable(sEnvVar As String) As String
	Dim As ULong l = GetEnvironmentVariable(sEnvVar, 0, 0)
	If l < 1 Then Return ""
	Dim As ZString Ptr pEnvDir = CAllocate(l)
	Dim As String sEnvPath = ""
	If GetEnvironmentVariable(sEnvVar, pEnvDir, l) <> 0 Then sEnvPath = pEnvDir[0] 
	Deallocate(pEnvDir)
	Return sEnvPath
End Function

? _WinAPI_GetEnvironmentVariable("APPDATA")
Sleep
You can also use the native FB Environ command:

Code: Select all

print Environ("APPDATA")
Which already contains a list of all the environment values.
I didn't know that internal function - thanks for the tip.
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC file paths

Post by dodicat »

Or shell which is more powerful than environ (gets more environment variables).

Code: Select all

 shell("echo "+"%"+"APPDATA"+"%") 
sleep 
UEZ
Posts: 1006
Joined: May 05, 2017 19:59
Location: Germany

Re: FreeBASIC file paths

Post by UEZ »

dodicat wrote: Sep 17, 2024 21:13 Or shell which is more powerful than environ (gets more environment variables).

Code: Select all

 shell("echo "+"%"+"APPDATA"+"%") 
sleep 
I think the disadvantage here is the way over the file i/o to save the output to a variable.
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC file paths

Post by dodicat »

You can pipe shell commands to a string, including the APPDATA

Code: Select all


 #include "crt.bi"
Declare Function stats Cdecl Alias "_stat"(As zstring Ptr,As Any Ptr) As Integer

 Function pipeout(Byval s As String="") Byref As String
    Var f=Freefile
    Dim As String tmp
    Open Pipe s For Input As #f 
    s=""
    Do Until Eof(f)
        Line Input #f,tmp
        s+=tmp+Chr(10)
    Loop
    Close #f
    Return s
End Function 

Function isfolder(path As zstring Ptr) As Long
    #define S_ISDIR(m)   (((m) And &hF000) = &h4000)
    Dim As stat statbuf
    If (stats(path, @statbuf) <> 0) Then Return 0
    Return S_ISDIR(statbuf.st_mode)
End Function


dim as string s=pipeout("echo "+"%"+"APPDATA"+"%")
print "'";rtrim(s,chr(10));"'"
print cbool(isfolder(rtrim(s,chr(10))))

sleep
 
  
Berkeley
Posts: 64
Joined: Jun 08, 2024 15:03

Re: FreeBASIC file paths

Post by Berkeley »

I already knew, but it doesn't cover all the needs, for example just your "Documents" folder, a savegame folder or a folder for config files. And it's inconsistent, "Environ" requires different key words under Windows and Linux. Maybe someone could explain which Windows folder has which purpose - "AppData": "Local", "LocalLow", "Roaming"... - Where should the config files be for the current user and for all users, what "standard folders" do you need and so on. We should create a "gold standard".

I wrote among other things this library: (just documentation part copied) If you have some annotations...

Code: Select all

'
' prefs.bi
'
' FreeBASIC preferences library
'
' handles application configuration/settings
' puts program parameters and setting files together in one union
'
' program parameters must have one of these forms:
' +x                  enable switch 'x' (case-sensitive letters or numbers)
' -x                  disable switch 'x'
' +x:"<string>"       assigns variable 'x' a value
' =<word> or --word   enables switch '<word>' (case-insensitive combination of letters or numbers)
' =<word>:"<string>" or --<word>:"<string>"  sets the variable '<word>' to given value
' text without specification defaults to "=file(<no.>):"<text>"", it's bad style to do though
' "+?" and "=help" are preserved for a help text with instructions on the console
'
' setting files are named ".cfg" and in "INI" format - Text:
' ' or ! for comments (recommended), further //, also "*" - resp. everything "illegal"
' [<section name>]
' <parameter name>[=,:]"<parameter content>"
' <parameter name>[=,:]<(no space chars)value: decimal, hexadecimal: 0x...,
'                       binary: 0b..., boolean: true/false, yes/no, on/off resp. 0/1/-1>
' you address parameters/variables by "<sectionname>.<parameter name>"
' names must only contain a-z/A-Z 0-9 "(" ")" "_" and "." for pseudo-subsections
' pseudo-subsection: "[A] ... [A.B]" vs. "[A] ... [B]" although "A.B" is a new/own section like "B"
' in this example, it looks like as if "A.B" is a subsection of "A"
' Note that only the first occurrence of a section will be regarded, it ends with the next section.
' Parameter names may also contain points if there are no sections, if you mix both you'll get
' unpredictable results.
' Parameter content must not be binary data, i.e. only characters above 31 allowed.
'
' config file paths can be a full path and filename
' You may use as filepath also (only alone without filename):
' %USER% - a/THE user-bound config file
' %APPDATA% - a config file for all users, mostly where the application's data is stored
' %LOCAL% - the local config file, might be write-protected(!) if installed in a "programs folder"
'
' PREFSNEW - initialises preferences library, not required to be called implicitely
'
' PREFSVALIDATE(STRING validargs) - checks whether the program parameters (arguments) are almost
'           valid (=true), returns false if unknown switches are used or arguments that expect values
'           without value.
'           "validargs" is a list like "o:,a,c,compile,file:" (without spaces), containing all
'           allowed arguments; returns false if a argument is found that is not in this list
'           "a" means a switch - "+/-a", "a:" a value, e.g. "+a:"13"", same for words - "=word"
'           or "=word:"value""
'           If a word or letter works as both, you have to add it twice e.g. "a,a:".
'           Values itself can't be validated this way. You may or may not add "?" and "help"
'           because the helptext should normally appear with invalid arguments anyway
'
' PREFSLOAD(STRING filename) - loads a supplementary preference file
'           values in the latest loaded files are read/changed with highest priority
'
' PREFSUNLOAD(STRING filename) - unloads the specified preference file
'
' PREFSSAVE(STRING filename) - saves changes of the specified preference file
' PREFSSAVEUSERCONFIG - saves user preferences file
' PREFSSAVEALLUSERSCONFIG - saves system-wide preferences file
'
' PREF([STRING arg_char][, STRING arg_word][, STRING variable][, BOOLEAN default])
'           - returns TRUE or FALSE whether switch/variable is set
'
' PREFSGET([STRING arg_char], [STRING arg_word], STRING variable[, STRING default])
'           - returns content of specified setting - a string, program parameters/"switches" only returns
'           a value if there is one explicitely specified; you have to use PREFSISSET() to determine
'           whether a switch without data was in the program call
'           => "myapp +s" will return "" like without "+s", "myapp +s:"42"" returns "42",
'              PREFSISSET() will return in both cases TRUE
'
' PREFSGETVALINT(...) / PREFSGETVALFLOAT(...) / PREFSGETVALDEC(...) like PREFSGET, converting to a numeric type
'                     => "INT": Integer, "FLOAT": double, "DEC": decimal
'
' PREFSISSET([STRING arg_char], [STRING arg_word], [STRING variable])
'           returns if given switch/argument or variable in preferences files exists, no matter,
'           if it has a content/value
'
' PREFSSET([STRING filename,] STRING variable, STRING value) - sets a string/text as setting content
'
Jattenalle
Posts: 50
Joined: Nov 17, 2023 14:41
Contact:

Re: FreeBASIC file paths

Post by Jattenalle »

dodicat wrote: Sep 17, 2024 21:13 Or shell which is more powerful than environ (gets more environment variables).

Code: Select all

 shell("echo "+"%"+"APPDATA"+"%") 
sleep 
dodicat wrote: Sep 17, 2024 21:58 You can pipe shell commands to a string, including the APPDATA

Code: Select all


 #include "crt.bi"
Declare Function stats Cdecl Alias "_stat"(As zstring Ptr,As Any Ptr) As Integer

 Function pipeout(Byval s As String="") Byref As String
    Var f=Freefile
    Dim As String tmp
    Open Pipe s For Input As #f 
    s=""
    Do Until Eof(f)
        Line Input #f,tmp
        s+=tmp+Chr(10)
    Loop
    Close #f
    Return s
End Function 

Function isfolder(path As zstring Ptr) As Long
    #define S_ISDIR(m)   (((m) And &hF000) = &h4000)
    Dim As stat statbuf
    If (stats(path, @statbuf) <> 0) Then Return 0
    Return S_ISDIR(statbuf.st_mode)
End Function


dim as string s=pipeout("echo "+"%"+"APPDATA"+"%")
print "'";rtrim(s,chr(10));"'"
print cbool(isfolder(rtrim(s,chr(10))))

sleep
 
  
This is poor code and bad advice.
Don't do this. Invoking a shell cmd will trigger every anti-virus ever, is horrible practice, and opens a myriad security issues and problems.
And its even worse if you try to "hide" it via pipe.
Post Reply