Page 1 of 1

Add #PB_Preference_ForceCreation flag

Posted: Sun Nov 06, 2016 11:12 am
by Michael Vogel
When a program works with a preference file, it usually will create the file when it does not exist. This has to be done with a code like that...

Code: Select all

#PreferenceFile="something.ini"
; Protected n

n=OpenPreferences(#PreferenceFile,#PB_Preference_GroupSeparator)
If n=0
	n=CreatePreferences(#PreferenceFile,#PB_Preference_GroupSeparator)
EndIf

If n
	;
	;
Endif
It would be fine to save some code lines and a local variable by expanding the OpenPreference function to something like this...

Code: Select all

#PreferenceFile="something.ini"

If OpenPreferences(#PreferenceFile,#PB_Preference_GroupSeparator|#PB_Preference_ForceCreation)
	;
	;
Endif

Re: Add #PB_Preference_ForceCreation flag

Posted: Wed Dec 07, 2016 3:40 pm
by Fred
What would be the point to have an empty ini file ?

Re: Add #PB_Preference_ForceCreation flag

Posted: Sun Jan 15, 2017 4:33 pm
by Michael Vogel
That's the point, all preferences should be conservated, if possible - so I don't want to do a CreatePreferences but an OpenPreferences command.

Therefore an option which creates a preference file automatically if it does not exist would help and replaces a lot of code (like the following lines or in the first posting)...

Code: Select all

If FileSize(Ini)=#Undefined
	If CreateFile(#Null,Ini)
		CloseFile(#Null)
	EndIf
EndIf
If OpenPreferences(Ini,#PB_Preference_NoSpace)
	:
Else
	:
Another issue is given when using OpenPreferences and the preference file has set the write protection flag - because there's no feedback when using the write commands.

Re: Add #PB_Preference_ForceCreation flag

Posted: Sun Jan 15, 2017 6:11 pm
by Mistrel
When dealing with I/O there is rarely such a thing as too much error handling logic. Because PureBasic does not support exceptions we are only able to rely upon return values which typically amount to a binary success-or-failure.

As a preferences file is a file then like any file open operation you need to explicitly define what you want to do if the file does not exists, exists already, exists but is locked, exists but has no permission, etc.

The illusion here is that instead of using FileSize() to see if the file exists first you are using OpenPreferences(). The logic is still the same: you want to open the file if it exists; otherwise create and then open it. You are right to rely upon OpenPreferences() instead of FileSize() in this case as there may be other conditions within the OpenPreferences() function which might cause it to still fail. But even then, as it is I/O, there is always the inherent race condition between when you checked to see if the file exists and when you try to open it. With the exception of nuking it from orbit, generous error handling is the only way to truly be sure.

Cramming this behavior into OpenPreferences() might seem logical but is actually contrary to the behavior established not only in PureBasic's File library but also for many others'.

Instead of favoring if-true logic, try if-not-true as a method of escape. This has the added benefit of reducing the indentation of code, improving readability, and reducing logic complexity by minimizing the need for if-else blocks.

For example:

Code: Select all

If Not OpenPreferences(File,#PB_Preference_NoSpace)
   ;/ Handle error
   
   ProcedureReturn
EndIf

;/ Continue executing

Re: Add #PB_Preference_ForceCreation flag

Posted: Sun Jan 15, 2017 6:27 pm
by Michael Vogel
Thanks, and even I don't see a big difference between handling return=0 or handling return!=0 I'd like to use native PureBasic commands (and their return values !), where possible. :wink: And so you're right again, when you talk about a speed race - also a reason why I would like to have a single OpenPreference call instead of doing serial things in a row (anyhow I hope time is not as critical as in other situations, like IsThread / KillThread)

Actually the preference functions are just offering a best effort strategy while it would be possible to check some attributes, triggered by flags (ForceCreation, WriteAccess). If you want to have a reliable functionality it is necessary to create your own preference commands or you have to do crude things like adding a ReadPreference command after each WritePreference to see, if the value has been written. :|

Re: Add #PB_Preference_ForceCreation flag

Posted: Sun Jan 15, 2017 6:40 pm
by Fredi
Michael Vogel wrote: Add #PB_Preference_ForceCreation flag
+1
Or like OpenFile() automatically creates a new preference file if it does not exist

Re: Add #PB_Preference_ForceCreation flag

Posted: Sun Jan 15, 2017 8:44 pm
by Mistrel
Michael Vogel wrote:If you want to have a reliable functionality it is necessary to create your own preference commands or you have to do crude things like adding a ReadPreference command after each WritePreference to see, if the value has been written. :|
This has to do with the WirePreferences..() commands not providing an error result to indicate an I/O exception. This kind of thing would make a good feature request. The Write..() functions in the File library already support this.