summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2024-10-10 11:46:31 +0200
committerMatthias Melcher <github@matthiasm.com>2024-10-10 11:46:31 +0200
commita0f1d5bc5e6de365c467b8c885e02285c0b64607 (patch)
treec031deb1c484114a7238ba3080f1a05025043509
parent81d3ccefa4b6c3cbaeab20231b2c39705dfb3fb8 (diff)
Fl_Preferences documentation update.
-rw-r--r--FL/Fl_Preferences.H47
-rw-r--r--src/Fl_Preferences.cxx119
2 files changed, 143 insertions, 23 deletions
diff --git a/FL/Fl_Preferences.H b/FL/Fl_Preferences.H
index 98cc42523..dfdc7debe 100644
--- a/FL/Fl_Preferences.H
+++ b/FL/Fl_Preferences.H
@@ -32,10 +32,10 @@
/**
\brief Fl_Preferences store user settings between application starts.
- Fl_Preferences are similar to the Registry on Windows and Preferences on MacOS,
- providing a simple method to store customizable user settings between app
- launches, for instance the previous window position or a history of previously
- used documents.
+ FLTK Preferences are similar to the Registry on Windows and Preferences on
+ MacOS, providing a simple method to store customizable user settings between
+ application launches. A typical use is storing the last window position or a
+ history of previously used documents.
Preferences are organized in a hierarchy of groups. Every group can contain
more groups and any number of key/value pairs. Keys can be text strings
@@ -43,21 +43,23 @@
in a key name are treated as subgroups, i.e. the key 'window/width' would
actually refer to the key 'width' inside the group 'window'.
- Keys usually have a unique name within their group. Duplicate keys are
- possible though and can be accessed using the index based functions.
-
- A value can be an UTF-8 string. Control characters and UTF-8 sequences are
- stored as octal values. Long strings are wrapped at the line ending and will
- be reassembled when reading the file back.
+ Keys have a unique name within their group. A value can be any string includin
+ control characters 0x00 to 0x1f, 0x7f, and UTF-8 octets.
Several methods allow setting and getting numerical values and binary data.
- Preferences are stored in text files that can be edited manually if needed.
- The file format is easy to read and relatively forgiving. Preference files are
- the same on all platforms. User comments in preference files are preserved.
- Filenames are unique for each application by using a vendor/application naming
- scheme. The user must provide default values for all entries to ensure proper
- operation should preferences be corrupted or not yet exist.
+ Preferences files are the same across platforms. User comments in preference
+ files are preserved. Filenames are unique for each application by using a
+ vendor/application naming scheme. The developer app must provide default values
+ for all entries to ensure proper operation should preferences be corrupted
+ or not yet exist.
+
+ \note The format of preferences files is not part of the FLTK specification
+ and intentionally undocumented. The only valid way to read or write prefs
+ files is via the API from your app. The fact that the current
+ implementation looks like human-readable text is purely coincidental and
+ may change at any time. Preferences files are not meant to be created
+ or edited "by hand."
FLTK preferences are not meant to replace a fully features database. No merging
of data takes place. If several instances of an app access the same database at
@@ -65,7 +67,7 @@
Preferences should no be used to store document data. The .prefs file should
be kept small for performance reasons. One application can have multiple
- preference files. Extensive binary data however should be stored in separate
+ preferences files. Extensive binary data however should be stored in separate
files: see \a Fl_Preferences::get_userdata_path() .
Fl_Preferences are not thread-safe. They can temporarily change the locale
@@ -97,13 +99,12 @@
\see Fl_Preferences::Fl_Preferences(Root root, const char *vendor, const char *application)
- As a special case, Fl_Preferences can be memory mapped and not be associated
- with a file on disk.
-
- \see Fl_Preferences::Fl_Preferences(Fl_Preferences *parent, const char *group)
- for more details on memory mapped preferences.
+ \see As a special case, Fl_Preferences can be memory mapped and not be associated
+ with a file on disk. See
+ Fl_Preferences::Fl_Preferences(Fl_Preferences *parent, const char *group)
+ and Fl_Preferences::MEMORY for more details on memory mapped preferences.
- \note Starting with FLTK 1.3, preference databases are expected to
+ \note Starting with FLTK 1.3, preferences databases are expected to
be in UTF-8 encoding. Previous databases were stored in the
current character set or code page which renders them incompatible
for text entries using international characters.
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index d4284af19..a53ef335b 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -32,6 +32,125 @@
#include <string>
#endif
+/*
+ The format of preferences files is not part of the FLTK specification
+ and intentionally undocumented in Doxygen. The following documentation is FOR
+ CORE DEVELOPERS ONLY. Don't let any app developer see this!
+
+ This is the unofficial documentation of the file format as it currently stands.
+ The format may change at any point (although it really should stay backwards
+ compatible). Preferences files are supposed to be edited manually.
+ Nevertheless, here are the docs:
+
+ A .prefs file contains multiple lines. A line is defined a 0 or more ASCII
+ characters in the range from 0x20 to 0x7e, followed by a single '\n' line
+ ending character. Note that there are no tabs, \0 characters, or '\r'
+ characters anywhere in a line. Some parts of a line may allow 0x80 to 0xff
+ to support Unicode UTF8 octets.
+
+ The first line is always "; FLTK preferences file format 1.0", followed by a
+ '\n' to indicate the end of the line. The version number may change some time
+ in the future if the file format ever changes.
+
+ The second line contains the vendor information when the file was created:
+ "; vendor: VENDOR\n"
+
+ The third line contains the application name
+ "; application: APPLICATION_NAME\n"
+
+ Any following line that starts with a ';' is not relevant for data and seen
+ as a comment. Fl_Preferences tries to preserve comments, but has no API to set
+ or read comments.
+
+ All data is stored in key/value pairs. All key/value pairs are store inside
+ their group. There can be multiple groups. Group naming is used to
+ indicate a hierarchy.
+
+ A line starting with a '[' starts a group. Before and after a group line,
+ there is always an empty line (no characters, just a '\n'). A group line ends
+ in "]\n". Directly between the '[] and ']' is the name of the group. The first
+ ("root")-group is always declared with the line "[.]\n".
+
+ Simple group names are written starting with "./", for example "[./name]\n".
+ To generate a hierarchy of groups, deeper nested names are generated by adding
+ more '/name" segments (just like a Unix file path),
+ for example "[./dialog/button/position]\n".
+
+ Remember that there is an empty line after the group line.
+
+ A group line is followed by 0 or more lines containing key/value pairs for the
+ given group.
+
+ A key is a sequence of ASCII letters, numbers, ".", or "_". The key should not
+ be longer than 32 characters. The key is followed by the ":" character and
+ the value. There is no space before or after the ":". The value may contain
+ more ":" characters.
+
+ The value is a text of ASCII characters 0x20 to 0x7e, or UTF8 Unicode octets
+ 0x80 to 0xff.
+
+ The key/value line ends in a "\n". Key/value lines wrap before or at column 80
+ with a "/n" and continue in the next line, starting with a "+" which indicates
+ that this is an overflow line and is furthermore ignored. The type of a value
+ is not stored in a file. It is not an error to call Fl_Preferences::set with a
+ "double" and read back a string.
+
+ * Integers are written as signed int using "%d".
+ * Floating point values are written with decimal points if C_LOCALE is set
+ when creating the file.
+ * When text is written, "\r", "\n", and the "\" character are escaped by
+ prepending them with an additional "\", other characters <0x20 and 0x7f
+ are encoded in octal format: "\001", UTF-8 is allowed.
+ * Binary data is written as lower case hex digits, two digits per byte.
+
+ Example data as generated by the test/preferences app:
+
+ ```
+ ; FLTK preferences file format 1.0
+ ; vendor: fltk.org
+ ; application: test/preferences
+
+ [.]
+
+
+ [./Bed]
+
+ ; The value is "8:00". Values can contain a ':' character
+ alarm:8:00
+ ; Some integer values
+ ampm:0
+ wear:2
+ side:1
+ taskFlags:5
+
+ [./Breakfast]
+
+ drink:1
+ wMilk:1
+ bread:1
+ wButter:1
+ nEggs:2
+ ; A floating point value
+ minutes:4.91
+ newspaper:NY Tymes
+ ; A text value containing newlines and two other control codes
+ foo:bar\nfly\rBackslash: \\ and bell: \007 and delete: \177\n
+ ; A key can be numeric, but the numeric value has no special meaning
+ 3:Test3
+ ; Short binary data block. Data is written verbatim,
+ ; CPU endianess has no meaning here
+ binFoo:2387efcd
+ ; A long binary data block, generating wrapped lines
+ binFoo2:7c0802a6bfc1fff8900100089421ff707c3e0b78429f00057fe802a6381e
+ +00487c030378388000013c5f000538a287c43c5f000538c287d04801be31381e0050385e00487c03
+ +03787c4413783c5f000538a287e44801b6f93c5f00053842dc70800200007c030378480450197c69
+ +1b78381e00507c0303783c5f0005388287e87d254b784801ab253c5f00053842dc6c800200007c03
+ +0378480450097c691b78381e00507c0303783c5f0005388287f87d254b784801af8d3c5f00053842
+ +dc14800200007c03037848044fd97c691b78381e00507c0303783c5f0005388288007d254b784801
+ +af5d38000000901e00403c5f00053842db84800200007c030378
+ ```
+ */
+
char Fl_Preferences::nameBuffer[128];
char Fl_Preferences::uuidBuffer[40];
Fl_Preferences *Fl_Preferences::runtimePrefs = 0;