Skip to content

Commit d9d04c4

Browse files
committed
Create README.md
1 parent d68edbe commit d9d04c4

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

README.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# minIni
2+
minIni is a portable and configurable library for reading and writing ".INI" files. At 830 lines of commented source
3+
code
4+
(version 1.2), minIni truly is a "mini" INI file parser, especially considering its features.
5+
6+
The library does not require the file I/O functions from the standard C/C++ library, but instead lets you configure
7+
the file I/O interface to use via macros. minIni uses limited stack space and does not use dynamic memory (malloc and
8+
friends) at all.
9+
10+
Some minor variations on standard INI files are supported too, notably minIni supports INI files that lack sections.
11+
12+
13+
# Acknowledgement
14+
15+
minIni is derived from an earlier INI file parser (which I wrote) for desktop systems.
16+
17+
In turn, that earlier parser was a re-write of the code from the article "Multiplatform .INI Files" by Joseph J. Graf
18+
in the March 1994 issue of Dr. Dobb's Journal. In other words, minIni has its roots in the work of Joseph Graf (even
19+
though the code has been almost completely re-written).
20+
21+
22+
# Features
23+
24+
minIni is a programmer's library to read and write "INI" files in embedded systems. minIni takes little resources,
25+
can be configured for various kinds of file I/O libraries and provides functionality for reading, writing and
26+
deleting keys from an INI file.
27+
28+
Although the main feature of minIni is that it is small and minimal, it has a few other features:
29+
30+
* minIni supports reading keys that are outside a section, and it thereby supports configuration files that do not use sections (but that are otherwise compatible with INI files).
31+
* You may use a colon to separate key and value; the colon is equivalent to the equal sign. That is, the strings "Name: Value" and "Name=Value" have the same meaning.
32+
* The hash character ("#") is an alternative for the semicolon to start a comment. Trailing comments (i.e. behind a key/value pair on a line) are allowed.
33+
* Leading and trailing white space around key names and values is ignored.
34+
* When writing a value that contains a comment character (";" or "#"), that value will automatically be put between double quotes; when reading the value, these quotes are removed. When a double-quote itself appears in the setting, these characters are escaped.
35+
* Section and key enumeration are supported.
36+
* You can optionally set the line termination (for text files) that minIni will use. (This is a compile-time setting, not a run-time setting.)
37+
* Since writing speed is much lower than reading speed in Flash memory (SD/MMC cards, USB memory sticks), minIni minimizes "file writes" at the expense of double "file reads".
38+
* The memory footprint is deterministic. There is no dynamic memory allocation.
39+
40+
## INI file reading paradigms
41+
42+
There are two approaches to reading settings from an INI file. One way is to call a function, such as
43+
GetProfileString() for every section and key that you need. This is especially convenient if there is a large
44+
INI file, but you only need a few settings from that file at any time —especially if the INI file can also
45+
change while your program runs. This is the approach that the Microsoft Windows API uses.
46+
47+
The above procedure is quite inefficient, however, when you need to retrieve quite a few settings in a row from
48+
the INI file —especially if the INI file is not cached in memory (which it isn't, in minIni). A different approach
49+
to getting settings from an INI file is to call a "parsing" function and let that function call the application
50+
back with the section and key names plus the associated data. XML parsing libraries often use this approach; see
51+
for example the Expat library.
52+
53+
minIni supports both approaches. For reading a single setting, use functions like ini_gets(). For the callback
54+
approach, implement a callback and call ini_browse(). See the minIni manual for details.
55+
56+
57+
# INI file syntax
58+
59+
INI files are best known from Microsoft Windows, but they are also used with applications that run on other
60+
platforms (although their file extension is sometimes ".cfg" instead of ".ini").
61+
62+
INI files have a simple syntax with name/value pairs in a plain text file. The name must be unique (per section)
63+
and the value must fit on a single line. INI files are commonly separated into sections —in minIni, this is
64+
optional. A section is a name between square brackets, like "[Network]" in the example below.
65+
66+
```
67+
[Network]
68+
hostname=My Computer
69+
address=dhcp
70+
dns = 192.168.1.1
71+
```
72+
73+
In the API and in this documentation, the "name" for a setting is denoted as the key for the setting. The key
74+
and the value are separated by an equal sign ("="). minIni supports the colon (":") as an alternative to the
75+
equal sign for the key/value delimiter.
76+
77+
Leading a trailing spaces around values or key names are removed. If you need to include leading and/or trailing
78+
spaces in a value, put the value between double quotes. The ini_gets() function (from the minIni library, see the
79+
minIni manual) strips off the double quotes from the returned value. Function ini_puts() adds double quotes if
80+
the value to write contains trailing white space (or special characters).
81+
82+
minIni ignores spaces around the "=" or ":" delimiters, but it does not ignore spaces between the brackets in a
83+
section name. In other words, it is best not to put spaces behind the opening bracket "[" or before the closing
84+
bracket "]" of a section name.
85+
86+
Comments in the INI must start with a semicolon (";") or a hash character ("#"), and run to the end of the line.
87+
A comment can be a line of its own, or it may follow a key/value pair (the "#" character and trailing comments
88+
are extensions of minIni).
89+
90+
For more details on the format, please see http://en.wikipedia.org/wiki/INI_file.
91+
92+
93+
# Adapting minIni to a file system
94+
95+
The minIni library must be configured for a platform with the help of a so- called "glue file". This glue file
96+
contains macros (and possibly functions) that map file reading and writing functions used by the minIni library
97+
to those provided by the operating system. The glue file must be called "minGlue.h".
98+
99+
To get you started, the minIni distribution comes with the following example glue files:
100+
101+
* a glue file that maps to the standard C/C++ library (specifically the file I/O functions from the "stdio" package),
102+
* a glue file for Microchip's "Memory Disk Drive File System Library" (see http://www.microchip.com/),
103+
* a glue file for the FAT library provided with the CCS PIC compiler (see http://www.ccsinfo.com/)
104+
* a glue file for the EFS Library (EFSL, http://www.efsl.be/),
105+
* and a glue file for the FatFs and Petit-FatFs libraries (http://elm-chan.org/fsw/ff/00index_e.html).
106+
107+
The minIni library does not rely on the availability of a standard C library, because embedded operating systems
108+
may have limited support for file I/O. Even on full operating systems, separating the file I/O from the INI format
109+
parsing carries advantages, because it allows you to cache the INI file and thereby enhance performance.
110+
111+
The glue file must specify the type that identifies a file, whether it is a handle or a pointer. For the standard
112+
C/C++ file I/O library, this would be:
113+
114+
```C
115+
#define INI_FILETYPE FILE*
116+
```
117+
118+
If you are not using the standard C/C++ file I/O library, chances are that you need a different handle or
119+
"structure" to identify the storage than the ubiquitous "FILE*" type. For example, the glue file for the FatFs
120+
library uses the following declaration:
121+
122+
```C
123+
#define INI_FILETYPE FIL
124+
```
125+
126+
The minIni functions declare variables of this INI_FILETYPE type and pass these variables to sub-functions
127+
(including the glue interface functions) by reference.
128+
129+
For "write support", another type that must be defined is for variables that hold the "current position" in a
130+
file. For the standard C/C++ I/O library, this is "fpos_t".
131+
132+
Another item that needs to be configured is the buffer size. The functions in the minIni library allocate this
133+
buffer on the stack, so the buffer size is directly related to the stack usage. In addition, the buffer size
134+
determines the maximum line length that is supported in the INI file and the maximum path name length for the
135+
temporary file. For example, minGlue.h could contain the definition:
136+
137+
```C
138+
#define INI_BUFFERSIZE 512
139+
```
140+
141+
The above macro limits the line length of the INI files supported by minIni to 512 characters.
142+
143+
The temporary file is only used when writing to INI files. The minIni routines copy/change the INI file to a
144+
temporary file and then rename that temporary file to the original file. This approach uses the least amount of
145+
memory. The path name of the temporary file is the same as the input file, but with the last character set to a
146+
tilde ("~").
147+
148+
Below is an example of a glue file (this is the one that maps to the C/C++ "stdio" library).
149+
150+
```C
151+
#include <stdio.h>
152+
153+
#define INI_FILETYPE FILE*
154+
#define ini_openread(filename,file) ((*(file) = fopen((filename),"r")) != NULL)
155+
#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"w")) != NULL)
156+
#define ini_close(file) (fclose(*(file)) == 0)
157+
#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL)
158+
#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0)
159+
#define ini_rename(source,dest) (rename((source), (dest)) == 0)
160+
#define ini_remove(filename) (remove(filename) == 0)
161+
162+
#define INI_FILEPOS fpos_t
163+
#define ini_tell(file,pos) (fgetpos(*(file), (pos)) == 0)
164+
#define ini_seek(file,pos) (fsetpos(*(file), (pos)) == 0)
165+
```
166+
167+
As you can see, a glue file is mostly a set of macros that wraps one function definition around another.
168+
169+
The glue file may contain more settings, for support of rational numbers, to explicitly set the line termination
170+
character(s), or to disable write support (for example). See the manual that comes with the archive for the details.

0 commit comments

Comments
 (0)