summaryrefslogtreecommitdiff
path: root/plugins/sid/sidplay-libs/libsidutils/src/ini
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sid/sidplay-libs/libsidutils/src/ini')
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.am11
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.in426
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/headings.h55
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/headings.i346
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/ini.cpp939
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/ini.h68
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/keys.h54
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/keys.i397
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/list.h31
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/list.i314
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/ini/types.i409
11 files changed, 3050 insertions, 0 deletions
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.am b/plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.am
new file mode 100644
index 00000000..9afbd7db
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.am
@@ -0,0 +1,11 @@
+# The library.
+
+noinst_LTLIBRARIES = libini.la
+
+libini_la_SOURCES = headings.h ini.cpp ini.h \
+keys.h list.h
+
+EXTRA_DIST=headings.i keys.i list.i types.i
+
+# Remove bad default includes
+DEFAULT_INCLUDES=
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.in b/plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.in
new file mode 100644
index 00000000..a7e5247f
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/Makefile.in
@@ -0,0 +1,426 @@
+# Makefile.in generated by automake 1.7.1 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# The library.
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+LIBSIDPLAY2_BUILDERS = @LIBSIDPLAY2_BUILDERS@
+LIBSIDPLAY2_CXXFLAGS = @LIBSIDPLAY2_CXXFLAGS@
+LIBSIDPLAY2_LDFLAGS = @LIBSIDPLAY2_LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LIBVERSION = @LIBVERSION@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+noinst_LTLIBRARIES = libini.la
+
+libini_la_SOURCES = headings.h ini.cpp ini.h \
+keys.h list.h
+
+
+EXTRA_DIST = headings.i keys.i list.i types.i
+
+# Remove bad default includes
+DEFAULT_INCLUDES =
+subdir = src/ini
+mkinstalldirs = $(SHELL) $(top_srcdir)/unix/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/unix/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+libini_la_LDFLAGS =
+libini_la_LIBADD =
+am_libini_la_OBJECTS = ini.lo
+libini_la_OBJECTS = $(am_libini_la_OBJECTS)
+depcomp = $(SHELL) $(top_srcdir)/unix/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ini.Plo
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+ $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libini_la_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libini_la_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/ini/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" = "$$p" && dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libini.la: $(libini_la_OBJECTS) $(libini_la_DEPENDENCIES)
+ $(CXXLINK) $(libini_la_LDFLAGS) $(libini_la_OBJECTS) $(libini_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ini.Plo@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \
+@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCXX_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+
+installdirs:
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-depend distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am info \
+ info-am install install-am install-data install-data-am \
+ install-exec install-exec-am install-info install-info-am \
+ install-man install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/headings.h b/plugins/sid/sidplay-libs/libsidutils/src/ini/headings.h
new file mode 100644
index 00000000..2f7fcf74
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/headings.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ headings.h - Section Heading Manipulation Functions
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _headings_h_
+#define _headings_h_
+
+#include <stdio.h>
+#include "ini.h"
+
+//*******************************************************************************************************************
+// Data structure definitions
+//*******************************************************************************************************************
+struct keys_tag;
+struct ini_t;
+
+// Linked list structure for holding section/heading information.
+struct section_tag
+{
+ char *heading;
+ struct key_tag *first;
+ struct key_tag *last;
+ struct key_tag *selected;
+ struct section_tag *pNext;
+ struct section_tag *pPrev;
+
+#ifdef INI_USE_HASH_TABLE
+ unsigned long crc;
+ struct key_tag *keys[256];
+ struct section_tag *pNext_Acc;
+ struct section_tag *pPrev_Acc;
+#endif // INI_USE_HASH_TABLE
+};
+
+static struct section_tag *__ini_addHeading (struct ini_t *ini, char *heading);
+static struct section_tag *__ini_faddHeading (struct ini_t *ini, FILE *file, long pos, size_t length);
+static struct section_tag *__ini_createHeading (struct ini_t *ini, char *heading);
+static void __ini_deleteHeading (struct ini_t *ini);
+static struct section_tag *__ini_locateHeading (struct ini_t *ini, char *heading);
+
+#endif // _headings_h_
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/headings.i b/plugins/sid/sidplay-libs/libsidutils/src/ini/headings.i
new file mode 100644
index 00000000..11833a99
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/headings.i
@@ -0,0 +1,346 @@
+/***************************************************************************
+ headings.i - Section Heading Manipulation Functions
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "headings.h"
+
+
+/********************************************************************************************************************
+ * Function : __ini_addHeading
+ * Parameters : ini - pointer to ini file database. heading - heading name
+ * Returns : Pointer to new heading.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Adds a new heading to the ini file database and updates the temporary workfile
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct section_tag *__ini_addHeading (ini_t *ini, char *heading)
+{
+ struct section_tag *section;
+ size_t length;
+ long pos;
+
+ // Format heading for storing
+ __ini_strtrim (heading);
+
+ /* Create a backup of the file we are about to edit */
+ if (ini->write == heading)
+ return __ini_locateHeading (ini, heading);
+
+ // Add new heading to work file and read it in
+ // using file add
+ fseek (ini->ftmp, 0, SEEK_END);
+ fputs ("\n[", ini->ftmp);
+ pos = ftell (ini->ftmp);
+ fputs (heading, ini->ftmp);
+ length = (size_t) (ftell (ini->ftmp) - pos);
+ section = __ini_faddHeading (ini, ini->ftmp, pos, length);
+ fseek (ini->ftmp, 0, SEEK_END);
+ fputs ("]\n", ini->ftmp);
+ ini->write = section->heading;
+ return section;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_faddheading
+ * Parameters : ini - pointer to ini file database, file - ini file to read heading from
+ * : pos - heading position in file, length - heading length
+ * Returns : Pointer to new heading.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Adds a new heading to the ini file database from the input file.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct section_tag *__ini_faddHeading (ini_t *ini, FILE *file, long pos, size_t length)
+{
+ struct section_tag *section;
+ char *str;
+
+ if (length)
+ {
+ length++;
+ str = (char *) malloc (sizeof(char) * length);
+ assert (str);
+ fseek (file, pos, SEEK_SET);
+ fgets (str, (int) length, file);
+ __ini_strtrim (str);
+ }
+ else
+ str = "";
+
+ section = __ini_createHeading (ini, str);
+ // Make sure heading was created
+ if (!(section || length))
+ {
+ free (str);
+ return NULL;
+ }
+
+ return section;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_createHeading
+ * Parameters : ini - pointer to ini file database. heading - heading name
+ * Returns : Pointer to new heading.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Adds an entry into the heading linked list ready for formating by the addHeading commands
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct section_tag *__ini_createHeading (ini_t *ini, char *heading)
+{
+ struct section_tag *pNew;
+
+ pNew = __ini_locateHeading (ini, heading);
+ // Check to see if heading already exists
+ if (!pNew)
+ { // Create a new heading;
+ pNew = (struct section_tag *) malloc (sizeof (struct section_tag));
+ assert (pNew);
+ memset (pNew, 0, sizeof (struct section_tag));
+ pNew->heading = heading;
+
+ if (*heading)
+ { // Normal case
+ pNew->pPrev = ini->last;
+ ini->last = pNew;
+ if (pNew->pPrev)
+ pNew->pPrev->pNext = pNew;
+ else
+ ini->first = pNew;
+ }
+ else
+ { // This case must always be first
+ pNew->pNext = ini->first;
+ ini->first = pNew;
+ if (pNew->pNext)
+ pNew->pNext->pPrev = pNew;
+ else
+ ini->last = pNew;
+ }
+
+
+#ifdef INI_USE_HASH_TABLE
+ { // Rev 1.3 - Added
+ struct section_tag *pOld;
+ unsigned long crc32;
+ unsigned char accel;
+
+ crc32 = __ini_createCrc32 (heading, strlen (heading));
+ pNew->crc = crc32;
+ // Rev 1.3 - Add accelerator list
+ accel = (unsigned char) crc32 & 0x0FF;
+ pNew->pPrev_Acc = NULL;
+ pOld = ini->sections[accel];
+ ini->sections[accel] = pNew;
+ if (pOld) pOld->pPrev_Acc = pNew;
+ pNew->pNext_Acc = pOld;
+ }
+#endif // INI_USE_HASH_TABLE
+ }
+
+ ini->selected = pNew;
+ ini->changed = true;
+ return pNew;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_deleteHeading
+ * Parameters : ini - pointer to ini file database. heading - heading name
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Removes a heading from the database only.
+ * : This change does not occur in the file until ini_close is called.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+void __ini_deleteHeading (ini_t *ini)
+{
+ struct section_tag *current_h;
+
+ // Delete Heading
+ current_h = ini->selected;
+ if (current_h)
+ { // Delete Keys
+ while (current_h->first)
+ {
+ current_h->selected = current_h->first;
+ __ini_deleteKey (ini);
+ }
+
+ // Tidy up all users of this heading
+ ini->selected = NULL;
+ if (ini->last == current_h)
+ ini->last = current_h->pPrev;
+
+ // Break heading out of list
+ if (!current_h->pPrev)
+ ini->first = current_h->pNext;
+ else
+ current_h->pPrev->pNext = current_h->pNext;
+ if (current_h->pNext)
+ current_h->pNext->pPrev = current_h->pPrev;
+
+#ifdef INI_USE_HASH_TABLE
+ // Rev 1.3 - Take member out of accelerator list
+ if (!current_h->pPrev_Acc)
+ ini->sections[(unsigned char) current_h->crc & 0x0FF] = current_h->pNext_Acc;
+ else
+ current_h->pPrev_Acc->pNext_Acc = current_h->pNext_Acc;
+ if (current_h->pNext_Acc)
+ current_h->pNext_Acc->pPrev_Acc = current_h->pPrev_Acc;
+#endif // INI_USE_HASH_TABLE
+
+ // Delete Heading
+ if (*current_h->heading)
+ free (current_h->heading);
+ free (current_h);
+ ini->changed = true;
+ }
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_locateHeading
+ * Parameters : ini - pointer to ini file database. heading - heading name
+ * Returns : Pointer to heading.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Locates a heading entry in the database.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct section_tag *__ini_locateHeading (ini_t *ini, char *heading)
+{
+ struct section_tag *current_h;
+
+#ifdef INI_USE_HASH_TABLE
+ // Rev 1.3 - Revised to use new accelerator
+ unsigned long crc32;
+ crc32 = __ini_createCrc32 (heading, strlen (heading));
+
+ // Search for heading
+ for (current_h = ini->sections[(unsigned char) crc32 & 0x0FF]; current_h; current_h = current_h->pNext_Acc)
+ {
+ if (current_h->crc == crc32)
+ {
+ if (!strcmp (current_h->heading, heading))
+ break;
+ }
+ }
+#else
+ // Search for heading
+ for (current_h = ini->first; current_h; current_h = current_h->pNext)
+ {
+ if (!strcmp (current_h->heading, heading))
+ break;
+ }
+#endif // INI_USE_HASH_TABLE
+
+ ini->selected = current_h;
+ return current_h;
+}
+
+
+/********************************************************************************************************************
+ * Function : (public) ini_deleteHeading
+ * Parameters : ini - pointer to ini file descriptor
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Equivalent Microsoft write string API call where both data & key are set to NULL.
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_deleteHeading (ini_fd_t fd)
+{
+ ini_t *ini = (ini_t *) fd;
+ if (!ini->selected)
+ return -1;
+ // Can't delete a temporary section
+ if (ini->selected == &(ini->tmpSection))
+ return -1;
+ __ini_deleteHeading (ini);
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : (public) ini_locateHeading
+ * Parameters : fd - pointer to ini file descriptor
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Equivalent Microsoft write string API call where both data & key are set to NULL.
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_locateHeading (ini_fd_t fd, char *heading)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct section_tag *section;
+
+ if (!heading)
+ return -1;
+
+ section = __ini_locateHeading (ini, heading);
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Rev 1.1 - Remove buffered list
+ if (ini->list)
+ {
+ free (ini->list);
+ ini->list = NULL;
+ }
+#endif // INI_ADD_LIST_SUPPORT
+
+ if (section)
+ return 0;
+
+ // Ok no section was found, but maybe the user is wanting to create a
+ // new one so create it temporarily and see what actually happens later
+ {
+ char *p;
+ size_t length;
+ // Remove old heading
+ section = &(ini->tmpSection);
+ if (section->heading)
+ free (section->heading);
+
+ // Add new heading
+ length = strlen (heading) + 1;
+ p = (char *) malloc (length);
+ if (!p)
+ return -1;
+ memcpy (p, heading, length);
+ section->heading = p;
+ ini->selected = section;
+ }
+ return -1;
+}
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/ini.cpp b/plugins/sid/sidplay-libs/libsidutils/src/ini/ini.cpp
new file mode 100644
index 00000000..b7d39362
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/ini.cpp
@@ -0,0 +1,939 @@
+/***************************************************************************
+ ini.cpp - Reads and writes keys to a
+ ini file.
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ * $Log: ini.cpp,v $
+ * Revision 1.9 2002/02/18 20:02:33 s_a_white
+ * Synced with libini.
+ *
+ * Revision 1.16 2002/02/18 19:56:35 s_a_white
+ * Faster CRC alogarithm for hash key generation.
+ *
+ * Revision 1.15 2002/01/15 21:08:43 s_a_white
+ * crc fix.
+ *
+ * Revision 1.14 2001/11/15 21:19:34 s_a_white
+ * Appended __ini_ to global variables and INI_ to #defines.
+ *
+ * Revision 1.13 2001/11/15 21:13:13 s_a_white
+ * Appended __ini_ to strtrim and createCrc32.
+ *
+ * Revision 1.12 2001/09/30 15:15:30 s_a_white
+ * Fixed backup file removal.
+ *
+ * Revision 1.11 2001/09/22 08:56:06 s_a_white
+ * Added mode support. This is used to determine how the INI file should be
+ * accessed.
+ *
+ * Revision 1.10 2001/08/23 19:59:18 s_a_white
+ * ini_append fix so not freeing wrong buffer.
+ *
+ * Revision 1.9 2001/08/17 19:23:16 s_a_white
+ * Added ini_append.
+ *
+ * Revision 1.8 2001/08/14 22:21:21 s_a_white
+ * Hash table and list removal fixes.
+ *
+ * Revision 1.7 2001/07/27 11:10:15 s_a_white
+ * Simplified __ini_deleteAll.
+ *
+ * Revision 1.6 2001/07/21 09:47:12 s_a_white
+ * Bug Fixes (thanks Andy):
+ * *) After a flush the key and heading are now remembered.
+ * *) ini_deleteAll then ini_close now correctly deletes the ini file.
+ * *) ini_flush with no changes no longer destroys the ini object.
+ *
+ ***************************************************************************/
+
+//*******************************************************************************************************************
+// Include Files
+//*******************************************************************************************************************
+#include <assert.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+#include "ini.h"
+
+#define INI_BUFFER_SIZE (1024 * 5)
+
+
+//*******************************************************************************************************************
+// Function Prototypes
+//*******************************************************************************************************************
+static ini_t *__ini_open (const char *name, ini_mode_t mode);
+static int __ini_close (ini_t *ini, bool flush);
+static void __ini_delete (ini_t *ini);
+static struct key_tag *__ini_locate (ini_t *ini, char *heading, char *key);
+static int __ini_process (ini_t *ini, FILE *file);
+static int __ini_store (ini_t *ini, FILE *file);
+
+
+#ifdef INI_USE_HASH_TABLE
+static const unsigned long __ini_crc32Table[0x100] =
+{
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
+
+/********************************************************************************************************************
+ * Function : createCrc32
+ * Parameters : init - initial crc starting value, pBuf - data to base crc on
+ * : length - length in bytes of data
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Creates a 32 bit CRC based on the input data
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+static unsigned long __ini_createCrc32 (char *pBuf, size_t length)
+{
+ unsigned long crc = 0xffffffff;
+ for (size_t i = 0; i < length; i++)
+ crc = (crc >> 8) ^ __ini_crc32Table[(crc & 0xFF) ^ (unsigned) *pBuf++];
+ return (crc ^ 0xffffffff);
+}
+#endif // INI_USE_HASH_TABLE
+
+
+/********************************************************************************************************************
+ * Function : __ini_strtrim
+ * Parameters : str - string to be trimmed
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Removes all char deemed to be spaces from start and end of string.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+void __ini_strtrim (char *str)
+{
+ long first, last;
+ first = 0;
+ last = strlen (str);
+
+ if (!last--)
+ return;
+
+ // Clip end first
+ while (isspace (str[last]) && last > 0)
+ last--;
+ str[last + 1] = '\0';
+
+ // Clip beginning
+ while (isspace (str[first]) && (first < last))
+ first++;
+ strcpy (str, str + first);
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_open
+ * Parameters : name - ini file to parse
+ * Returns : Pointer to ini database.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Opens an ini data file and reads it's contents into a database
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+ini_t *__ini_open (const char *name, ini_mode_t mode)
+{
+ ini_t *ini;
+ FILE *file = NULL;
+ unsigned long length;
+
+ if (!name)
+ return 0;
+
+ length = strlen(name);
+ if (!length)
+ return 0;
+
+ // Create ini database stub
+ ini = (ini_t *) malloc (sizeof (ini_t));
+ if (!ini)
+ goto ini_openError;
+ memset (ini, 0, sizeof (ini_t));
+
+ // Store ini filename
+ ini->filename = (char *) malloc (sizeof(char) * (strlen(name) + 1));
+ if (!ini->filename)
+ goto ini_openError;
+ strcpy (ini->filename, name);
+
+ // Open input file
+ ini->mode = mode;
+ file = fopen (ini->filename, "rb");
+ if (!file)
+ { // File doesn't exist and we are not allowed
+ // to create one
+ if (mode != INI_NEW)
+ goto ini_openError;
+
+ // Seems we can make so new one, check and
+ // make sure
+ file = fopen (ini->filename, "wb");
+ if (!file)
+ goto ini_openError;
+ ini->newfile = true;
+ fclose (file);
+ }
+
+ // Open backup file
+ if (ini->mode == INI_READ)
+ ini->ftmp = tmpfile ();
+ else
+ {
+ ini->filename[length - 1] = '~';
+ ini->ftmp = fopen (ini->filename, "wb+");
+ ini->filename[length - 1] = name[length - 1];
+ }
+
+ if (!ini->ftmp)
+ goto ini_openError;
+ if (file)
+ { // Process existing ini file
+ if (__ini_process (ini, file) < 0)
+ goto ini_openError;
+ }
+
+ // Rev 1.1 Added - Changed set on open bug fix
+ ini->changed = false;
+return ini;
+
+ini_openError:
+ if (ini)
+ {
+ if (ini->ftmp)
+ { // Close and remove backup file
+ fclose (ini->ftmp);
+ if (ini->mode != INI_READ)
+ {
+ ini->filename[strlen (ini->filename) - 1] = '~';
+ remove (ini->filename);
+ }
+ }
+ if (ini->filename)
+ free (ini->filename);
+ free (ini);
+ }
+
+ if (file)
+ fclose (file);
+
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_close
+ * Parameters : ini - pointer to ini file database. force - if true, the database will be removed from
+ * : memory even if an error occured in saving the new ini file.
+ * Returns : -1 on error, 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Save any changes back to the new ini file.
+ * : The backup file contains all the orignal data + any modifcations appended at the bottom
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int __ini_close (ini_t *ini, bool flush)
+{
+ FILE *file;
+ int ret = 0;
+
+ // Open output file
+ if (ini->changed)
+ {
+ if (!ini->first)
+ remove(ini->filename);
+ else
+ {
+#ifdef INI_ADD_LIST_SUPPORT
+ char *delims;
+ // Rev 1.1 Added - Must remove delims before saving
+ delims = ini->listDelims;
+ ini->listDelims = NULL;
+#endif // INI_ADD_LIST_SUPPORT
+
+ // Not point writing an unchanged file
+ file = fopen (ini->filename, "w");
+ if (file)
+ { // Output all new headers and keys
+ ret = __ini_store (ini, file);
+ fflush (file);
+ fclose (file);
+ }
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Rev 1.1 Added - This was only a flush, so lets restore
+ // the old delims
+ ini->listDelims = delims;
+#endif // INI_ADD_LIST_SUPPORT
+ if (!file)
+ return -1;
+ }
+ }
+
+ // Check if the user dosent want the file closed.
+ if (!flush)
+ return 0;
+
+ // Cleanup
+ fclose (ini->ftmp);
+
+ if (ini->mode != INI_READ)
+ { // If no mods were made, delete tmp file
+ if (!ini->changed || ini->newfile)
+ {
+ ini->filename[strlen (ini->filename) - 1] = '~';
+ remove (ini->filename);
+ }
+ }
+
+ __ini_delete (ini);
+ free (ini->filename);
+
+ if (ini->tmpSection.heading)
+ free (ini->tmpSection.heading);
+ if (ini->tmpKey.key)
+ free (ini->tmpKey.key);
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Rev 1.1 - Remove buffered list
+ if (ini->list)
+ free (ini->list);
+#endif // INI_ADD_LIST_SUPPORT
+
+ free (ini);
+ return ret;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_delete
+ * Parameters : ini - pointer to ini file database.
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Deletes the whole ini database from memory, but leaves the ini stub so the ini_close can be
+ * : called.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+void __ini_delete (ini_t *ini)
+{ // If already deleted, don't delete it again
+ if (!ini->first)
+ return;
+
+ // Go through all sections deleting them
+ while (ini->first)
+ {
+ ini->selected = ini->first;
+ __ini_deleteHeading (ini);
+ }
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Rev 1.1 - Remove buffered list
+ if (ini->list)
+ {
+ free (ini->list);
+ ini->list = NULL;
+ }
+#endif // INI_ADD_LIST_SUPPORT
+
+ ini->changed = true;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_process
+ * Parameters : ini - pointer to ini file database, file - ini file to read heading from
+ * Returns : -1 on error and 0 on success
+ * Globals Used : buffer
+ * Globals Modified : buffer
+ * Description : Read the ini file to determine all valid sections and keys. Also stores the location of
+ * : the keys data for faster accessing.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int __ini_process (ini_t *ini, FILE *file)
+{
+ char *current, ch;
+ long pos, first, last;
+ size_t count;
+ bool inSection, findNewline, newline, isEOF;
+ struct key_tag *key = NULL;
+ char *buffer;
+
+ if (!ini)
+ return -1;
+ if (!file)
+ return -1;
+
+ // Get a read buffer
+ buffer = (char *) malloc (INI_BUFFER_SIZE * sizeof(char));
+ if (buffer == NULL)
+ return -1;
+
+ // Clear out an existing ini structure
+ __ini_delete (ini);
+ pos = 0;
+ first = -1;
+ last = -1;
+ findNewline = false;
+ newline = true;
+ inSection = false;
+ isEOF = false;
+
+ for(;;)
+ {
+ fseek (file, pos, SEEK_SET);
+ current = buffer;
+ count = fread (buffer, sizeof(char),
+ INI_BUFFER_SIZE, file);
+
+ if (count <= 0)
+ {
+ if (feof (file))
+ {
+ count = 1;
+ *buffer = '\x1A';
+ }
+ }
+
+ while (count--)
+ {
+ ch = *current++;
+ switch (ch)
+ {
+ // Check for newline or end of file
+ case '\x1A':
+ isEOF = true;
+ // Deliberate run on
+ case '\n': case '\r': case '\f':
+ inSection = false;
+ newline = true;
+ first = -1;
+ last = -1;
+ findNewline = false;
+ goto __ini_processDataEnd;
+
+ // Check for a comment
+ case ';':
+ case '#':
+ findNewline = true;
+ __ini_processDataEnd:
+ // Now know keys data length
+ if (key)
+ { key->length = (size_t) (pos - key->pos);
+ key = NULL;
+ }
+ break;
+
+ default:
+ if (!findNewline)
+ {
+ switch (ch)
+ {
+ // Check for key value
+ case '=':
+ if (!inSection)
+ { // Make sure the key has a string content
+ last = pos;
+ if (first > 0)
+ {
+ if (!ini->selected) // Handle keys which are not in a section
+ {
+ if (!__ini_faddHeading (ini, file, 0, 0))
+ goto __ini_processError;
+ }
+
+ key = __ini_faddKey (ini, file, first, last - first);
+ if (!key)
+ goto __ini_processError;
+ }
+ }
+
+ findNewline = true;
+ break;
+
+ // Check for header (must start far left)
+ case '[':
+ if (newline)
+ {
+ first = pos + 1;
+ inSection = true;
+ }
+ else
+ findNewline = true;
+ break;
+
+ // Check for header termination
+ case ']':
+ if (inSection)
+ {
+ last = pos;
+ if (first <= last) // Handle []
+ {
+ if (!__ini_faddHeading (ini, file, first, last - first))
+ goto __ini_processError;
+ }
+ }
+ findNewline = true;
+ break;
+
+ default:
+ if (newline)
+ first = pos;
+ break;
+ }
+
+ newline = false;
+ }
+ break;
+ }
+
+ // Rev 1.1 Added - Exit of EOF
+ if (isEOF)
+ break;
+
+ fputc (ch, ini->ftmp);
+ pos++;
+ if (!pos)
+ {
+ printf ("INI file is too large\n");
+ __ini_delete (ini);
+ return -1;
+ }
+ }
+
+ // Exit of EOF
+ if (isEOF)
+ break;
+ }
+ free (buffer);
+ return 0;
+
+__ini_processError:
+ free (buffer);
+ __ini_delete (ini);
+ return -1;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_store
+ * Parameters : ini - pointer to ini file database, file - ini file to read heading from
+ * Returns : -1 on error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Writes a new ini file containing all the necessary changes
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int __ini_store (ini_t *ini, FILE *file)
+{
+ struct section_tag *current_h, *selected_h;
+ struct key_tag *current_k, *selected_k;
+ char *str = NULL;
+ size_t length = 0, equal_pos = 0;
+ int ret = -1;
+
+ if (!ini)
+ return -1;
+ if (!file)
+ return -1;
+
+ // Backup selected heading and key
+ selected_h = ini->selected;
+ selected_k = selected_h->selected;
+
+ current_h = ini->first;
+ while (current_h)
+ {
+ // Output section heading
+ if (*current_h->heading)
+ {
+ if (fprintf (file, "[%s]\n", current_h->heading) < 0)
+ goto __ini_storeError;
+ }
+
+ // Output the sections keys
+ equal_pos = __ini_averageLengthKey (current_h);
+ current_k = current_h->first;
+ while (current_k)
+ {
+ if (((current_k->length + 1) > length) || !str)
+ { // Need more space
+ if (str)
+ free (str);
+ length = current_k->length + 1;
+ str = (char *) malloc (sizeof(char) * length);
+ if (!str)
+ goto __ini_storeError;
+ }
+
+ { // Output key
+ char format[10];
+ // Rev 1.1 Added - to support lining up of equals characters
+ sprintf (format, "%%-%lus=", (unsigned long) equal_pos);
+ if (fprintf (file, format, current_k->key) < 0)
+ goto __ini_storeError;
+ }
+
+ // Output keys data (point to correct keys data)
+ ini->selected = current_h;
+ current_h->selected = current_k;
+ if (ini_readString ((ini_fd_t) ini, str, length) < 0)
+ goto __ini_storeError;
+
+ if (fprintf (file, "%s\n", str) < 0)
+ goto __ini_storeError;
+
+ current_k = current_k->pNext;
+ }
+
+ current_h = current_h->pNext;
+ if (fprintf (file, "\n") < 0)
+ goto __ini_storeError;
+ }
+ ret = 0;
+
+__ini_storeError:
+ if (str)
+ free (str);
+ // Restore selected heading and key
+ ini->selected = selected_h;
+ ini->selected->selected = selected_k;
+ return ret;
+}
+
+
+
+//********************************************************************************************************************
+//********************************************************************************************************************
+// User INI File Manipulation Functions
+//********************************************************************************************************************
+//********************************************************************************************************************
+
+
+/********************************************************************************************************************
+ * Function : ini_open
+ * Parameters : name - ini file to create
+ * Returns : Pointer to ini database.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Opens an ini data file and reads it's contents into a database
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+ini_fd_t INI_LINKAGE ini_open (const char *name, const char *mode,
+ const char *)
+{
+ ini_mode_t _mode;
+ if (!mode)
+ return NULL;
+ // Convert mode
+ switch (*mode)
+ {
+ case 'r': _mode = INI_READ; break;
+ case 'w': _mode = INI_NEW; break;
+ case 'a': _mode = INI_EXIST; break;
+ default: return NULL;
+ }
+ return (ini_fd_t) __ini_open (name, _mode);
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_close
+ * Parameters : ini - pointer to ini file database.
+ * Returns : -1 on error, 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Call close, but make sure ini object IS deleted
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_close (ini_fd_t fd)
+{
+ return __ini_close ((ini_t *) fd, true);
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_flush
+ * Parameters : ini - pointer to ini file database.
+ * Returns : -1 on error, 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Call close, but make sure ini object IS NOT deleted
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_flush (ini_fd_t fd)
+{
+ return __ini_close ((ini_t *) fd, false);
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_dataLength
+ * Parameters : ini - pointer to ini file database. heading - heading name. key - key name
+ * Returns : Number of bytes to read the keys data in as a string. 1 must be added to this length
+ * : to cater for a NULL character.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Number of bytes to read the keys data in as a string
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_dataLength (ini_fd_t fd)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+ if (!ini)
+ return -1;
+
+ // Check to make sure a section/key has
+ // been asked for by the user
+ if (!ini->selected)
+ return -1;
+ _key = ini->selected->selected;
+ if (!_key)
+ return -1;
+
+#ifdef INI_ADD_LIST_SUPPORT
+ if (ini->listDelims)
+ return __ini_listIndexLength (ini);
+#endif
+ return (int) _key->length;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_delete
+ * Parameters : ini - pointer to ini file database.
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Deletes the whole ini database from memory, but leaves the ini stub so the ini_close can be
+ * : called.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+extern "C" int INI_LINKAGE ini_delete (ini_fd_t fd)
+{
+ ini_t *ini = (ini_t *) fd;
+ if (!ini)
+ return -1;
+ __ini_delete (ini);
+ return 0;
+}
+
+
+#ifdef INI_ADD_EXTRAS
+
+/********************************************************************************************************************
+ * Function : ini_append
+ * Parameters : fdsrc - pointer to src ini file database to copy from.
+ * : fddst - pointer to dst ini file database to copy to.
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Copies the contents of the src ini to the dst ini. The resulting ini contains both
+ * : headings and keys from each. Src keys will overwrite dst keys or similar names.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+extern "C" int INI_LINKAGE ini_append (ini_fd_t fddst, ini_fd_t fdsrc)
+{
+ struct section_tag *current_h;
+ struct key_tag *current_k;
+ struct section_tag *src_h, *dst_h;
+ struct key_tag *src_k, *dst_k;
+ char *data = NULL;
+ int length = 0, ret = -1;
+
+#ifdef INI_ADD_LIST_SUPPORT
+ char *delims;
+#endif
+
+ ini_t *src = (ini_t *) fdsrc;
+ ini_t *dst = (ini_t *) fddst;
+ if (!(src && dst))
+ return -1;
+
+ // Backup selected heading and key
+ src_h = src->selected;
+ src_k = src_h->selected;
+ dst_h = dst->selected;
+ dst_k = dst_h->selected;
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Remove delims for proper reads
+ delims = src->listDelims;
+ src->listDelims = NULL;
+#endif
+
+ // Go through the src ini headings
+ current_h = src->first;
+ while (current_h)
+ { // Locate heading in the dst
+ ini_locateHeading (dst, current_h->heading);
+ // Go through the src keys under the heading
+ src->selected = current_h;
+ current_k = current_h->first;
+ while (current_k)
+ { // Check if data buffer can hold the key
+ int i = current_k->length;
+ current_h->selected = current_k;
+ if (i > length)
+ { // Make data buffer bigger, with some spare
+ length = i + 10;
+ if (data != NULL)
+ free (data);
+ data = (char *) malloc (sizeof (char) * length);
+ if (data == NULL)
+ goto ini_appendError;
+ }
+ // Locate key in dst ini file
+ ini_locateKey (dst, current_k->key);
+ // Copy the key from src to dst ini file
+ if (ini_readString (src, data, length) != i)
+ goto ini_appendError;
+ if (ini_writeString (dst, data) < 0)
+ goto ini_appendError;
+ // Move to next key
+ current_k = current_k->pNext;
+ }
+ // Move to next heading
+ current_h = current_h->pNext;
+ }
+ ret = 0;
+
+ini_appendError:
+ if (data != NULL)
+ free (data);
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Restore delims
+ src->listDelims = delims;
+#endif
+ // Restore selected headings and keys
+ src->selected = src_h;
+ src_h->selected = src_k;
+ dst->selected = dst_h;
+ dst_h->selected = dst_k;
+ return ret;
+}
+
+#endif // INI_ADD_EXTRAS
+
+
+// Add Code Modules
+// Add Header Manipulation Functions
+#include "headings.i"
+// Add Key Manipulation Functions
+#include "keys.i"
+// Add Supported Datatypes
+#include "types.i"
+// Add List Support
+#ifdef INI_ADD_LIST_SUPPORT
+# include "list.i"
+#endif // INI_ADD_LIST_SUPPORT
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/ini.h b/plugins/sid/sidplay-libs/libsidutils/src/ini/ini.h
new file mode 100644
index 00000000..bc622cba
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/ini.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ ini.h - Ini database definition
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _ini_h_
+#define _ini_h_
+
+#define INI_USE_HASH_TABLE
+
+#include "libini.h"
+#include "keys.h"
+#include "headings.h"
+#ifdef INI_ADD_LIST_SUPPORT
+# include "list.h"
+#endif
+
+typedef enum {INI_NEW, INI_EXIST, INI_READ} ini_mode_t;
+
+// Database containing all information about an ini file.
+typedef struct ini_t
+{
+ char *filename;
+ FILE *ftmp; // Temporary work file
+ bool changed;
+ bool newfile;
+ ini_mode_t mode; // Access mode
+
+ struct section_tag *first;
+ struct section_tag *last;
+ struct section_tag *selected;
+ char *write; // Last written section.
+ struct section_tag tmpSection;
+ struct key_tag tmpKey;
+
+#ifdef INI_USE_HASH_TABLE
+ struct section_tag *sections[256];
+#endif
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Rev 1.1 Added - New for list accessing
+ char *list; // Accelerator for accessing same list (When all list read, will be freed)
+ char *listDelims; // list sperators
+ char *listIndexPtr; // current element we wish to access (will auto increment)
+ unsigned int listLength;
+ unsigned int listIndex;
+#endif // INI_ADD_LIST_SUPPORT
+} ini_t;
+
+static void __ini_strtrim (char *str);
+#ifdef INI_USE_HASH_TABLE
+static unsigned long __ini_createCrc32 (char *pBuf, size_t length);
+#endif
+
+#endif // _ini_h_
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/keys.h b/plugins/sid/sidplay-libs/libsidutils/src/ini/keys.h
new file mode 100644
index 00000000..2bef0ff4
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/keys.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ keys.h - Key Manipulation Functions
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _keys_h_
+#define _keys_h_
+
+#include <stdio.h>
+#include "ini.h"
+
+//*******************************************************************************************************************
+// Data structure definitions
+//*******************************************************************************************************************
+struct ini_t;
+struct section_tag;
+
+// Linked list structure for holding key information.
+struct key_tag
+{
+ char *key;
+ long pos;
+ size_t length;
+ struct key_tag *pNext;
+ struct key_tag *pPrev;
+
+#ifdef INI_USE_HASH_TABLE
+ unsigned long crc;
+ struct key_tag *pNext_Acc;
+ struct key_tag *pPrev_Acc;
+#endif // INI_USE_HASH_TABLE
+};
+
+static struct key_tag *__ini_addKey (struct ini_t *ini, char *key);
+static struct key_tag *__ini_faddKey (struct ini_t *ini, FILE *file, long pos, size_t length);
+static struct key_tag *__ini_createKey (struct ini_t *ini, char *key);
+static void __ini_deleteKey (struct ini_t *ini);
+static struct key_tag *__ini_locateKey (struct ini_t *ini, char *key);
+static size_t __ini_averageLengthKey (struct section_tag *current_h);
+
+#endif // _keys_h_
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/keys.i b/plugins/sid/sidplay-libs/libsidutils/src/ini/keys.i
new file mode 100644
index 00000000..5507b95d
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/keys.i
@@ -0,0 +1,397 @@
+/***************************************************************************
+ keys.i - Key Manipulation Functions
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "keys.h"
+
+#define INI_EQUALS_ALIGN 10
+
+
+/********************************************************************************************************************
+ * Function : __ini_addKey
+ * Parameters : ini - pointer to ini file database. key - key name
+ * Returns : Pointer to key.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Adds a new key to the ini file database and updates the temporary workfile.
+ * : A heading operation must be called before this function.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct key_tag *__ini_addKey (ini_t *ini, char *key)
+{
+ struct key_tag *_key;
+ size_t length;
+ long pos;
+
+ // Format heading for storing
+ __ini_strtrim (key);
+ if (!*key)
+ return NULL;
+
+ // Add new key to work file and read it in
+ // using file add
+ fseek (ini->ftmp, 0, SEEK_END);
+ pos = ftell (ini->ftmp);
+ fputs (key, ini->ftmp);
+ length = (size_t) (ftell (ini->ftmp) - pos);
+ _key = __ini_faddKey (ini, ini->ftmp, pos, length);
+ fseek (ini->ftmp, 0, SEEK_END);
+ fputc ('=', ini->ftmp);
+ return _key;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_averageLengthKey
+ * Parameters : current_h - pointer to current header.
+ * Returns : Returns the average key length
+ * Globals Used :
+ * Globals Modified :
+ * Description : Finds average key length for aligning equals.
+ ********************************************************************************************************************/
+size_t __ini_averageLengthKey (struct section_tag *current_h)
+{
+#ifdef INI_EQUALS_ALIGN
+ size_t equal_pos, equal_max, keylength;
+ size_t average = 0, count = 0;
+ struct key_tag *current_k;
+
+ // Rev 1.1 Added - Line up equals characters for keys
+ // Calculate Average
+ current_k = current_h->first;
+ while (current_k)
+ {
+ count++;
+ average += strlen (current_k->key);
+ current_k = current_k->pNext;
+ }
+
+ if (!count)
+ return 0;
+
+ average /= count;
+ equal_pos = (equal_max = average);
+
+#if INI_EQUALS_ALIGN > 0
+ // Work out the longest key in that range
+ current_k = current_h->first;
+ while (current_k)
+ {
+ keylength = strlen (current_k->key);
+ equal_max = average + INI_EQUALS_ALIGN;
+
+ if ((equal_max > keylength) && (keylength > equal_pos))
+ equal_pos = keylength;
+ current_k = current_k->pNext;
+ }
+#endif // INI_EQUALS_ALIGN > 0
+ return equal_pos;
+#else
+ return 0;
+#endif // INI_EQUALS_ALIGN
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_faddKey
+ * Parameters : ini - pointer to ini file database, file - ini file to read key from
+ * : pos - key position in file, length - key length
+ * Returns : Pointer to key.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Adds a new key to the ini file database from the input file.
+ * : A heading operation must be called before this function.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct key_tag *__ini_faddKey (ini_t *ini, FILE *file, long pos, size_t length)
+{
+ struct key_tag *_key;
+ char *str;
+
+ length++;
+ str = (char *) malloc (sizeof(char) * length);
+ assert (str);
+ fseek (file, pos, SEEK_SET);
+ fgets (str, (int) length, file);
+ __ini_strtrim (str);
+
+ _key = __ini_createKey (ini, str);
+ if (!_key)
+ { free (str);
+ return NULL;
+ }
+
+ _key->pos = pos + (long) length;
+ return _key;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_createKey
+ * Parameters : ini - pointer to ini file database. key - key name
+ * Returns : Pointer to key.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Adds an entry into the key linked list ready for formating by the addKey commands
+ * : A heading operation must be called before this function.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct key_tag *__ini_createKey (ini_t *ini, char *key)
+{
+ struct section_tag *section;
+ struct key_tag *pNew;
+ long pos;
+
+ if (!*key)
+ return NULL;
+
+ section = ini->selected;
+ pNew = __ini_locateKey (ini, key);
+ if (pNew)
+ { // Reset details of existing key
+ free (pNew->key);
+ pNew->key = key;
+ pos = 0;
+ }
+ else
+ { // Create a new key and add at end;
+ pNew = (struct key_tag *) malloc (sizeof (struct key_tag));
+ if (!pNew)
+ return NULL;
+ memset (pNew, 0, sizeof (struct key_tag));
+ pNew->key = key;
+
+ if (!section->first)
+ section->first = pNew;
+ else
+ section->last->pNext = pNew;
+
+ pNew->pPrev = section->last;
+ section->last = pNew;
+ section->selected = pNew;
+
+#ifdef INI_USE_HASH_TABLE
+ { // Rev 1.3 - Added
+ struct key_tag *pOld;
+ unsigned long crc32;
+ unsigned char accel;
+
+ crc32 = __ini_createCrc32 (key, strlen (key));
+ pNew->crc = crc32;
+ // Rev 1.3 - Add accelerator list
+ accel = (unsigned char) crc32 & 0x0FF;
+ pNew->pPrev_Acc = NULL;
+ pOld = section->keys[accel];
+ section->keys[accel] = pNew;
+ if (pOld) pOld->pPrev_Acc = pNew;
+ pNew->pNext_Acc = pOld;
+ }
+#endif
+ }
+
+ section->selected = pNew;
+ ini->changed = true;
+ return pNew;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_deleteKey
+ * Parameters : ini - pointer to ini file database. key - key name
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Removes a key from the database only.
+ * : This change does not occur in the file until ini_close is called.
+ * : A heading operation must be called before this function.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+void __ini_deleteKey (ini_t *ini)
+{
+ struct key_tag *current_k;
+ struct section_tag *section = ini->selected;
+
+ current_k = section->selected;
+ if (current_k)
+ {
+ // Tidy up all users of this key
+ section->selected = NULL;
+ if (section->last == current_k)
+ section->last = current_k->pPrev;
+
+ // Check to see if all keys were removed
+ if (!current_k->pPrev)
+ section->first = current_k->pNext;
+ else
+ current_k->pPrev->pNext = current_k->pNext;
+ if (current_k->pNext)
+ current_k->pNext->pPrev = current_k->pPrev;
+
+#ifdef INI_USE_HASH_TABLE
+ // Rev 1.3 - Take member out of accelerator list
+ if (!current_k->pPrev_Acc)
+ section->keys[(unsigned char) current_k->crc & 0x0FF] = current_k->pNext_Acc;
+ else
+ current_k->pPrev_Acc->pNext_Acc = current_k->pNext_Acc;
+ if (current_k->pNext_Acc)
+ current_k->pNext_Acc->pPrev_Acc = current_k->pPrev_Acc;
+#endif // INI_USE_HASH_TABLE
+
+ // Delete Key
+ free (current_k->key);
+ free (current_k);
+ ini->changed = true;
+ }
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_locateKey
+ * Parameters : ini - pointer to ini file database. key - key name
+ * Returns : Pointer to key.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Locates a key entry in the database.
+ * : A heading operation must be called before this function.
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+struct key_tag *__ini_locateKey (ini_t *ini, char *key)
+{
+ struct key_tag *current_k;
+ struct section_tag *section;
+ section = ini->selected;
+
+#ifdef INI_USE_HASH_TABLE
+ { // Rev 1.3 - Added
+ unsigned long crc32;
+ crc32 = __ini_createCrc32 (key, strlen (key));
+
+ // Search for key
+ for (current_k = section->keys[(unsigned char) crc32 & 0x0FF]; current_k; current_k = current_k->pNext_Acc)
+ {
+ if (current_k->crc == crc32)
+ {
+ if (!strcmp (current_k->key, key))
+ break;
+ }
+ }
+ }
+#else
+ { // Search for key
+ for (current_k = section->first; current_k; current_k = current_k->pNext)
+ {
+ if (!strcmp (current_k->key, key))
+ break;
+ }
+ }
+#endif // INI_USE_HASH_TABLE
+
+ section->selected = current_k;
+ return current_k;
+}
+
+
+/********************************************************************************************************************
+ * Function : (public) ini_deleteKey
+ * Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Equivalent Microsoft write string API call where data set to NULL
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_deleteKey (ini_fd_t fd)
+{
+ ini_t *ini = (ini_t *) fd;
+ if (!ini->selected)
+ return -1;
+ // Can't delete a temporary key
+ if (ini->selected->selected == &(ini->tmpKey))
+ return -1;
+
+ __ini_deleteKey (ini);
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : (public) ini_locateKey
+ * Parameters : fd - pointer to ini file descriptor
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description :
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_locateKey (ini_fd_t fd, char *key)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key = NULL;
+
+ if (!key)
+ return -1;
+ if (!ini->selected)
+ return -1;
+
+ // Can't search for a key in a temporary heading
+ if (ini->selected != &(ini->tmpSection))
+ _key = __ini_locateKey (ini, key);
+
+#ifdef INI_ADD_LIST_SUPPORT
+ // Rev 1.1 - Remove buffered list
+ if (ini->list)
+ {
+ free (ini->list);
+ ini->list = NULL;
+ }
+#endif // INI_ADD_LIST_SUPPORT
+
+ if (_key)
+ return 0;
+
+ // Ok no key was found, but maybe the user is wanting to create a
+ // new one so create it temporarily and see what actually happens later
+ {
+ char *p;
+ size_t length;
+ // Remove all key
+ _key = &(ini->tmpKey);
+ if (_key->key)
+ free (_key->key);
+
+ // Add new key
+ length = strlen (key) + 1;
+ p = (char *) malloc (length);
+ if (!p)
+ return -1;
+ memcpy (p, key, length);
+ _key->key = p;
+ ini->selected->selected = _key;
+ }
+ return -1;
+}
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/list.h b/plugins/sid/sidplay-libs/libsidutils/src/ini/list.h
new file mode 100644
index 00000000..9e7f88e4
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/list.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ list.h - Adds list support to ini files
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _list_h_
+#define _list_h_
+
+#include "ini.h"
+#ifdef INI_ADD_LIST_SUPPORT
+
+struct ini_t;
+static int __ini_listEval (struct ini_t *ini);
+static char *__ini_listRead (struct ini_t *ini);
+static int __ini_listIndexLength (struct ini_t *ini);
+
+#endif // INI_ADD_LIST_SUPPORT
+#endif // _list_h_
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/list.i b/plugins/sid/sidplay-libs/libsidutils/src/ini/list.i
new file mode 100644
index 00000000..57f6011d
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/list.i
@@ -0,0 +1,314 @@
+/***************************************************************************
+ list.i - Adds list support to ini files
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "list.h"
+
+#ifdef INI_ADD_LIST_SUPPORT
+
+/********************************************************************************************************************
+ * Function : ini_listEval
+ * Parameters : ini - pointer to ini file database.
+ * Returns : -1 for Error or the numbers of list items found
+ * Globals Used :
+ * Globals Modified :
+ * Description : Uses the currently specified delimiters to calculate the number of eliments in a list
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int __ini_listEval (ini_t *ini)
+{
+ int length, count, i, ret;
+ int ldelim;
+ char ch;
+
+ // Remove old list
+ if (ini->list)
+ {
+ free (ini->list);
+ ini->list = '\0';
+ }
+
+ // Re-evaluate with new settings
+ length = ini->selected->selected->length;
+ if (length < 0)
+ return -1;
+ if (!length)
+ {
+ ini->listIndex = '\0';
+ ini->listLength = 0;
+ if (ini->selected->selected == &ini->tmpKey)
+ return -1; // Can't read tmpKey
+ return 0;
+ }
+
+ // See if there are any chars which can be used to split the string into sub ones
+ if (!ini->listDelims)
+ return -1;
+ ldelim = (int) strlen (ini->listDelims);
+
+ // Buffer string for faster access
+ ini->list = (char *) malloc (length + 1);
+ if (!ini->list)
+ return -1;
+
+ { // Backup up delims to avoid causing problems with readString
+ char *delims = ini->listDelims;
+ ini->listDelims = NULL;
+ ret = ini_readString ((ini_fd_t) ini, ini->list, length + 1);
+ ini->listDelims = delims;
+ if (ret < 0)
+ return -1;
+ }
+
+ // Process buffer string to find number of sub strings
+ {
+ char lastch = '\0';
+ count = 1;
+ while (length)
+ {
+ length--;
+ ch = ini->list[length];
+ for (i = 0; i < ldelim; i++)
+ {
+ if ((char) ch == ini->listDelims[i])
+ { // Prevent lots of NULL strings on multiple
+ // whitespace
+ if (lastch == '\0')
+ {
+ if (isspace (ch))
+ {
+ ch = '\0';
+ break;
+ }
+ }
+
+ // Seperate strings
+ ini->list[length] = (ch = '\0');
+ count++;
+ break;
+ }
+ }
+ lastch = ch;
+ }
+ }
+
+ ini->listLength = count;
+ ini->listIndexPtr = ini->list;
+ ini->listIndex = 0;
+ return count;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_listRead
+ * Parameters : ini - pointer to ini file database.
+ * Returns : NULL for error, string point otherwise
+ * Globals Used :
+ * Globals Modified :
+ * Description : Reads the indexed parameter from the list and auto
+ * : increments
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+char *__ini_listRead (ini_t *ini)
+{
+ char *p;
+
+ // we must read an element from the list
+ // Rev 1.2 Changed order of these two ifs as test was performed
+ // sometimes before anything was read
+ if (!ini->list)
+ {
+ if (__ini_listEval (ini) < 0)
+ return 0;
+ }
+
+ // Check to see if we are trying to get a value beyond the end of the list
+ if (ini->listIndex >= ini->listLength)
+ return 0;
+ p = ini->listIndexPtr;
+ // Auto increment pointers to next index
+ ini->listIndexPtr += (strlen (ini->listIndexPtr) + 1);
+ ini->listIndex++;
+ return p;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_listLength
+ * Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
+ * Returns : -1 for Error or the numbers of list items found
+ * Globals Used :
+ * Globals Modified :
+ * Description : Uses the currently specified delimiters to calculate the number of eliments in a list
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_listLength (ini_fd_t fd)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+
+ // Check to make sure a section/key has
+ // been asked for by the user
+ if (!ini->selected)
+ return -1;
+ _key = ini->selected->selected;
+ if (!_key)
+ return -1;
+
+ // Check to see if we have moved to a new key
+ if (!ini->list)
+ return __ini_listEval (ini);
+
+ return ini->listLength;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_listDelims
+ * Parameters : ini - pointer to ini file database. delims - string of delimitor chars
+ * Returns : -1 for Error or 0 for success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Sets the delimiters used for list accessing, (default delim is NULL)
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_listDelims (ini_fd_t fd, char *delims)
+{
+ ini_t *ini = (ini_t *) fd;
+ if (ini->listDelims)
+ free (ini->listDelims);
+ ini->listDelims = NULL;
+
+ // Make sure we have something to copy
+ if (delims)
+ {
+ if (*delims)
+ { // Store delims for later use
+ ini->listDelims = (char *) malloc (strlen (delims) + 1);
+ if (!ini->listDelims)
+ return -1;
+ strcpy (ini->listDelims, delims);
+ }
+ }
+
+ // List will need recalculating at some point
+ if (ini->list)
+ {
+ free (ini->list);
+ ini->list = NULL;
+ }
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_listIndex
+ * Parameters : ini - pointer to ini file database. delims - string of delimitor chars
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Sets the index that the next call to any of the read function will obtain (default 0)
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_listIndex (ini_fd_t fd, unsigned long index)
+{
+ ini_t *ini = (ini_t *) fd;
+ unsigned int count;
+ char *p;
+
+ // Check to make sure a section/key has
+ // been asked for by the user
+ if (!ini->selected)
+ return -1;
+ if (!ini->selected->selected)
+ return -1;
+
+ // Pull in new list
+ if (!ini->list)
+ {
+ if (__ini_listEval (ini) < 0)
+ return -1;
+ }
+
+ // Now scroll through to required index
+ if (!ini->listLength)
+ return -1;
+ if (index == ini->listIndex)
+ return 0;
+
+ if (index > ini->listIndex)
+ { // Continue search from the from current position
+ count = ini->listIndex;
+ p = ini->listIndexPtr;
+ }
+ else
+ { // Reset list and search from beginning
+ count = 0;
+ p = ini->list;
+ }
+
+ while (count != index)
+ {
+ count++;
+ if (count >= ini->listLength)
+ return -1;
+ // Jump to next sub string
+ p += (strlen (p) + 1);
+ }
+
+ ini->listIndex = count;
+ ini->listIndexPtr = p;
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : __ini_listIndexLength
+ * Parameters : ini - pointer to ini file database
+ * Returns :
+ * Globals Used :
+ * Globals Modified :
+ * Description : Returns the length the indexed sub string
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int __ini_listIndexLength (ini_t *ini)
+{
+ if (!ini->list)
+ { // No list yet. So try to get one
+ if (__ini_listEval (ini) < 0)
+ return -1;
+ }
+
+ // Now return length
+ return strlen (ini->listIndexPtr);
+}
+
+#endif // INI_ADD_LIST_SUPPORT
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/ini/types.i b/plugins/sid/sidplay-libs/libsidutils/src/ini/types.i
new file mode 100644
index 00000000..a59d0dbf
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/ini/types.i
@@ -0,0 +1,409 @@
+/***************************************************************************
+ types.i - Libini supported data types
+ Use readString for others
+
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ini.h"
+
+
+/********************************************************************************************************************
+ * Function : __ini_write
+ * Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
+ * Returns : Pointer to new key.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Make calls to add a new key and appends a description of changes in the backup file
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+static struct key_tag *__ini_write (ini_t *ini)
+{
+ struct section_tag *section;
+ struct key_tag *key;
+
+ // Is file read only?
+ if (ini->mode == INI_READ)
+ return NULL;
+
+ // Check to make sure a section/key has
+ // been asked for by the user
+ section = ini->selected;
+ if (!section)
+ return NULL;
+ key = section->selected;
+ if (!key)
+ return NULL;
+
+ // Add or replace key
+ if (!__ini_addHeading (ini, section->heading))
+ return NULL;
+ return __ini_addKey (ini, key->key);
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_readString
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for error or the number of chars read.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Reads data part from a key and returns it as a string
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size)
+{
+ struct key_tag *_key;
+ ini_t *ini = (ini_t *) fd;
+
+ if (!ini->selected)
+ return -1;
+ if (size <= 0)
+ return -1;
+
+ // Locate and read keys value
+ _key = ini->selected->selected;
+ if (!_key)
+ return -1;
+
+ size--; // Reserve space for NULL
+
+#ifdef INI_ADD_LIST_SUPPORT
+ if (ini->listDelims)
+ {
+ char *data;
+ size_t length;
+
+ data = __ini_listRead (ini);
+ if (!data)
+ return -1;
+
+ // Check to make sure size is correct
+ length = strlen (data);
+ if (size > length)
+ size = length;
+ memcpy (str, data, size);
+ }
+ else
+#endif // INI_ADD_LIST_SUPPORT
+ { // Locate and read back keys data (Index ignored)
+ // Check to make sure size is correct
+ if (size > _key->length)
+ size = _key->length;
+
+ if (size)
+ {
+ fseek (ini->ftmp, _key->pos, SEEK_SET);
+ size = fread (str, sizeof(char), size, ini->ftmp);
+ }
+ else if (_key == &ini->tmpKey)
+ return -1; // Can't read tmpKey
+ }
+
+ str[size] = '\0';
+ __ini_strtrim (str);
+ return size;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_writeString
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Writes data part to a key.
+ * : Conforms to Microsoft API call. E.g. use NULLS to remove headings/keys
+ * : Headings and keys will be created as necessary
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_writeString (ini_fd_t fd, char *str)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+
+ _key = __ini_write (ini);
+ if (!_key)
+ return -1;
+
+ // Write data to bottom of backup file
+ _key->length = strlen (str);
+ fprintf (ini->ftmp, "%s\n", str);
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_readInt
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for error or the number of values read.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Reads data part from a key and returns it as a int
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+
+ // Check to make sure a section has been
+ // asked for by the user
+ if (!ini->selected)
+ return -1;
+ // Locate and read keys value
+ _key = ini->selected->selected;
+ if (!_key)
+ return -1;
+
+#ifdef INI_ADD_LIST_SUPPORT
+ if (ini->listDelims)
+ {
+ char *data;
+ data = __ini_listRead (ini);
+ if (!data)
+ return -1;
+ sscanf (data, "%d", value);
+ }
+ else
+#endif // INI_ADD_LIST_SUPPORT
+ {
+ if (_key->length)
+ { // Locate and read back keys data
+ fseek (ini->ftmp, _key->pos, SEEK_SET);
+ fscanf (ini->ftmp, "%d", value);
+ }
+ else if (_key == &ini->tmpKey)
+ return -1; // Can't read tmpKey
+ }
+
+ return 0;
+}
+
+
+#ifdef INI_ADD_EXTRAS
+
+/********************************************************************************************************************
+ * Function : ini_readLong
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for error or the number of values read.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Reads data part from a key and returns it as a long
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+
+ // Check to make sure a section has been
+ // asked for by the user
+ if (!ini->selected)
+ return -1;
+ // Locate and read keys value
+ _key = ini->selected->selected;
+ if (!_key)
+ return -1;
+
+#ifdef INI_ADD_LIST_SUPPORT
+ if (ini->listDelims)
+ {
+ char *data;
+ data = __ini_listRead (ini);
+ if (!data)
+ return -1;
+ sscanf (data, "%ld", value);
+ }
+ else
+#endif // INI_ADD_LIST_SUPPORT
+ {
+ if (_key->length)
+ { // Locate and read back keys data
+ fseek (ini->ftmp, _key->pos, SEEK_SET);
+ fscanf (ini->ftmp, "%ld", value);
+ }
+ else if (_key == &ini->tmpKey)
+ return -1; // Can't read tmpKey
+ }
+
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_readDouble
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for error or the number of values read.
+ * Globals Used :
+ * Globals Modified :
+ * Description : Reads data part from a key and returns it as a double (real)
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+
+ // Check to make sure a section has been
+ // asked for by the user
+ if (!ini->selected)
+ return -1;
+ // Locate and read keys value
+ _key = ini->selected->selected;
+ if (!_key)
+ return -1;
+
+#ifdef INI_ADD_LIST_SUPPORT
+ if (ini->listDelims)
+ {
+ char *data;
+ data = __ini_listRead (ini);
+ if (!data)
+ return -1;
+ sscanf (data, "%lf", value);
+ }
+ else
+#endif // INI_ADD_LIST_SUPPORT
+ {
+ if (_key->length)
+ { // Locate and read back keys data
+ fseek (ini->ftmp, _key->pos, SEEK_SET);
+ fscanf (ini->ftmp, "%lf", value);
+ }
+ else if (_key == &ini->tmpKey)
+ return -1; // Can't read tmpKey
+ }
+
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_writeInt
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Writes data part to a key.
+ * : Headings and keys will be created as necessary
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+ long pos;
+
+ _key = __ini_write (ini);
+ if (!_key)
+ return -1;
+
+ // Write data to bottom of backup file
+ fprintf (ini->ftmp, "%d", value);
+ pos = ftell (ini->ftmp);
+ _key->length = (size_t) (pos - _key->pos);
+ fprintf (ini->ftmp, "\n");
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_writeLong
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Writes data part to a key.
+ * : Headings and keys will be created as necessary
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+ long pos;
+
+ _key = __ini_write (ini);
+ if (!_key)
+ return -1;
+
+ // Write data to bottom of backup file
+ fprintf (ini->ftmp, "%ld", value);
+ pos = ftell (ini->ftmp);
+ _key->length = (size_t) (pos - _key->pos);
+ fprintf (ini->ftmp, "\n");
+ return 0;
+}
+
+
+/********************************************************************************************************************
+ * Function : ini_writeDouble
+ * Parameters : ini - pointer to ini file database.
+ * : value - keys data
+ * Returns : -1 for Error and 0 on success
+ * Globals Used :
+ * Globals Modified :
+ * Description : Writes data part to a key.
+ * : Headings and keys will be created as necessary
+ ********************************************************************************************************************
+ * Rev | Date | By | Comment
+ * ----------------------------------------------------------------------------------------------------------------
+ ********************************************************************************************************************/
+int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value)
+{
+ ini_t *ini = (ini_t *) fd;
+ struct key_tag *_key;
+ long pos;
+
+ _key = __ini_write (ini);
+ if (!_key)
+ return -1;
+
+ // Write data to bottom of backup file
+ fprintf (ini->ftmp, "%f", value);
+ pos = ftell (ini->ftmp);
+ _key->length = (size_t) (pos - _key->pos);
+ fprintf (ini->ftmp, "\n");
+ return 0;
+}
+
+#endif // INI_ADD_EXTRAS