diff options
author | lpouzenc <lpouzenc@gmail.com> | 2013-07-11 11:31:40 +0200 |
---|---|---|
committer | lpouzenc <lpouzenc@gmail.com> | 2013-07-11 11:31:40 +0200 |
commit | fa2962ee433efb0b1c34d43d458682821b7ca8d8 (patch) | |
tree | 3e70718a2c076d30b1b0bf94f9332b092c4975c2 /src/minini | |
parent | bef3340ba0ea373f324b0eb300747236d1a8d4fa (diff) | |
download | mplemmings-fa2962ee433efb0b1c34d43d458682821b7ca8d8.tar.gz mplemmings-fa2962ee433efb0b1c34d43d458682821b7ca8d8.tar.bz2 mplemmings-fa2962ee433efb0b1c34d43d458682821b7ca8d8.zip |
Integration de minini avec les fonctions SDL d'IO. Sous linux, c'est ok... Mais ça, on le savait déjà.
Diffstat (limited to 'src/minini')
-rw-r--r-- | src/minini/LICENSE | 189 | ||||
-rw-r--r-- | src/minini/NOTICE | 12 | ||||
-rw-r--r-- | src/minini/dev/minGlue-FatFs.h | 37 | ||||
-rw-r--r-- | src/minini/dev/minGlue-ccs.h | 64 | ||||
-rw-r--r-- | src/minini/dev/minGlue-efsl.h | 63 | ||||
-rw-r--r-- | src/minini/dev/minGlue-ffs.h | 26 | ||||
-rw-r--r-- | src/minini/dev/minGlue-mdd.h | 57 | ||||
-rw-r--r-- | src/minini/dev/minGlue-sdl2.h | 38 | ||||
-rw-r--r-- | src/minini/dev/minGlue-stdio.h | 30 | ||||
-rw-r--r-- | src/minini/dev/minGlue.h | 38 | ||||
-rw-r--r-- | src/minini/dev/minIni.c | 832 | ||||
-rw-r--r-- | src/minini/dev/minIni.h | 152 | ||||
-rw-r--r-- | src/minini/dev/my_SDL_stdinc.c | 24 | ||||
-rw-r--r-- | src/minini/dev/my_SDL_stdinc.h | 4 | ||||
-rw-r--r-- | src/minini/dev/test.c | 114 | ||||
-rw-r--r-- | src/minini/dev/test.ini | 8 | ||||
-rw-r--r-- | src/minini/dev/test2.cc | 80 | ||||
-rw-r--r-- | src/minini/dev/testplain.ini | 3 | ||||
-rw-r--r-- | src/minini/dev/wxMinIni.h | 101 | ||||
-rw-r--r-- | src/minini/doc/minIni.pdf | bin | 0 -> 221115 bytes |
20 files changed, 1872 insertions, 0 deletions
diff --git a/src/minini/LICENSE b/src/minini/LICENSE new file mode 100644 index 0000000..ee069fd --- /dev/null +++ b/src/minini/LICENSE @@ -0,0 +1,189 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + + EXCEPTION TO THE APACHE 2.0 LICENSE
+ + As a special exception to the Apache License 2.0 (and referring to the
+ definitions in Section 1 of this license), you may link, statically or
+ dynamically, the "Work" to other modules to produce an executable file + containing portions of the "Work", and distribute that executable file + in "Object" form under the terms of your choice, without any of the + additional requirements listed in Section 4 of the Apache License 2.0.
+ This exception applies only to redistributions in "Object" form (not
+ "Source" form) and only if no modifications have been made to the "Work".
+ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + diff --git a/src/minini/NOTICE b/src/minini/NOTICE new file mode 100644 index 0000000..6ce0ef3 --- /dev/null +++ b/src/minini/NOTICE @@ -0,0 +1,12 @@ +minIni is a programmer's library to read and write "INI" files in embedded
+systems. The library takes little resources and can be configured for various
+kinds of file I/O libraries.
+
+The method for portable INI file management in minIni is, in part based, on the
+article "Multiplatform .INI Files" by Joseph J. Graf in the March 1994 issue of
+Dr. Dobb's Journal.
+
+The C++ class in minIni.h was contributed by Steven Van Ingelgem.
+
+The option to compile minIni as a read-only library was contributed by Luca
+Bassanello.
diff --git a/src/minini/dev/minGlue-FatFs.h b/src/minini/dev/minGlue-FatFs.h new file mode 100644 index 0000000..51593a2 --- /dev/null +++ b/src/minini/dev/minGlue-FatFs.h @@ -0,0 +1,37 @@ +/* Glue functions for the minIni library, based on the FatFs and Petit-FatFs + * libraries, see http://elm-chan.org/fsw/ff/00index_e.html + * + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + * + * (The FatFs and Petit-FatFs libraries are copyright by ChaN and licensed at + * its own terms.) + */ + +#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ + +/* You must set _USE_STRFUNC to 1 or 2 in the include file ff.h (or tff.h) + * to enable the "string functions" fgets() and fputs(). + */ +#include "ff.h" /* include tff.h for Tiny-FatFs */ + +#define INI_FILETYPE FIL +#define ini_openread(filename,file) (f_open((file), (filename), FA_READ+FA_OPEN_EXISTING) == FR_OK) +#define ini_openwrite(filename,file) (f_open((file), (filename), FA_WRITE+FA_CREATE_ALWAYS) == FR_OK) +#define ini_close(file) (f_close(file) == FR_OK) +#define ini_read(buffer,size,file) f_gets((buffer), (size),(file)) +#define ini_write(buffer,file) f_puts((buffer), (file)) +#define ini_remove(filename) (f_unlink(filename) == FR_OK) + +#define INI_FILEPOS DWORD +#define ini_tell(file,pos) (*(pos) = f_tell((file))) +#define ini_seek(file,pos) (f_lseek((file), *(pos)) == FR_OK) + +static int ini_rename(TCHAR *source, const TCHAR *dest) +{ + /* Function f_rename() does not allow drive letters in the destination file */ + char *drive = strchr(dest, ':'); + drive = (drive == NULL) ? dest : drive + 1; + return (f_rename(source, drive) == FR_OK); +} diff --git a/src/minini/dev/minGlue-ccs.h b/src/minini/dev/minGlue-ccs.h new file mode 100644 index 0000000..a8e19f1 --- /dev/null +++ b/src/minini/dev/minGlue-ccs.h @@ -0,0 +1,64 @@ +/* minIni glue functions for FAT library by CCS, Inc. (as provided with their
+ * PIC MCU compiler)
+ *
+ * By CompuPhase, 2011-2012
+ * This "glue file" is in the public domain. It is distributed without
+ * warranties or conditions of any kind, either express or implied.
+ *
+ * (The FAT library is copyright (c) 2007 Custom Computer Services, and
+ * licensed at its own terms.)
+ */
+
+#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */
+
+#ifndef FAT_PIC_C
+ #error FAT library must be included before this module
+#endif
+#define const /* keyword not supported by CCS */
+
+#define INI_FILETYPE FILE
+#define ini_openread(filename,file) (fatopen((filename), "r", (file)) == GOODEC)
+#define ini_openwrite(filename,file) (fatopen((filename), "w", (file)) == GOODEC)
+#define ini_close(file) (fatclose((file)) == 0)
+#define ini_read(buffer,size,file) (fatgets((buffer), (size), (file)) != NULL)
+#define ini_write(buffer,file) (fatputs((buffer), (file)) == GOODEC)
+#define ini_remove(filename) (rm_file((filename)) == 0)
+
+#define INI_FILEPOS fatpos_t
+#define ini_tell(file,pos) (fatgetpos((file), (pos)) == 0)
+#define ini_seek(file,pos) (fatsetpos((file), (pos)) == 0)
+
+#ifndef INI_READONLY
+/* CCS FAT library lacks a rename function, so instead we copy the file to the
+ * new name and delete the old file
+ */
+static int ini_rename(char *source, char *dest)
+{
+ FILE fr, fw;
+ int n;
+
+ if (fatopen(source, "r", &fr) != GOODEC)
+ return 0;
+ if (rm_file(dest) != 0)
+ return 0;
+ if (fatopen(dest, "w", &fw) != GOODEC)
+ return 0;
+
+ /* With some "insider knowledge", we can save some memory: the "source"
+ * parameter holds a filename that was built from the "dest" parameter. It
+ * was built in a local buffer with the size INI_BUFFERSIZE. We can reuse
+ * this buffer for copying the file.
+ */
+ while (n=fatread(source, 1, INI_BUFFERSIZE, &fr))
+ fatwrite(source, 1, n, &fw);
+
+ fatclose(&fr);
+ fatclose(&fw);
+
+ /* Now we need to delete the source file. However, we have garbled the buffer
+ * that held the filename of the source. So we need to build it again.
+ */
+ ini_tempname(source, dest, INI_BUFFERSIZE);
+ return rm_file(source) == 0;
+}
+#endif
diff --git a/src/minini/dev/minGlue-efsl.h b/src/minini/dev/minGlue-efsl.h new file mode 100644 index 0000000..5fe0fcf --- /dev/null +++ b/src/minini/dev/minGlue-efsl.h @@ -0,0 +1,63 @@ +/* Glue functions for the minIni library, based on the EFS Library, see + * http://www.efsl.be/ + * + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + * + * (EFSL is copyright 2005-2006 Lennart Ysboodt and Michael De Nil, and + * licensed under the GPL with an exception clause for static linking.) + */ + +#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */ +#define INI_LINETERM "\r\n" /* set line termination explicitly */ + +#include "efs.h" +extern EmbeddedFileSystem g_efs; + +#define INI_FILETYPE EmbeddedFile +#define ini_openread(filename,file) (file_fopen((file), &g_efs.myFs, (char*)(filename), 'r') == 0) +#define ini_openwrite(filename,file) (file_fopen((file), &g_efs.myFs, (char*)(filename), 'w') == 0) +#define ini_close(file) file_fclose(file) +#define ini_read(buffer,size,file) (file_read((file), (size), (buffer)) > 0) +#define ini_write(buffer,file) (file_write((file), strlen(buffer), (char*)(buffer)) > 0) +#define ini_remove(filename) rmfile(&g_efs.myFs, (char*)(filename)) + +#define INI_FILEPOS euint32 +#define ini_tell(file,pos) (*(pos) = (file)->FilePtr)) +#define ini_seek(file,pos) file_setpos((file), (*pos)) + +#if ! defined INI_READONLY +/* EFSL lacks a rename function, so instead we copy the file to the new name + * and delete the old file + */ +static int ini_rename(char *source, const char *dest) +{ + EmbeddedFile fr, fw; + int n; + + if (file_fopen(&fr, &g_efs.myFs, source, 'r') != 0) + return 0; + if (rmfile(&g_efs.myFs, (char*)dest) != 0) + return 0; + if (file_fopen(&fw, &g_efs.myFs, (char*)dest, 'w') != 0) + return 0; + + /* With some "insider knowledge", we can save some memory: the "source" + * parameter holds a filename that was built from the "dest" parameter. It + * was built in buffer and this buffer has the size INI_BUFFERSIZE. We can + * reuse this buffer for copying the file. + */ + while (n=file_read(&fr, INI_BUFFERSIZE, source)) + file_write(&fw, n, source); + + file_fclose(&fr); + file_fclose(&fw); + + /* Now we need to delete the source file. However, we have garbled the buffer + * that held the filename of the source. So we need to build it again. + */ + ini_tempname(source, dest, INI_BUFFERSIZE); + return rmfile(&g_efs.myFs, source) == 0; +} +#endif diff --git a/src/minini/dev/minGlue-ffs.h b/src/minini/dev/minGlue-ffs.h new file mode 100644 index 0000000..5dadace --- /dev/null +++ b/src/minini/dev/minGlue-ffs.h @@ -0,0 +1,26 @@ +/* Glue functions for the minIni library, based on the "FAT Filing System"
+ * library by embedded-code.com
+ *
+ * By CompuPhase, 2008-2012
+ * This "glue file" is in the public domain. It is distributed without
+ * warranties or conditions of any kind, either express or implied.
+ *
+ * (The "FAT Filing System" library itself is copyright embedded-code.com, and
+ * licensed at its own terms.)
+ */
+
+#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */
+#include <mem-ffs.h>
+
+#define INI_FILETYPE FFS_FILE*
+#define ini_openread(filename,file) ((*(file) = ffs_fopen((filename),"r")) != NULL)
+#define ini_openwrite(filename,file) ((*(file) = ffs_fopen((filename),"w")) != NULL)
+#define ini_close(file) (ffs_fclose(*(file)) == 0)
+#define ini_read(buffer,size,file) (ffs_fgets((buffer),(size),*(file)) != NULL)
+#define ini_write(buffer,file) (ffs_fputs((buffer),*(file)) >= 0)
+#define ini_rename(source,dest) (ffs_rename((source), (dest)) == 0)
+#define ini_remove(filename) (ffs_remove(filename) == 0)
+
+#define INI_FILEPOS long
+#define ini_tell(file,pos) (ffs_fgetpos(*(file), (pos)) == 0)
+#define ini_seek(file,pos) (ffs_fsetpos(*(file), (pos)) == 0)
diff --git a/src/minini/dev/minGlue-mdd.h b/src/minini/dev/minGlue-mdd.h new file mode 100644 index 0000000..87cd04b --- /dev/null +++ b/src/minini/dev/minGlue-mdd.h @@ -0,0 +1,57 @@ +/* minIni glue functions for Microchip's "Memory Disk Drive" file system
+ * library, as presented in Microchip application note AN1045.
+ *
+ * By CompuPhase, 2011-2012
+ * This "glue file" is in the public domain. It is distributed without
+ * warranties or conditions of any kind, either express or implied.
+ *
+ * (The "Microchip Memory Disk Drive File System" is copyright (c) Microchip
+ * Technology Incorporated, and licensed at its own terms.)
+ */
+
+#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */
+
+#include "MDD File System\fsio.h"
+#include <string.h>
+
+#define INI_FILETYPE FSFILE*
+#define ini_openread(filename,file) ((*(file) = FSfopen((filename), FS_READ)) != NULL)
+#define ini_openwrite(filename,file) ((*(file) = FSfopen((filename), FS_WRITE)) != NULL)
+#define ini_close(file) (FSfclose(*(file)) == 0)
+#define ini_write(buffer,file) (FSfwrite((buffer), 1, strlen(buffer), (*file)) > 0)
+#define ini_remove(filename) (FSremove((filename)) == 0)
+
+#define INI_FILEPOS long
+#define ini_tell(file,pos) (*(pos) = FSftell(*(file)))
+#define ini_seek(file,pos) (FSfseek(*(file), *(pos), SEEK_SET) == 0)
+
+/* Since the Memory Disk Drive file system library reads only blocks of files,
+ * the function to read a text line does so by "over-reading" a block of the
+ * of the maximum size and truncating it behind the end-of-line.
+ */
+static int ini_read(char *buffer, int size, INI_FILETYPE *file)
+{
+ size_t numread = size;
+ char *eol;
+
+ if ((numread = FSfread(buffer, 1, size, *file)) == 0)
+ return 0; /* at EOF */
+ if ((eol = strchr(buffer, '\n')) == NULL)
+ eol = strchr(buffer, '\r');
+ if (eol != NULL) {
+ /* terminate the buffer */
+ *++eol = '\0';
+ /* "unread" the data that was read too much */
+ FSfseek(*file, - (int)(numread - (size_t)(eol - buffer)), SEEK_CUR);
+ } /* if */
+ return 1;
+}
+
+#ifndef INI_READONLY
+static int ini_rename(const char *source, const char *dest)
+{
+ FSFILE* ftmp = FSfopen((source), FS_READ);
+ FSrename((dest), ftmp);
+ return FSfclose(ftmp) == 0;
+}
+#endif
diff --git a/src/minini/dev/minGlue-sdl2.h b/src/minini/dev/minGlue-sdl2.h new file mode 100644 index 0000000..8a56299 --- /dev/null +++ b/src/minini/dev/minGlue-sdl2.h @@ -0,0 +1,38 @@ +/* Glue functions for the minIni library, based on the C/C++ stdio library + * + * Or better said: this file contains macros that maps the function interface + * used by minIni to the standard C/C++ file I/O functions. + * + * By Ludovic Pouzenc <lpouzenc@gmail.com>, 2013. + * From template by CompuPhase, 2008-2012 + * + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + */ + +/* map required file I/O types and functions to the standard C library */ + +/* These include should come from SDL2 library */ +#include <SDL_rwops.h> +#include <SDL_stdinc.h> +#include "my_SDL_stdinc.h" + +#define INI_FILETYPE SDL_RWops* +#define ini_openread(filename,file) ((*(file) = SDL_RWFromFile((filename),"rb")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = SDL_RWFromFile((filename),"wb")) != NULL) +#define ini_close(file) (SDL_RWclose(*(file)) == 0) +#define ini_read(buffer,size,file) (my_SDL_RWfgets(*(file),(buffer),(size)) != NULL) +#define ini_write(buffer,file) (SDL_RWwrite(*(file),(buffer),1,SDL_strlen((buffer))) >= 0) + +#define ini_rename(source,dest) (rename((source), (dest)) == 0) // Pas de solution SDL :( +#define ini_remove(filename) (remove(filename) == 0) // Pas de solution SDL :( + +#define INI_FILEPOS Sint64 +#define ini_tell(file,pos) (*(pos) = SDL_RWtell(*(file)),0) +#define ini_seek(file,pos) (SDL_RWseek(*(file), *(pos), RW_SEEK_SET) != -1) + +/* for floating-point support, define additional types and functions */ +#define INI_REAL double +#define ini_ftoa(string,value) SDL_snprintf((string),32,"%f",(value)) +#define ini_atof(string) SDL_atof((string)) + diff --git a/src/minini/dev/minGlue-stdio.h b/src/minini/dev/minGlue-stdio.h new file mode 100644 index 0000000..202d6dc --- /dev/null +++ b/src/minini/dev/minGlue-stdio.h @@ -0,0 +1,30 @@ +/* Glue functions for the minIni library, based on the C/C++ stdio library + * + * Or better said: this file contains macros that maps the function interface + * used by minIni to the standard C/C++ file I/O functions. + * + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + */ + +/* map required file I/O types and functions to the standard C library */ +#include <stdio.h> + +#define INI_FILETYPE FILE* +#define ini_openread(filename,file) ((*(file) = fopen((filename),"rb")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wb")) != NULL) +#define ini_close(file) (fclose(*(file)) == 0) +#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL) +#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0) +#define ini_rename(source,dest) (rename((source), (dest)) == 0) +#define ini_remove(filename) (remove(filename) == 0) + +#define INI_FILEPOS fpos_t +#define ini_tell(file,pos) (fgetpos(*(file), (pos)) == 0) +#define ini_seek(file,pos) (fsetpos(*(file), (pos)) == 0) + +/* for floating-point support, define additional types and functions */ +#define INI_REAL float +#define ini_ftoa(string,value) sprintf((string),"%f",(value)) +#define ini_atof(string) (INI_REAL)strtod((string),NULL) diff --git a/src/minini/dev/minGlue.h b/src/minini/dev/minGlue.h new file mode 100644 index 0000000..8a56299 --- /dev/null +++ b/src/minini/dev/minGlue.h @@ -0,0 +1,38 @@ +/* Glue functions for the minIni library, based on the C/C++ stdio library + * + * Or better said: this file contains macros that maps the function interface + * used by minIni to the standard C/C++ file I/O functions. + * + * By Ludovic Pouzenc <lpouzenc@gmail.com>, 2013. + * From template by CompuPhase, 2008-2012 + * + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + */ + +/* map required file I/O types and functions to the standard C library */ + +/* These include should come from SDL2 library */ +#include <SDL_rwops.h> +#include <SDL_stdinc.h> +#include "my_SDL_stdinc.h" + +#define INI_FILETYPE SDL_RWops* +#define ini_openread(filename,file) ((*(file) = SDL_RWFromFile((filename),"rb")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = SDL_RWFromFile((filename),"wb")) != NULL) +#define ini_close(file) (SDL_RWclose(*(file)) == 0) +#define ini_read(buffer,size,file) (my_SDL_RWfgets(*(file),(buffer),(size)) != NULL) +#define ini_write(buffer,file) (SDL_RWwrite(*(file),(buffer),1,SDL_strlen((buffer))) >= 0) + +#define ini_rename(source,dest) (rename((source), (dest)) == 0) // Pas de solution SDL :( +#define ini_remove(filename) (remove(filename) == 0) // Pas de solution SDL :( + +#define INI_FILEPOS Sint64 +#define ini_tell(file,pos) (*(pos) = SDL_RWtell(*(file)),0) +#define ini_seek(file,pos) (SDL_RWseek(*(file), *(pos), RW_SEEK_SET) != -1) + +/* for floating-point support, define additional types and functions */ +#define INI_REAL double +#define ini_ftoa(string,value) SDL_snprintf((string),32,"%f",(value)) +#define ini_atof(string) SDL_atof((string)) + diff --git a/src/minini/dev/minIni.c b/src/minini/dev/minIni.c new file mode 100644 index 0000000..e33d514 --- /dev/null +++ b/src/minini/dev/minIni.c @@ -0,0 +1,832 @@ +/* minIni - Multi-Platform INI file parser, suitable for embedded systems + * + * These routines are in part based on the article "Multiplatform .INI Files" + * by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal. + * + * Copyright (c) CompuPhase, 2008-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Version: $Id: minIni.c 46 2012-12-04 13:37:29Z thiadmer.riemersma $ + */ + +#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined MININI_ANSI +# if !defined UNICODE /* for Windows */ +# define UNICODE +# endif +# if !defined _UNICODE /* for C library */ +# define _UNICODE +# endif +#endif + +#define MININI_IMPLEMENTATION +#include "minIni.h" +#if defined NDEBUG + #define assert(e) +#else + #include <assert.h> +#endif + +#if !defined __T + #include <ctype.h> + #include <string.h> + #include <stdlib.h> + #define TCHAR char + #define __T(s) s + #define _tcscat strcat + #define _tcschr strchr + #define _tcscmp strcmp + #define _tcscpy strcpy + #define _tcsicmp stricmp + #define _tcslen strlen + #define _tcsncmp strncmp + #define _tcsnicmp strnicmp + #define _tcsrchr strrchr + #define _tcstol strtol + #define _tcstod strtod + #define _totupper toupper + #define _stprintf sprintf + #define _tfgets fgets + #define _tfputs fputs + #define _tfopen fopen + #define _tremove remove + #define _trename rename +#endif + +//#if defined __linux || defined __linux__ +#if (defined __linux || defined __linux__) && !defined __LINUX__ + #define __LINUX__ +#elif defined FREEBSD && !defined __FreeBSD__ + #define __FreeBSD__ +#elif defined(_MSC_VER) + #pragma warning(disable: 4996) /* for Microsoft Visual C/C++ */ +#endif +#if !defined strnicmp && !defined PORTABLE_STRNICMP + #if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ + #define strnicmp strncasecmp + #endif +#endif + +#if !defined INI_LINETERM + #define INI_LINETERM __T("\n") +#endif +#if !defined INI_FILETYPE + #error Missing definition for INI_FILETYPE. +#endif + +#if !defined sizearray + #define sizearray(a) (sizeof(a) / sizeof((a)[0])) +#endif + +enum quote_option { + QUOTE_NONE, + QUOTE_ENQUOTE, + QUOTE_DEQUOTE, +}; + +#if defined PORTABLE_STRNICMP +int strnicmp(const TCHAR *s1, const TCHAR *s2, size_t n) +{ + register int c1, c2; + + while (n-- != 0 && (*s1 || *s2)) { + c1 = *s1++; + if ('a' <= c1 && c1 <= 'z') + c1 += ('A' - 'a'); + c2 = *s2++; + if ('a' <= c2 && c2 <= 'z') + c2 += ('A' - 'a'); + if (c1 != c2) + return c1 - c2; + } /* while */ + return 0; +} +#endif /* PORTABLE_STRNICMP */ + +static TCHAR *skipleading(const TCHAR *str) +{ + assert(str != NULL); + while (*str != '\0' && *str <= ' ') + str++; + return (TCHAR *)str; +} + +static TCHAR *skiptrailing(const TCHAR *str, const TCHAR *base) +{ + assert(str != NULL); + assert(base != NULL); + while (str > base && *(str-1) <= ' ') + str--; + return (TCHAR *)str; +} + +static TCHAR *striptrailing(TCHAR *str) +{ + TCHAR *ptr = skiptrailing(_tcschr(str, '\0'), str); + assert(ptr != NULL); + *ptr = '\0'; + return str; +} + +static TCHAR *save_strncpy(TCHAR *dest, const TCHAR *source, size_t maxlen, enum quote_option option) +{ + size_t d, s; + + assert(maxlen>0); + assert(dest <= source || dest >= source + maxlen); + if (option == QUOTE_ENQUOTE && maxlen < 3) + option = QUOTE_NONE; /* cannot store two quotes and a terminating zero in less than 3 characters */ + + switch (option) { + case QUOTE_NONE: + for (d = 0; d < maxlen - 1 && source[d] != '\0'; d++) + dest[d] = source[d]; + assert(d < maxlen); + dest[d] = '\0'; + break; + case QUOTE_ENQUOTE: + d = 0; + dest[d++] = '"'; + for (s = 0; source[s] != '\0' && d < maxlen - 2; s++, d++) { + if (source[s] == '"') { + if (d >= maxlen - 3) + break; /* no space to store the escape character plus the one that follows it */ + dest[d++] = '\\'; + } /* if */ + dest[d] = source[s]; + } /* for */ + dest[d++] = '"'; + dest[d] = '\0'; + break; + case QUOTE_DEQUOTE: + for (d = s = 0; source[s] != '\0' && d < maxlen - 1; s++, d++) { + if ((source[s] == '"' || source[s] == '\\') && source[s + 1] == '"') + s++; + dest[d] = source[s]; + } /* for */ + dest[d] = '\0'; + break; + default: + assert(0); + } /* switch */ + + return dest; +} + +static TCHAR *cleanstring(TCHAR *string, enum quote_option *quotes) +{ + int isstring; + TCHAR *ep; + + assert(string != NULL); + assert(quotes != NULL); + + /* Remove a trailing comment */ + isstring = 0; + for (ep = string; *ep != '\0' && ((*ep != ';' && *ep != '#') || isstring); ep++) { + if (*ep == '"') { + if (*(ep + 1) == '"') + ep++; /* skip "" (both quotes) */ + else + isstring = !isstring; /* single quote, toggle isstring */ + } else if (*ep == '\\' && *(ep + 1) == '"') { + ep++; /* skip \" (both quotes */ + } /* if */ + } /* for */ + assert(ep != NULL && (*ep == '\0' || *ep == ';' || *ep == '#')); + *ep = '\0'; /* terminate at a comment */ + striptrailing(string); + /* Remove double quotes surrounding a value */ + *quotes = QUOTE_NONE; + if (*string == '"' && (ep = _tcschr(string, '\0')) != NULL && *(ep - 1) == '"') { + string++; + *--ep = '\0'; + *quotes = QUOTE_DEQUOTE; /* this is a string, so remove escaped characters */ + } /* if */ + return string; +} + +static int getkeystring(INI_FILETYPE *fp, const TCHAR *Section, const TCHAR *Key, + int idxSection, int idxKey, TCHAR *Buffer, int BufferSize) +{ + TCHAR *sp, *ep; + int len, idx; + enum quote_option quotes; + TCHAR LocalBuffer[INI_BUFFERSIZE]; + + assert(fp != NULL); + /* Move through file 1 line at a time until a section is matched or EOF. If + * parameter Section is NULL, only look at keys above the first section. If + * idxSection is postive, copy the relevant section name. + */ + len = (Section != NULL) ? _tcslen(Section) : 0; + if (len > 0 || idxSection >= 0) { + idx = -1; + do { + if (!ini_read(LocalBuffer, INI_BUFFERSIZE, fp)) + return 0; + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, ']'); + } while (*sp != '[' || ep == NULL || (((int)(ep-sp-1) != len || _tcsnicmp(sp+1,Section,len) != 0) && ++idx != idxSection)); + if (idxSection >= 0) { + if (idx == idxSection) { + assert(ep != NULL); + assert(*ep == ']'); + *ep = '\0'; + save_strncpy(Buffer, sp + 1, BufferSize, QUOTE_NONE); + return 1; + } /* if */ + return 0; /* no more section found */ + } /* if */ + } /* if */ + + /* Now that the section has been found, find the entry. + * Stop searching upon leaving the section's area. + */ + assert(Key != NULL || idxKey >= 0); + len = (Key != NULL) ? (int)_tcslen(Key) : 0; + idx = -1; + do { + if (!ini_read(LocalBuffer,INI_BUFFERSIZE,fp) || *(sp = skipleading(LocalBuffer)) == '[') + return 0; + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, '='); /* Parse out the equal sign */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + } while (*sp == ';' || *sp == '#' || ep == NULL || (((int)(skiptrailing(ep,sp)-sp) != len || _tcsnicmp(sp,Key,len) != 0) && ++idx != idxKey)); + if (idxKey >= 0) { + if (idx == idxKey) { + assert(ep != NULL); + assert(*ep == '=' || *ep == ':'); + *ep = '\0'; + striptrailing(sp); + save_strncpy(Buffer, sp, BufferSize, QUOTE_NONE); + return 1; + } /* if */ + return 0; /* no more key found (in this section) */ + } /* if */ + + /* Copy up to BufferSize chars to buffer */ + assert(ep != NULL); + assert(*ep == '=' || *ep == ':'); + sp = skipleading(ep + 1); + sp = cleanstring(sp, "es); /* Remove a trailing comment */ + save_strncpy(Buffer, sp, BufferSize, quotes); + return 1; +} + +/** ini_gets() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue default string in the event of a failed read + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * \return the number of characters copied into the supplied buffer + */ +int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue, + TCHAR *Buffer, int BufferSize, const TCHAR *Filename) +{ + INI_FILETYPE fp; + int ok = 0; + + if (Buffer == NULL || BufferSize <= 0 || Key == NULL) + return 0; + if (ini_openread(Filename, &fp)) { + ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize); + (void)ini_close(&fp); + } /* if */ + if (!ok) + save_strncpy(Buffer, DefValue, BufferSize, QUOTE_NONE); + return _tcslen(Buffer); +} + +/** ini_getl() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue the default value in the event of a failed read + * \param Filename the name of the .ini file to read from + * + * \return the value located at Key + */ +long ini_getl(const TCHAR *Section, const TCHAR *Key, long DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + return (len == 0) ? DefValue + : ((len >= 2 && _totupper(LocalBuffer[1]) == 'X') ? _tcstol(LocalBuffer, NULL, 16) + : _tcstol(LocalBuffer, NULL, 10)); +} + +#if defined INI_REAL +/** ini_getf() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue the default value in the event of a failed read + * \param Filename the name of the .ini file to read from + * + * \return the value located at Key + */ +INI_REAL ini_getf(const TCHAR *Section, const TCHAR *Key, INI_REAL DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + return (len == 0) ? DefValue : ini_atof(LocalBuffer); +} +#endif + +/** ini_getbool() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue default value in the event of a failed read; it should + * zero (0) or one (1). + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * A true boolean is found if one of the following is matched: + * - A string starting with 'y' or 'Y' + * - A string starting with 't' or 'T' + * - A string starting with '1' + * + * A false boolean is found if one of the following is matched: + * - A string starting with 'n' or 'N' + * - A string starting with 'f' or 'F' + * - A string starting with '0' + * + * \return the true/false flag as interpreted at Key + */ +int ini_getbool(const TCHAR *Section, const TCHAR *Key, int DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[2]; + int ret; + + ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + LocalBuffer[0] = (TCHAR)toupper(LocalBuffer[0]); + if (LocalBuffer[0] == 'Y' || LocalBuffer[0] == '1' || LocalBuffer[0] == 'T') + ret = 1; + else if (LocalBuffer[0] == 'N' || LocalBuffer[0] == '0' || LocalBuffer[0] == 'F') + ret = 0; + else + ret = DefValue; + + return(ret); +} + +/** ini_getsection() + * \param idx the zero-based sequence number of the section to return + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * \return the number of characters copied into the supplied buffer + */ +int ini_getsection(int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename) +{ + INI_FILETYPE fp; + int ok = 0; + + if (Buffer == NULL || BufferSize <= 0 || idx < 0) + return 0; + if (ini_openread(Filename, &fp)) { + ok = getkeystring(&fp, NULL, NULL, idx, -1, Buffer, BufferSize); + (void)ini_close(&fp); + } /* if */ + if (!ok) + *Buffer = '\0'; + return _tcslen(Buffer); +} + +/** ini_getkey() + * \param Section the name of the section to browse through, or NULL to + * browse through the keys outside any section + * \param idx the zero-based sequence number of the key to return + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * \return the number of characters copied into the supplied buffer + */ +int ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename) +{ + INI_FILETYPE fp; + int ok = 0; + + if (Buffer == NULL || BufferSize <= 0 || idx < 0) + return 0; + if (ini_openread(Filename, &fp)) { + ok = getkeystring(&fp, Section, NULL, -1, idx, Buffer, BufferSize); + (void)ini_close(&fp); + } /* if */ + if (!ok) + *Buffer = '\0'; + return _tcslen(Buffer); +} + + +#if !defined INI_NOBROWSE +/** ini_browse() + * \param Callback a pointer to a function that will be called for every + * setting in the INI file. + * \param UserData arbitrary data, which the function passes on the the + * \c Callback function + * \param Filename the name and full path of the .ini file to read from + * + * \return 1 on success, 0 on failure (INI file not found) + * + * \note The \c Callback function must return 1 to continue + * browsing through the INI file, or 0 to stop. Even when the + * callback stops the browsing, this function will return 1 + * (for success). + */ +int ini_browse(INI_CALLBACK Callback, const void *UserData, const TCHAR *Filename) +{ + TCHAR LocalBuffer[INI_BUFFERSIZE]; + TCHAR *sp, *ep; + int lenSec, lenKey; + enum quote_option quotes; + INI_FILETYPE fp; + + if (Callback == NULL) + return 0; + if (!ini_openread(Filename, &fp)) + return 0; + + LocalBuffer[0] = '\0'; /* copy an empty section in the buffer */ + lenSec = _tcslen(LocalBuffer) + 1; + for ( ;; ) { + if (!ini_read(LocalBuffer + lenSec, INI_BUFFERSIZE - lenSec, &fp)) + break; + sp = skipleading(LocalBuffer + lenSec); + /* ignore empty strings and comments */ + if (*sp == '\0' || *sp == ';' || *sp == '#') + continue; + /* see whether we reached a new section */ + ep = _tcschr(sp, ']'); + if (*sp == '[' && ep != NULL) { + *ep = '\0'; + save_strncpy(LocalBuffer, sp + 1, INI_BUFFERSIZE, QUOTE_NONE); + lenSec = _tcslen(LocalBuffer) + 1; + continue; + } /* if */ + /* not a new section, test for a key/value pair */ + ep = _tcschr(sp, '='); /* test for the equal sign or colon */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + if (ep == NULL) + continue; /* invalid line, ignore */ + *ep++ = '\0'; /* split the key from the value */ + striptrailing(sp); + save_strncpy(LocalBuffer + lenSec, sp, INI_BUFFERSIZE - lenSec, QUOTE_NONE); + lenKey = _tcslen(LocalBuffer + lenSec) + 1; + /* clean up the value */ + sp = skipleading(ep); + sp = cleanstring(sp, "es); /* Remove a trailing comment */ + save_strncpy(LocalBuffer + lenSec + lenKey, sp, INI_BUFFERSIZE - lenSec - lenKey, quotes); + /* call the callback */ + if (!Callback(LocalBuffer, LocalBuffer + lenSec, LocalBuffer + lenSec + lenKey, UserData)) + break; + } /* for */ + + (void)ini_close(&fp); + return 1; +} +#endif /* INI_NOBROWSE */ + +#if ! defined INI_READONLY +static void ini_tempname(TCHAR *dest, const TCHAR *source, int maxlength) +{ + TCHAR *p; + + save_strncpy(dest, source, maxlength, QUOTE_NONE); + p = _tcsrchr(dest, '\0'); + assert(p != NULL); + *(p - 1) = '~'; +} + +static enum quote_option check_enquote(const TCHAR *Value) +{ + const TCHAR *p; + + /* run through the value, if it has trailing spaces, or '"', ';' or '#' + * characters, enquote it + */ + assert(Value != NULL); + for (p = Value; *p != '\0' && *p != '"' && *p != ';' && *p != '#'; p++) + /* nothing */; + return (*p != '\0' || (p > Value && *(p - 1) == ' ')) ? QUOTE_ENQUOTE : QUOTE_NONE; +} + +static void writesection(TCHAR *LocalBuffer, const TCHAR *Section, INI_FILETYPE *fp) +{ + TCHAR *p; + + if (Section != NULL && _tcslen(Section) > 0) { + LocalBuffer[0] = '['; + save_strncpy(LocalBuffer + 1, Section, INI_BUFFERSIZE - 4, QUOTE_NONE); /* -1 for '[', -1 for ']', -2 for '\r\n' */ + p = _tcsrchr(LocalBuffer, '\0'); + assert(p != NULL); + *p++ = ']'; + _tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */ + (void)ini_write(LocalBuffer, fp); + } /* if */ +} + +static void writekey(TCHAR *LocalBuffer, const TCHAR *Key, const TCHAR *Value, INI_FILETYPE *fp) +{ + TCHAR *p; + enum quote_option option = check_enquote(Value); + save_strncpy(LocalBuffer, Key, INI_BUFFERSIZE - 3, QUOTE_NONE); /* -1 for '=', -2 for '\r\n' */ + p = _tcsrchr(LocalBuffer, '\0'); + assert(p != NULL); + *p++ = '='; + save_strncpy(p, Value, INI_BUFFERSIZE - (p - LocalBuffer) - 2, option); /* -2 for '\r\n' */ + p = _tcsrchr(LocalBuffer, '\0'); + assert(p != NULL); + _tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */ + (void)ini_write(LocalBuffer, fp); +} + +static int cache_accum(const TCHAR *string, int *size, int max) +{ + int len = _tcslen(string); + if (*size + len >= max) + return 0; + *size += len; + return 1; +} + +static int cache_flush(TCHAR *buffer, int *size, + INI_FILETYPE *rfp, INI_FILETYPE *wfp, INI_FILEPOS *mark) +{ + int pos = 0; + + (void)ini_seek(rfp, mark); + assert(buffer != NULL); + buffer[0] = '\0'; + assert(size != NULL); + while (pos < *size) { + (void)ini_read(buffer + pos, INI_BUFFERSIZE - pos, rfp); + pos += _tcslen(buffer + pos); + assert(pos <= *size); + } /* while */ + if (buffer[0] != '\0') + (void)ini_write(buffer, wfp); + (void)ini_tell(rfp, mark); /* update mark */ + *size = 0; + /* return whether the buffer ended with a line termination */ + return (_tcscmp(buffer + pos - _tcslen(INI_LINETERM), INI_LINETERM) == 0); +} + +static int close_rename(INI_FILETYPE *rfp, INI_FILETYPE *wfp, const TCHAR *filename, TCHAR *buffer) +{ + (void)ini_close(rfp); + (void)ini_close(wfp); + (void)ini_remove(filename); + (void)ini_tempname(buffer, filename, INI_BUFFERSIZE); + (void)ini_rename(buffer, filename); + return 1; +} + +/** ini_puts() + * \param Section the name of the section to write the string in + * \param Key the name of the entry to write, or NULL to erase all keys in the section + * \param Value a pointer to the buffer the string, or NULL to erase the key + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename) +{ + INI_FILETYPE rfp; + INI_FILETYPE wfp; + INI_FILEPOS mark; + TCHAR *sp, *ep; + TCHAR LocalBuffer[INI_BUFFERSIZE]; + int len, match, flag, cachelen; + + assert(Filename != NULL); + if (!ini_openread(Filename, &rfp)) { + /* If the .ini file doesn't exist, make a new file */ + if (Key != NULL && Value != NULL) { + if (!ini_openwrite(Filename, &wfp)) + return 0; + writesection(LocalBuffer, Section, &wfp); + writekey(LocalBuffer, Key, Value, &wfp); + (void)ini_close(&wfp); + } /* if */ + return 1; + } /* if */ + + /* If parameters Key and Value are valid (so this is not an "erase" request) + * and the setting already exists and it already has the correct value, do + * nothing. This early bail-out avoids rewriting the INI file for no reason. + */ + if (Key != NULL && Value != NULL) { + (void)ini_tell(&rfp, &mark); + match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer)); + if (match && _tcscmp(LocalBuffer,Value) == 0) { + (void)ini_close(&rfp); + return 1; + } /* if */ + /* key not found, or different value -> proceed (but rewind the input file first) */ + (void)ini_seek(&rfp, &mark); + } /* if */ + + /* Get a temporary file name to copy to. Use the existing name, but with + * the last character set to a '~'. + */ + ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE); + if (!ini_openwrite(LocalBuffer, &wfp)) { + (void)ini_close(&rfp); + return 0; + } /* if */ + (void)ini_tell(&rfp, &mark); + cachelen = 0; + + /* Move through the file one line at a time until a section is + * matched or until EOF. Copy to temp file as it is read. + */ + len = (Section != NULL) ? _tcslen(Section) : 0; + if (len > 0) { + do { + if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { + /* Failed to find section, so add one to the end */ + flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key!=NULL && Value!=NULL) { + if (!flag) + (void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */ + writesection(LocalBuffer, Section, &wfp); + writekey(LocalBuffer, Key, Value, &wfp); + } /* if */ + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ + } /* if */ + /* Copy the line from source to dest, but not if this is the section that + * we are looking for and this section must be removed + */ + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, ']'); + match = (*sp == '[' && ep != NULL && (int)(ep-sp-1) == len && _tcsnicmp(sp + 1,Section,len) == 0); + if (!match || Key != NULL) { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ + } /* if */ + } while (!match); + } /* if */ + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + /* when deleting a section, the section head that was just found has not been + * copied to the output file, but because this line was not "accumulated" in + * the cache, the position in the input file was reset to the point just + * before the section; this must now be skipped (again) + */ + if (Key == NULL) { + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + (void)ini_tell(&rfp, &mark); + } /* if */ + + /* Now that the section has been found, find the entry. Stop searching + * upon leaving the section's area. Copy the file as it is read + * and create an entry if one is not found. + */ + len = (Key!=NULL) ? _tcslen(Key) : 0; + for( ;; ) { + if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { + /* EOF without an entry so make one */ + flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key!=NULL && Value!=NULL) { + if (!flag) + (void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */ + writekey(LocalBuffer, Key, Value, &wfp); + } /* if */ + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ + } /* if */ + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, '='); /* Parse out the equal sign */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + match = (ep != NULL && (int)(skiptrailing(ep,sp)-sp) == len && _tcsnicmp(sp,Key,len) == 0); + if ((Key != NULL && match) || *sp == '[') + break; /* found the key, or found a new section */ + /* copy other keys in the section */ + if (Key == NULL) { + (void)ini_tell(&rfp, &mark); /* we are deleting the entire section, so update the read position */ + } else { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ + } /* if */ + } /* for */ + /* the key was found, or we just dropped on the next section (meaning that it + * wasn't found); in both cases we need to write the key, but in the latter + * case, we also need to write the line starting the new section after writing + * the key + */ + flag = (*sp == '['); + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key != NULL && Value != NULL) + writekey(LocalBuffer, Key, Value, &wfp); + /* cache_flush() reset the "read pointer" to the start of the line with the + * previous key or the new section; read it again (because writekey() destroyed + * the buffer) + */ + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + if (flag) { + /* the new section heading needs to be copied to the output file */ + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } else { + /* forget the old key line */ + (void)ini_tell(&rfp, &mark); + } /* if */ + /* Copy the rest of the INI file */ + while (ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ + } /* while */ + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ +} + +/* Ansi C "itoa" based on Kernighan & Ritchie's "Ansi C" book. */ +#define ABS(v) ((v) < 0 ? -(v) : (v)) + +static void strreverse(TCHAR *str) +{ + TCHAR t; + int i, j; + + for (i = 0, j = _tcslen(str) - 1; i < j; i++, j--) { + t = str[i]; + str[i] = str[j]; + str[j] = t; + } /* for */ +} + +static void long2str(long value, TCHAR *str) +{ + int i = 0; + long sign = value; + int n; + + /* generate digits in reverse order */ + do { + n = (int)(value % 10); /* get next lowest digit */ + str[i++] = (TCHAR)(ABS(n) + '0'); /* handle case of negative digit */ + } while (value /= 10); /* delete the lowest digit */ + if (sign < 0) + str[i++] = '-'; + str[i] = '\0'; + + strreverse(str); +} + +/** ini_putl() + * \param Section the name of the section to write the value in + * \param Key the name of the entry to write + * \param Value the value to write + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_putl(const TCHAR *Section, const TCHAR *Key, long Value, const TCHAR *Filename) +{ + TCHAR LocalBuffer[32]; + long2str(Value, LocalBuffer); + return ini_puts(Section, Key, LocalBuffer, Filename); +} + +#if defined INI_REAL +/** ini_putf() + * \param Section the name of the section to write the value in + * \param Key the name of the entry to write + * \param Value the value to write + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + ini_ftoa(LocalBuffer, Value); + return ini_puts(Section, Key, LocalBuffer, Filename); +} +#endif /* INI_REAL */ +#endif /* !INI_READONLY */ diff --git a/src/minini/dev/minIni.h b/src/minini/dev/minIni.h new file mode 100644 index 0000000..cf44e31 --- /dev/null +++ b/src/minini/dev/minIni.h @@ -0,0 +1,152 @@ +/* minIni - Multi-Platform INI file parser, suitable for embedded systems
+ *
+ * Copyright (c) CompuPhase, 2008-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Version: $Id: minIni.h 45 2012-05-14 11:53:09Z thiadmer.riemersma $
+ */
+#ifndef MININI_H
+#define MININI_H
+
+#include "minGlue.h"
+
+#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined MININI_ANSI
+ #include <tchar.h>
+ #define mTCHAR TCHAR
+#else
+ /* force TCHAR to be "char", but only for minIni */
+ #define mTCHAR char
+#endif
+
+#if !defined INI_BUFFERSIZE
+ #define INI_BUFFERSIZE 512
+#endif
+
+#if defined __cplusplus
+ extern "C" {
+#endif
+
+int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename);
+long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename);
+int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+
+#if defined INI_REAL
+INI_REAL ini_getf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL DefValue, const mTCHAR *Filename);
+#endif
+
+#if !defined INI_READONLY
+int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename);
+int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename);
+#if defined INI_REAL
+int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename);
+#endif
+#endif /* INI_READONLY */
+
+#if !defined INI_NOBROWSE
+typedef int (*INI_CALLBACK)(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const void *UserData);
+int ini_browse(INI_CALLBACK Callback, const void *UserData, const mTCHAR *Filename);
+#endif /* INI_NOBROWSE */
+
+#if defined __cplusplus
+ }
+#endif
+
+
+#if defined __cplusplus
+
+#if defined __WXWINDOWS__
+ #include "wxMinIni.h"
+#else
+ #include <string>
+
+ /* The C++ class in minIni.h was contributed by Steven Van Ingelgem. */
+ class minIni
+ {
+ public:
+ minIni(const std::string& filename) : iniFilename(filename)
+ { }
+
+ bool getbool(const std::string& Section, const std::string& Key, bool DefValue=false) const
+ { return ini_getbool(Section.c_str(), Key.c_str(), int(DefValue), iniFilename.c_str()) != 0; }
+
+ long getl(const std::string& Section, const std::string& Key, long DefValue=0) const
+ { return ini_getl(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); }
+
+ int geti(const std::string& Section, const std::string& Key, int DefValue=0) const
+ { return static_cast<int>(this->getl(Section, Key, long(DefValue))); }
+
+ std::string gets(const std::string& Section, const std::string& Key, const std::string& DefValue="") const
+ {
+ char buffer[INI_BUFFERSIZE];
+ ini_gets(Section.c_str(), Key.c_str(), DefValue.c_str(), buffer, INI_BUFFERSIZE, iniFilename.c_str());
+ return buffer;
+ }
+
+ std::string getsection(int idx) const
+ {
+ char buffer[INI_BUFFERSIZE];
+ ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.c_str());
+ return buffer;
+ }
+
+ std::string getkey(const std::string& Section, int idx) const
+ {
+ char buffer[INI_BUFFERSIZE];
+ ini_getkey(Section.c_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.c_str());
+ return buffer;
+ }
+
+#if defined INI_REAL
+ INI_REAL getf(const std::string& Section, const std::string& Key, INI_REAL DefValue=0) const
+ { return ini_getf(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); }
+#endif
+
+#if ! defined INI_READONLY
+ bool put(const std::string& Section, const std::string& Key, long Value) const
+ { return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
+
+ bool put(const std::string& Section, const std::string& Key, int Value) const
+ { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
+
+ bool put(const std::string& Section, const std::string& Key, bool Value) const
+ { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
+
+ bool put(const std::string& Section, const std::string& Key, const std::string& Value) const
+ { return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()) != 0; }
+
+ bool put(const std::string& Section, const std::string& Key, const char* Value) const
+ { return ini_puts(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
+
+#if defined INI_REAL
+ bool put(const std::string& Section, const std::string& Key, INI_REAL Value) const
+ { return ini_putf(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
+#endif
+
+ bool del(const std::string& Section, const std::string& Key) const
+ { return ini_puts(Section.c_str(), Key.c_str(), 0, iniFilename.c_str()) != 0; }
+
+ bool del(const std::string& Section) const
+ { return ini_puts(Section.c_str(), 0, 0, iniFilename.c_str()) != 0; }
+#endif
+
+ private:
+ std::string iniFilename;
+ };
+
+#endif /* __WXWINDOWS__ */
+#endif /* __cplusplus */
+
+#endif /* MININI_H */
diff --git a/src/minini/dev/my_SDL_stdinc.c b/src/minini/dev/my_SDL_stdinc.c new file mode 100644 index 0000000..74c9b63 --- /dev/null +++ b/src/minini/dev/my_SDL_stdinc.c @@ -0,0 +1,24 @@ +#include "my_SDL_stdinc.h" + +char * my_SDL_RWfgets(SDL_RWops *context, char *ptr, size_t maxsize) { + Sint64 pos; + size_t read,firstlinelen; + char * ptr_firstline_end; + + pos = SDL_RWtell(context); + if (pos==-1) return NULL; + + read = SDL_RWread(context, ptr, 1, maxsize); + if (read <= 0) return NULL; + + ptr_firstline_end=SDL_strchr(ptr, '\n'); + + if (ptr_firstline_end != NULL) { + *(ptr_firstline_end+1)='\0'; + firstlinelen = (size_t) (ptr_firstline_end - ptr); + pos = SDL_RWseek(context, pos+firstlinelen+1, RW_SEEK_SET); + if (pos == -1) return NULL; + } + return ptr; +} + diff --git a/src/minini/dev/my_SDL_stdinc.h b/src/minini/dev/my_SDL_stdinc.h new file mode 100644 index 0000000..c7a04be --- /dev/null +++ b/src/minini/dev/my_SDL_stdinc.h @@ -0,0 +1,4 @@ +#include <SDL_rwops.h> +#include <SDL_stdinc.h> + +char * my_SDL_RWfgets(SDL_RWops *context, char *ptr, size_t maxsize); diff --git a/src/minini/dev/test.c b/src/minini/dev/test.c new file mode 100644 index 0000000..88247d3 --- /dev/null +++ b/src/minini/dev/test.c @@ -0,0 +1,114 @@ +/* Simple test program + * + * gcc -o test test.c minIni.c + */ +#include <assert.h> +/* +#include <stdio.h> +#include <string.h> +*/ +#include "minIni.h" + +#define sizearray(a) (sizeof(a) / sizeof((a)[0])) + +const char inifile[] = "src/minini/dev/test.ini"; +const char inifile2[] = "src/minini/dev/testplain.ini"; + +int Callback(const char *section, const char *key, const char *value, const void *userdata) +{ + (void)userdata; /* this parameter is not used in this example */ + printf(" [%s]\t%s=%s\n", section, key, value); + return 1; +} + +int main(void) +{ + char str[100]; + long n; + int s, k; + char section[50]; + + /* string reading */ + n = ini_gets("first", "string", "dummy", str, sizearray(str), inifile); + assert(n==4 && SDL_strcmp(str,"noot")==0); + n = ini_gets("second", "string", "dummy", str, sizearray(str), inifile); + assert(n==4 && SDL_strcmp(str,"mies")==0); + n = ini_gets("first", "undefined", "dummy", str, sizearray(str), inifile); + assert(n==5 && SDL_strcmp(str,"dummy")==0); + /* ----- */ + n = ini_gets("", "string", "dummy", str, sizearray(str), inifile2); + assert(n==4 && SDL_strcmp(str,"noot")==0); + n = ini_gets(NULL, "string", "dummy", str, sizearray(str), inifile2); + assert(n==4 && SDL_strcmp(str,"noot")==0); + /* ----- */ + printf("1. String reading tests passed\n"); + + /* value reading */ + n = ini_getl("first", "val", -1, inifile); + assert(n==1); + n = ini_getl("second", "val", -1, inifile); + assert(n==2); + n = ini_getl("first", "undefined", -1, inifile); + assert(n==-1); + /* ----- */ + n = ini_getl(NULL, "val", -1, inifile2); + assert(n==1); + /* ----- */ + printf("2. Value reading tests passed\n"); + + /* string writing */ + n = ini_puts("first", "alt", "flagged as \"correct\"", inifile); + assert(n==1); + n = ini_gets("first", "alt", "dummy", str, sizearray(str), inifile); + assert(n==20 && SDL_strcmp(str,"flagged as \"correct\"")==0); + /* ----- */ + n = ini_puts("second", "alt", "correct", inifile); + assert(n==1); + n = ini_gets("second", "alt", "dummy", str, sizearray(str), inifile); + assert(n==7 && SDL_strcmp(str,"correct")==0); + /* ----- */ + n = ini_puts("third", "test", "correct", inifile); + assert(n==1); + n = ini_gets("third", "test", "dummy", str, sizearray(str), inifile); + assert(n==7 && SDL_strcmp(str,"correct")==0); + /* ----- */ + n = ini_puts("second", "alt", "overwrite", inifile); + assert(n==1); + n = ini_gets("second", "alt", "dummy", str, sizearray(str), inifile); + assert(n==9 && SDL_strcmp(str,"overwrite")==0); + /* ----- */ + n = ini_puts(NULL, "alt", "correct", inifile2); + assert(n==1); + n = ini_gets(NULL, "alt", "dummy", str, sizearray(str), inifile2); + assert(n==7 && SDL_strcmp(str,"correct")==0); + /* ----- */ + printf("3. String writing tests passed\n"); + + /* section/key enumeration */ + printf("4. Section/key enumertion, file contents follows\n"); + for (s = 0; ini_getsection(s, section, sizearray(section), inifile) > 0; s++) { + printf(" [%s]\n", section); + for (k = 0; ini_getkey(section, k, str, sizearray(str), inifile) > 0; k++) { + printf("\t%s\n", str); + } /* for */ + } /* for */ + + /* browsing through the file */ + printf("5. browse through all settings, file contents follows\n"); + ini_browse(Callback, NULL, inifile); + + /* string deletion */ + n = ini_puts("first", "alt", NULL, inifile); + assert(n==1); + n = ini_puts("second", "alt", NULL, inifile); + assert(n==1); + n = ini_puts("third", NULL, NULL, inifile); + assert(n==1); + /* ----- */ + n = ini_puts(NULL, "alt", NULL, inifile2); + assert(n==1); + printf("6. String deletion tests passed\n"); + + return 0; +} + diff --git a/src/minini/dev/test.ini b/src/minini/dev/test.ini new file mode 100644 index 0000000..3c22632 --- /dev/null +++ b/src/minini/dev/test.ini @@ -0,0 +1,8 @@ +[First]
+String=noot # trailing commment
+Val=1
+
+[Second]
+Val = 2
+#comment=3
+String = mies
diff --git a/src/minini/dev/test2.cc b/src/minini/dev/test2.cc new file mode 100644 index 0000000..b00501f --- /dev/null +++ b/src/minini/dev/test2.cc @@ -0,0 +1,80 @@ +/* + gcc -o minIni.o -c minIni.c + g++ -o test2.o -c test2.cc + g++ -o test2 test2.o minIni.o + ./test2 +*/ + + +#include <assert> +#include <iostream> +#include <string> +using namespace std ; + +#include "minIni.h" + +int main(void) +{ + minIni ini("test.ini"); + string s; + + /* string reading */ + s = ini.gets( "first", "string" , "aap" ); + assert(s == "noot"); + s = ini.gets( "second", "string" , "aap" ); + assert(s == "mies"); + s = ini.gets( "first", "dummy" , "aap" ); + assert(s == "aap"); + cout << "1. String reading tests passed" << endl ; + + + /* value reading */ + long n; + n = ini.getl("first", "val", -1 ); + assert(n==1); + n = ini.getl("second", "val", -1); + assert(n==2); + n = ini.getl("first", "dummy", -1); + assert(n==-1); + cout << "2. Value reading tests passed" << endl ; + + + /* string writing */ + bool b; + b = ini.put("first", "alt", "flagged as \"correct\""); + assert(b); + s = ini.gets("first", "alt", "aap"); + assert(s=="flagged as \"correct\""); + + b = ini.put("second", "alt", "correct"); + assert(b); + s = ini.gets("second", "alt", "aap"); + assert(s=="correct"); + + n = ini.put("third", "alt", "correct"); + assert(b); + s = ini.gets("third", "alt", "aap" ); + assert(s=="correct"); + cout << "3. String writing tests passed" << endl; + + /* section/key enumeration */ + cout << "4. section/key enumeration; file contents follows" << endl; + string section; + for (int is = 0; section = ini.getsection(is), section.length() > 0; is++) { + cout << " [" << section.c_str() << "]" << endl; + for (int ik = 0; s = ini.getkey(section, ik), s.length() > 0; ik++) { + cout << "\t" << s.c_str() << endl; + } + } + + /* string deletion */ + b = ini.del("first", "alt"); + assert(b); + b = ini.del("second", "alt"); + assert(b); + b = ini.del("third"); + assert(b); + cout << "5. string deletion passed " << endl; + + return 0; +} diff --git a/src/minini/dev/testplain.ini b/src/minini/dev/testplain.ini new file mode 100644 index 0000000..53df5ca --- /dev/null +++ b/src/minini/dev/testplain.ini @@ -0,0 +1,3 @@ +String=noot # trailing commment
+#comment=3
+Val=1
diff --git a/src/minini/dev/wxMinIni.h b/src/minini/dev/wxMinIni.h new file mode 100644 index 0000000..e59a74e --- /dev/null +++ b/src/minini/dev/wxMinIni.h @@ -0,0 +1,101 @@ +/* minIni - Multi-Platform INI file parser, wxWidgets interface
+ *
+ * Copyright (c) CompuPhase, 2008-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Version: $Id: wxMinIni.h 44 2012-01-04 15:52:56Z thiadmer.riemersma@gmail.com $
+ */
+#ifndef WXMININI_H
+#define WXMININI_H
+
+#include <wx/wx.h>
+#include "minIni.h"
+
+class minIni
+{
+public:
+ minIni(const wxString& filename) : iniFilename(filename)
+ { }
+
+ bool getbool(const wxString& Section, const wxString& Key, bool DefValue=false) const
+ { return ini_getbool(Section.utf8_str(), Key.utf8_str(), int(DefValue), iniFilename.utf8_str()) != 0; }
+
+ long getl(const wxString& Section, const wxString& Key, long DefValue=0) const
+ { return ini_getl(Section.utf8_str(), Key.utf8_str(), DefValue, iniFilename.utf8_str()); }
+
+ int geti(const wxString& Section, const wxString& Key, int DefValue=0) const
+ { return static_cast<int>(ini_getl(Section.utf8_str(), Key.utf8_str(), (long)DefValue, iniFilename.utf8_str())); }
+
+ wxString gets(const wxString& Section, const wxString& Key, const wxString& DefValue=wxT("")) const
+ {
+ char buffer[INI_BUFFERSIZE];
+ ini_gets(Section.utf8_str(), Key.utf8_str(), DefValue.utf8_str(), buffer, INI_BUFFERSIZE, iniFilename.utf8_str());
+ wxString result = wxString::FromUTF8(buffer);
+ return result;
+ }
+
+ wxString getsection(int idx) const
+ {
+ char buffer[INI_BUFFERSIZE];
+ ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.utf8_str());
+ wxString result = wxString::FromUTF8(buffer);
+ return result;
+ }
+
+ wxString getkey(const wxString& Section, int idx) const
+ {
+ char buffer[INI_BUFFERSIZE];
+ ini_getkey(Section.utf8_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.utf8_str());
+ wxString result = wxString::FromUTF8(buffer);
+ return result;
+ }
+
+#if defined INI_REAL
+ INI_REAL getf(const wxString& Section, wxString& Key, INI_REAL DefValue=0) const
+ { return ini_getf(Section.utf8_str(), Key.utf8_str(), DefValue, iniFilename.utf8_str()); }
+#endif
+
+#if ! defined INI_READONLY
+ bool put(const wxString& Section, const wxString& Key, long Value) const
+ { return ini_putl(Section.utf8_str(), Key.utf8_str(), Value, iniFilename.utf8_str()) != 0; }
+
+ bool put(const wxString& Section, const wxString& Key, int Value) const
+ { return ini_putl(Section.utf8_str(), Key.utf8_str(), (long)Value, iniFilename.utf8_str()) != 0; }
+
+ bool put(const wxString& Section, const wxString& Key, bool Value) const
+ { return ini_putl(Section.utf8_str(), Key.utf8_str(), (long)Value, iniFilename.utf8_str()) != 0; }
+
+ bool put(const wxString& Section, const wxString& Key, const wxString& Value) const
+ { return ini_puts(Section.utf8_str(), Key.utf8_str(), Value.utf8_str(), iniFilename.utf8_str()) != 0; }
+
+ bool put(const wxString& Section, const wxString& Key, const char* Value) const
+ { return ini_puts(Section.utf8_str(), Key.utf8_str(), Value, iniFilename.utf8_str()) != 0; }
+
+#if defined INI_REAL
+ bool put(const wxString& Section, const wxString& Key, INI_REAL Value) const
+ { return ini_putf(Section.utf8_str(), Key.utf8_str(), Value, iniFilename.utf8_str()) != 0; }
+#endif
+
+ bool del(const wxString& Section, const wxString& Key) const
+ { return ini_puts(Section.utf8_str(), Key.utf8_str(), 0, iniFilename.utf8_str()) != 0; }
+
+ bool del(const wxString& Section) const
+ { return ini_puts(Section.utf8_str(), 0, 0, iniFilename.utf8_str()) != 0; }
+#endif
+
+private:
+ wxString iniFilename;
+};
+
+#endif /* WXMININI_H */
diff --git a/src/minini/doc/minIni.pdf b/src/minini/doc/minIni.pdf Binary files differnew file mode 100644 index 0000000..f0d6fb0 --- /dev/null +++ b/src/minini/doc/minIni.pdf |