summaryrefslogtreecommitdiff
path: root/plugins/sid/sidplay-libs/libsidutils/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sid/sidplay-libs/libsidutils/src')
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.cpp360
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.h135
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5_Defs.h10
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.am8
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.in422
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/Makefile.am17
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/Makefile.in549
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/SidDatabase.cpp182
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/SidFilter.cpp220
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/SidTuneMod.cpp62
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/SidUsage.cpp377
-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
-rw-r--r--plugins/sid/sidplay-libs/libsidutils/src/smm0.h133
23 files changed, 5525 insertions, 0 deletions
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.cpp b/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.cpp
new file mode 100644
index 00000000..acb7e42f
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.cpp
@@ -0,0 +1,360 @@
+/*
+ * This code has been derived by Michael Schwendt <mschwendt@yahoo.com>
+ * from original work by L. Peter Deutsch <ghost@aladdin.com>.
+ *
+ * The original C code (md5.c, md5.h) is available here:
+ * ftp://ftp.cs.wisc.edu/ghost/packages/md5.tar.gz
+ */
+
+/*
+ * The original code is:
+
+ Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+
+#include <string.h>
+
+#include "config.h"
+#if defined(HAVE_MSWINDOWS) || defined(DLL_EXPORT)
+// Support for DLLs
+# define MD5_EXPORT __declspec(dllexport)
+#endif
+
+#include "MD5.h"
+
+/*
+ * Compile with -DMD5_TEST to create a self-contained executable test program.
+ * The test program should print out the same values as given in section
+ * A.5 of RFC 1321, reproduced below.
+ */
+
+#ifdef MD5_TEST
+
+#include <iostream.h>
+#include <iomanip.h>
+
+main()
+{
+ static const char *const test[7] = {
+ "", /*d41d8cd98f00b204e9800998ecf8427e*/
+ "a", /*0cc175b9c0f1b6a831c399e269772661*/
+ "abc", /*900150983cd24fb0d6963f7d28e17f72*/
+ "message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
+ "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ /*d174ab98d277d9f5a5611c2c9f419d9f*/
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
+ };
+
+ for (int i = 0; i < 7; ++i)
+ {
+ MD5 myMD5;
+ myMD5.append((const md5_byte_t *)test[i], strlen(test[i]));
+ myMD5.finish();
+ cout << "MD5 (\"" << test[i] << "\") = ";
+ for (int di = 0; di < 16; ++di)
+ cout << hex << setw(2) << setfill('0') << (int)myMD5.getDigest()[di];
+ cout << endl;
+ }
+ return 0;
+}
+#endif /* MD5_TEST */
+
+#define T1 0xd76aa478
+#define T2 0xe8c7b756
+#define T3 0x242070db
+#define T4 0xc1bdceee
+#define T5 0xf57c0faf
+#define T6 0x4787c62a
+#define T7 0xa8304613
+#define T8 0xfd469501
+#define T9 0x698098d8
+#define T10 0x8b44f7af
+#define T11 0xffff5bb1
+#define T12 0x895cd7be
+#define T13 0x6b901122
+#define T14 0xfd987193
+#define T15 0xa679438e
+#define T16 0x49b40821
+#define T17 0xf61e2562
+#define T18 0xc040b340
+#define T19 0x265e5a51
+#define T20 0xe9b6c7aa
+#define T21 0xd62f105d
+#define T22 0x02441453
+#define T23 0xd8a1e681
+#define T24 0xe7d3fbc8
+#define T25 0x21e1cde6
+#define T26 0xc33707d6
+#define T27 0xf4d50d87
+#define T28 0x455a14ed
+#define T29 0xa9e3e905
+#define T30 0xfcefa3f8
+#define T31 0x676f02d9
+#define T32 0x8d2a4c8a
+#define T33 0xfffa3942
+#define T34 0x8771f681
+#define T35 0x6d9d6122
+#define T36 0xfde5380c
+#define T37 0xa4beea44
+#define T38 0x4bdecfa9
+#define T39 0xf6bb4b60
+#define T40 0xbebfbc70
+#define T41 0x289b7ec6
+#define T42 0xeaa127fa
+#define T43 0xd4ef3085
+#define T44 0x04881d05
+#define T45 0xd9d4d039
+#define T46 0xe6db99e5
+#define T47 0x1fa27cf8
+#define T48 0xc4ac5665
+#define T49 0xf4292244
+#define T50 0x432aff97
+#define T51 0xab9423a7
+#define T52 0xfc93a039
+#define T53 0x655b59c3
+#define T54 0x8f0ccc92
+#define T55 0xffeff47d
+#define T56 0x85845dd1
+#define T57 0x6fa87e4f
+#define T58 0xfe2ce6e0
+#define T59 0xa3014314
+#define T60 0x4e0811a1
+#define T61 0xf7537e82
+#define T62 0xbd3af235
+#define T63 0x2ad7d2bb
+#define T64 0xeb86d391
+
+MD5::MD5()
+{
+ reset();
+}
+
+void
+MD5::reset()
+{
+ count[0] = count[1] = 0;
+ abcd[0] = 0x67452301;
+ abcd[1] = 0xefcdab89;
+ abcd[2] = 0x98badcfe;
+ abcd[3] = 0x10325476;
+ memset(digest,0,16);
+ memset(buf,0,64);
+}
+
+void
+MD5::process(const md5_byte_t data[64])
+{
+ md5_word_t a = abcd[0], b = abcd[1], c = abcd[2], d = abcd[3];
+
+#ifdef MD5_WORDS_BIG_ENDIAN
+
+ /*
+ * On big-endian machines, we must arrange the bytes in the right
+ * order. (This also works on machines of unknown byte order.)
+ */
+ const md5_byte_t *xp = data;
+ for (int i = 0; i < 16; ++i, xp += 4)
+ {
+ tmpBuf[i] = (xp[0]&0xFF) + ((xp[1]&0xFF)<<8) +
+ ((xp[2]&0xFF)<<16) + ((xp[3]&0xFF)<<24);
+ }
+ X = tmpBuf;
+
+#else /* !MD5_IS_BIG_ENDIAN */
+
+ /*
+ * On little-endian machines, we can process properly aligned data
+ * without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3))
+ {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ }
+ else
+ {
+ /* not aligned */
+ memcpy(tmpBuf, data, 64);
+ X = tmpBuf;
+ }
+#endif /* MD5_IS_BIG_ENDIAN */
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ SET(&MD5::F, a, b, c, d, 0, 7, T1);
+ SET(&MD5::F, d, a, b, c, 1, 12, T2);
+ SET(&MD5::F, c, d, a, b, 2, 17, T3);
+ SET(&MD5::F, b, c, d, a, 3, 22, T4);
+ SET(&MD5::F, a, b, c, d, 4, 7, T5);
+ SET(&MD5::F, d, a, b, c, 5, 12, T6);
+ SET(&MD5::F, c, d, a, b, 6, 17, T7);
+ SET(&MD5::F, b, c, d, a, 7, 22, T8);
+ SET(&MD5::F, a, b, c, d, 8, 7, T9);
+ SET(&MD5::F, d, a, b, c, 9, 12, T10);
+ SET(&MD5::F, c, d, a, b, 10, 17, T11);
+ SET(&MD5::F, b, c, d, a, 11, 22, T12);
+ SET(&MD5::F, a, b, c, d, 12, 7, T13);
+ SET(&MD5::F, d, a, b, c, 13, 12, T14);
+ SET(&MD5::F, c, d, a, b, 14, 17, T15);
+ SET(&MD5::F, b, c, d, a, 15, 22, T16);
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ SET(&MD5::G, a, b, c, d, 1, 5, T17);
+ SET(&MD5::G, d, a, b, c, 6, 9, T18);
+ SET(&MD5::G, c, d, a, b, 11, 14, T19);
+ SET(&MD5::G, b, c, d, a, 0, 20, T20);
+ SET(&MD5::G, a, b, c, d, 5, 5, T21);
+ SET(&MD5::G, d, a, b, c, 10, 9, T22);
+ SET(&MD5::G, c, d, a, b, 15, 14, T23);
+ SET(&MD5::G, b, c, d, a, 4, 20, T24);
+ SET(&MD5::G, a, b, c, d, 9, 5, T25);
+ SET(&MD5::G, d, a, b, c, 14, 9, T26);
+ SET(&MD5::G, c, d, a, b, 3, 14, T27);
+ SET(&MD5::G, b, c, d, a, 8, 20, T28);
+ SET(&MD5::G, a, b, c, d, 13, 5, T29);
+ SET(&MD5::G, d, a, b, c, 2, 9, T30);
+ SET(&MD5::G, c, d, a, b, 7, 14, T31);
+ SET(&MD5::G, b, c, d, a, 12, 20, T32);
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ SET(&MD5::H, a, b, c, d, 5, 4, T33);
+ SET(&MD5::H, d, a, b, c, 8, 11, T34);
+ SET(&MD5::H, c, d, a, b, 11, 16, T35);
+ SET(&MD5::H, b, c, d, a, 14, 23, T36);
+ SET(&MD5::H, a, b, c, d, 1, 4, T37);
+ SET(&MD5::H, d, a, b, c, 4, 11, T38);
+ SET(&MD5::H, c, d, a, b, 7, 16, T39);
+ SET(&MD5::H, b, c, d, a, 10, 23, T40);
+ SET(&MD5::H, a, b, c, d, 13, 4, T41);
+ SET(&MD5::H, d, a, b, c, 0, 11, T42);
+ SET(&MD5::H, c, d, a, b, 3, 16, T43);
+ SET(&MD5::H, b, c, d, a, 6, 23, T44);
+ SET(&MD5::H, a, b, c, d, 9, 4, T45);
+ SET(&MD5::H, d, a, b, c, 12, 11, T46);
+ SET(&MD5::H, c, d, a, b, 15, 16, T47);
+ SET(&MD5::H, b, c, d, a, 2, 23, T48);
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ SET(&MD5::I, a, b, c, d, 0, 6, T49);
+ SET(&MD5::I, d, a, b, c, 7, 10, T50);
+ SET(&MD5::I, c, d, a, b, 14, 15, T51);
+ SET(&MD5::I, b, c, d, a, 5, 21, T52);
+ SET(&MD5::I, a, b, c, d, 12, 6, T53);
+ SET(&MD5::I, d, a, b, c, 3, 10, T54);
+ SET(&MD5::I, c, d, a, b, 10, 15, T55);
+ SET(&MD5::I, b, c, d, a, 1, 21, T56);
+ SET(&MD5::I, a, b, c, d, 8, 6, T57);
+ SET(&MD5::I, d, a, b, c, 15, 10, T58);
+ SET(&MD5::I, c, d, a, b, 6, 15, T59);
+ SET(&MD5::I, b, c, d, a, 13, 21, T60);
+ SET(&MD5::I, a, b, c, d, 4, 6, T61);
+ SET(&MD5::I, d, a, b, c, 11, 10, T62);
+ SET(&MD5::I, c, d, a, b, 2, 15, T63);
+ SET(&MD5::I, b, c, d, a, 9, 21, T64);
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ abcd[0] += a;
+ abcd[1] += b;
+ abcd[2] += c;
+ abcd[3] += d;
+}
+
+void
+MD5::append(const void* data, int nbytes)
+{
+ const md5_byte_t* p = (const md5_byte_t*)data;
+ int left = nbytes;
+ int offset = (count[0]>>3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes<<3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ count[1] += nbytes >> 29;
+ count[0] += nbits;
+ if (count[0] < nbits)
+ count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset)
+ {
+ int copy = (offset + nbytes > 64) ? (64 - offset) : nbytes;
+ memcpy(buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ process(buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ process(p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(buf, p, left);
+}
+
+void
+MD5::finish()
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(count[i>>2] >> ((i&3)<<3));
+ /* Pad to 56 bytes mod 64. */
+ append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ append(data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(abcd[i>>2] >> ((i&3)<<3));
+}
+
+const md5_byte_t*
+MD5::getDigest()
+{
+ return digest;
+}
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.h b/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.h
new file mode 100644
index 00000000..7ced54f7
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5.h
@@ -0,0 +1,135 @@
+/*
+ * This code has been derived by Michael Schwendt <mschwendt@yahoo.com>
+ * from original work by L. Peter Deutsch <ghost@aladdin.com>.
+ *
+ * The original C code (md5.c, md5.h) is available here:
+ * ftp://ftp.cs.wisc.edu/ghost/packages/md5.tar.gz
+ */
+
+/*
+ Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+ */
+
+#ifndef MD5_H
+#define MD5_H
+
+#include "MD5_Defs.h"
+
+typedef unsigned char md5_byte_t; // 8-bit byte
+typedef unsigned int md5_word_t; // 32-bit word
+
+class MD5
+{
+ public:
+ // Initialize the algorithm. Reset starting values.
+ MD5();
+
+ // Append a string to the message.
+ void append(const void* data, int nbytes);
+
+ // Finish the message.
+ void finish();
+
+ // Return pointer to 16-byte fingerprint.
+ const md5_byte_t* getDigest();
+
+ // Initialize the algorithm. Reset starting values.
+ void reset();
+
+ private:
+
+ /* Define the state of the MD5 Algorithm. */
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+
+ md5_byte_t digest[16];
+
+ md5_word_t tmpBuf[16];
+ const md5_word_t* X;
+
+ void
+ process(const md5_byte_t data[64]);
+
+ md5_word_t
+ ROTATE_LEFT(const md5_word_t x, const int n);
+
+ md5_word_t
+ F(const md5_word_t x, const md5_word_t y, const md5_word_t z);
+
+ md5_word_t
+ G(const md5_word_t x, const md5_word_t y, const md5_word_t z);
+
+ md5_word_t
+ H(const md5_word_t x, const md5_word_t y, const md5_word_t z);
+
+ md5_word_t
+ I(const md5_word_t x, const md5_word_t y, const md5_word_t z);
+
+ typedef md5_word_t (MD5::*md5func)(const md5_word_t x, const md5_word_t y, const md5_word_t z);
+
+ void
+ SET(md5func func, md5_word_t& a, md5_word_t& b, md5_word_t& c,
+ md5_word_t& d, const int k, const int s,
+ const md5_word_t Ti);
+};
+
+inline md5_word_t
+MD5::ROTATE_LEFT(const md5_word_t x, const int n)
+{
+ return ( (x<<n) | (x>>(32-n)) );
+}
+
+inline md5_word_t
+MD5::F(const md5_word_t x, const md5_word_t y, const md5_word_t z)
+{
+ return ( (x&y) | (~x&z) );
+}
+
+inline md5_word_t
+MD5::G(const md5_word_t x, const md5_word_t y, const md5_word_t z)
+{
+ return ( (x&z) | (y&~z) );
+}
+
+inline md5_word_t
+MD5::H(const md5_word_t x, const md5_word_t y, const md5_word_t z)
+{
+ return ( x^y^z );
+}
+
+inline md5_word_t
+MD5::I(const md5_word_t x, const md5_word_t y, const md5_word_t z)
+{
+ return ( y ^ (x|~z) );
+}
+
+inline void
+MD5::SET(md5func func, md5_word_t& a, md5_word_t& b, md5_word_t& c,
+ md5_word_t& d, const int k, const int s,
+ const md5_word_t Ti)
+{
+ md5_word_t t = a + (this->*func)(b,c,d) + X[k] + Ti;
+ a = ROTATE_LEFT(t, s) + b;
+}
+
+#endif /* MD5_H */
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5_Defs.h b/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5_Defs.h
new file mode 100644
index 00000000..77dca881
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/MD5/MD5_Defs.h
@@ -0,0 +1,10 @@
+#ifndef MD5_DEFS_H
+#define MD5_DEFS_H
+
+#include <sidplay/sidendian.h>
+
+#ifdef SID_WORDS_BIGENDIAN
+#define MD5_WORDS_BIG_ENDIAN
+#endif
+
+#endif /* MD5_DEFS_H */
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.am b/plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.am
new file mode 100644
index 00000000..010f6f79
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.am
@@ -0,0 +1,8 @@
+# The library.
+
+noinst_LTLIBRARIES = libMD5.la
+
+libMD5_la_SOURCES = MD5.cpp MD5.h MD5_Defs.h
+
+# Remove bad default includes
+DEFAULT_INCLUDES=
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.in b/plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.in
new file mode 100644
index 00000000..c72e248b
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/MD5/Makefile.in
@@ -0,0 +1,422 @@
+# 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 = libMD5.la
+
+libMD5_la_SOURCES = MD5.cpp MD5.h MD5_Defs.h
+
+# Remove bad default includes
+DEFAULT_INCLUDES =
+subdir = src/MD5
+mkinstalldirs = $(SHELL) $(top_srcdir)/unix/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/unix/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+libMD5_la_LDFLAGS =
+libMD5_la_LIBADD =
+am_libMD5_la_OBJECTS = MD5.lo
+libMD5_la_OBJECTS = $(am_libMD5_la_OBJECTS)
+depcomp = $(SHELL) $(top_srcdir)/unix/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/MD5.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 = $(libMD5_la_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libMD5_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/MD5/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
+libMD5.la: $(libMD5_la_OBJECTS) $(libMD5_la_DEPENDENCIES)
+ $(CXXLINK) $(libMD5_la_LDFLAGS) $(libMD5_la_OBJECTS) $(libMD5_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MD5.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/Makefile.am b/plugins/sid/sidplay-libs/libsidutils/src/Makefile.am
new file mode 100644
index 00000000..448412ed
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/Makefile.am
@@ -0,0 +1,17 @@
+
+SUBDIRS = MD5 ini
+
+# The library.
+
+lib_LTLIBRARIES = libsidutils.la
+
+libsidutils_la_SOURCES = SidDatabase.cpp SidFilter.cpp SidTuneMod.cpp SidUsage.cpp smm0.h
+
+libsidutils_la_LIBADD = ./MD5/libMD5.la ./ini/libini.la \
+$(LIBSIDPLAY2_LDFLAGS)
+
+# We substitute the libtool-specific library version in configure.in.
+libsidutils_la_LDFLAGS = -version-info $(LIBVERSION)
+
+# Remove bad default includes
+DEFAULT_INCLUDES=
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/Makefile.in b/plugins/sid/sidplay-libs/libsidutils/src/Makefile.in
new file mode 100644
index 00000000..5e35304b
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/Makefile.in
@@ -0,0 +1,549 @@
+# 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@
+
+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@
+
+SUBDIRS = MD5 ini
+
+
+# The library.
+lib_LTLIBRARIES = libsidutils.la
+
+libsidutils_la_SOURCES = SidDatabase.cpp SidFilter.cpp SidTuneMod.cpp SidUsage.cpp smm0.h
+
+libsidutils_la_LIBADD = ./MD5/libMD5.la ./ini/libini.la \
+$(LIBSIDPLAY2_LDFLAGS)
+
+
+# We substitute the libtool-specific library version in configure.in.
+libsidutils_la_LDFLAGS = -version-info $(LIBVERSION)
+
+# Remove bad default includes
+DEFAULT_INCLUDES =
+subdir = src
+mkinstalldirs = $(SHELL) $(top_srcdir)/unix/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/unix/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libsidutils_la_DEPENDENCIES = ./MD5/libMD5.la ./ini/libini.la
+am_libsidutils_la_OBJECTS = SidDatabase.lo SidFilter.lo SidTuneMod.lo \
+ SidUsage.lo
+libsidutils_la_OBJECTS = $(am_libsidutils_la_OBJECTS)
+depcomp = $(SHELL) $(top_srcdir)/unix/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/SidDatabase.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/SidFilter.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/SidTuneMod.Plo ./$(DEPDIR)/SidUsage.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 = $(libsidutils_la_SOURCES)
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+ ps-recursive install-info-recursive uninstall-info-recursive \
+ all-recursive install-data-recursive install-exec-recursive \
+ installdirs-recursive install-recursive uninstall-recursive \
+ check-recursive installcheck-recursive
+DIST_COMMON = Makefile.am Makefile.in
+DIST_SUBDIRS = $(SUBDIRS)
+SOURCES = $(libsidutils_la_SOURCES)
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+libLTLIBRARIES_INSTALL = $(INSTALL)
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_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
+libsidutils.la: $(libsidutils_la_OBJECTS) $(libsidutils_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(libdir) $(libsidutils_la_LDFLAGS) $(libsidutils_la_OBJECTS) $(libsidutils_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SidDatabase.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SidFilter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SidTuneMod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SidUsage.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:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ 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: ctags-recursive $(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
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" \
+ distdir=../$(distdir)/$$subdir \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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-recursive
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+ clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-recursive ctags ctags-recursive distclean \
+ distclean-compile distclean-depend distclean-generic \
+ distclean-libtool distclean-recursive distclean-tags distdir \
+ dvi dvi-am dvi-recursive info info-am info-recursive install \
+ install-am install-data install-data-am install-data-recursive \
+ install-exec install-exec-am install-exec-recursive \
+ install-info install-info-am install-info-recursive \
+ install-libLTLIBRARIES install-man install-recursive \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am installdirs-recursive maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \
+ ps-recursive tags tags-recursive uninstall uninstall-am \
+ uninstall-info-am uninstall-info-recursive \
+ uninstall-libLTLIBRARIES uninstall-recursive
+
+# 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/SidDatabase.cpp b/plugins/sid/sidplay-libs/libsidutils/src/SidDatabase.cpp
new file mode 100644
index 00000000..20dd20b3
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/SidDatabase.cpp
@@ -0,0 +1,182 @@
+/***************************************************************************
+ dbget.cpp - Get time from database
+ -------------------
+ begin : Fri Jun 2 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 <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "SidDatabase.h"
+#include "MD5/MD5.h"
+
+const char *SidDatabase::ERR_DATABASE_CORRUPT = "SID DATABASE ERROR: Database seems to be corrupt.";
+const char *SidDatabase::ERR_NO_DATABASE_LOADED = "SID DATABASE ERROR: Songlength database not loaded.";
+const char *SidDatabase::ERR_NO_SELECTED_SONG = "SID DATABASE ERROR: No song selected for retrieving song length.";
+const char *SidDatabase::ERR_MEM_ALLOC = "SID DATABASE ERROR: Memory Allocation Failure.";
+const char *SidDatabase::ERR_UNABLE_TO_LOAD_DATABASE = "SID DATABASE ERROR: Unable to load the songlegnth database.";
+
+
+SidDatabase::~SidDatabase ()
+{
+ close ();
+}
+
+
+int_least32_t SidDatabase::parseTimeStamp(const char* arg)
+{
+ /* Read in m:s format at most.
+ * Could use a system function if available.
+ */
+ int_least32_t seconds = 0;
+ int passes = 2; // minutes, seconds
+ bool gotDigits = false;
+ while ( passes-- )
+ {
+ if ( isdigit(*arg) )
+ {
+ int t = atoi(arg);
+ seconds += t;
+ gotDigits = true;
+ }
+ while ( *arg && isdigit(*arg) )
+ {
+ ++arg;
+ }
+ if ( *arg && *arg==':' )
+ {
+ seconds *= 60;
+ ++arg;
+ }
+ }
+
+ // Handle -:-- time stamps and old 0:00 entries which
+ // need to be rounded up by one second.
+ if ( !gotDigits )
+ seconds = 0;
+ else if ( seconds==0 )
+ ++seconds;
+
+ return seconds;
+}
+
+
+uint_least8_t SidDatabase::timesFound (char *str)
+{
+ /* Try and determine the number of times read back.
+ * Used to check validility of times in database.
+ */
+ uint_least8_t count = 0;
+ while (*str)
+ {
+ if (*str++ == ':')
+ count++;
+ }
+ return count;
+}
+
+
+int SidDatabase::open (const char *filename)
+{
+ close ();
+ // @FIXME@: Libini should be changed
+ database = ini_open ((char *) filename, "r", ";");
+ if (!database)
+ {
+ errorString = ERR_UNABLE_TO_LOAD_DATABASE;
+ return -1;
+ }
+
+ return 0;
+}
+
+void SidDatabase::close ()
+{
+ if (database)
+ ini_close (database);
+}
+
+int_least32_t SidDatabase::length (SidTuneMod &tune)
+{
+ SidTuneInfo tuneInfo;
+ int_least32_t time = 0;
+ char timeStamp[10];
+ MD5 myMD5;
+ char digest[33];
+ uint_least16_t selectedSong = 0;
+
+ if (!database)
+ {
+ errorString = ERR_NO_DATABASE_LOADED;
+ return -1;
+ }
+
+ tune.getInfo(tuneInfo);
+ selectedSong = tuneInfo.currentSong;
+ if (!selectedSong)
+ {
+ errorString = ERR_NO_SELECTED_SONG;
+ return -1;
+ }
+
+ // Restart fingerprint
+ myMD5.reset();
+ tune.createMD5(myMD5);
+ myMD5.finish();
+
+ // Construct fingerprint.
+ digest[0] = '\0';
+ for (int di = 0; di < 16; ++di)
+ sprintf (digest, "%s%02x", digest, (int) myMD5.getDigest()[di]);
+
+
+ // Now set up array access
+ if (ini_listDelims (database, " ") == -1)
+ {
+ errorString = ERR_MEM_ALLOC;
+ return -1;
+ }
+
+ // Read Time (and check times before hand)
+ (void) ini_locateHeading (database, "Database");
+ (void) ini_locateKey (database, digest);
+ // If length return is -1 then no entry found in database
+ if (ini_dataLength (database) != -1)
+ {
+ selectedSong = 0;
+ while (selectedSong < tuneInfo.currentSong)
+ {
+ selectedSong++;
+ if (ini_readString (database, timeStamp, sizeof (timeStamp)) == -1)
+ { // No time found
+ errorString = ERR_DATABASE_CORRUPT;
+ return -1;
+ }
+
+ // Validate Time
+ if (timesFound (timeStamp) != 1)
+ {
+ errorString = ERR_DATABASE_CORRUPT;
+ return -1;
+ }
+ }
+
+ // Parse timestamp
+ time = parseTimeStamp (timeStamp);
+ }
+
+ return time;
+}
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/SidFilter.cpp b/plugins/sid/sidplay-libs/libsidutils/src/SidFilter.cpp
new file mode 100644
index 00000000..1d9b35ea
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/SidFilter.cpp
@@ -0,0 +1,220 @@
+/***************************************************************************
+ SidFilter.cpp - read filter
+ -------------------
+ begin : Sun Mar 11 2001
+ copyright : (C) 2001 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 <new>
+#include <math.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "SidFilter.h"
+
+
+SidFilter::SidFilter ()
+:m_status(false)
+{
+ m_errorString = "SID Filter: No filter loaded";
+}
+
+SidFilter::~SidFilter ()
+{
+ clear ();
+}
+
+void SidFilter::clear ()
+{
+ m_filter.points = 0;
+ m_status = false;
+ m_errorString = "SID Filter: No filter loaded";
+}
+
+void SidFilter::read (char *filename)
+{
+ ini_fd_t ini = ini_open (filename, "r", ";");
+
+ // Illegal ini fd
+ if (!ini)
+ {
+ m_status = false;
+ m_errorString = "SID Filter: Unable to open filter file";
+ return;
+ }
+
+ read (ini, "Filter");
+ ini_close (ini);
+}
+
+void SidFilter::read (ini_fd_t ini, char *heading)
+{
+ int type = 1;
+
+ clear ();
+ m_status = true;
+
+ if (ini_locateHeading (ini, heading) < 0)
+ {
+ m_status = false;
+ m_errorString = "SID Filter: Unable to locate filter section in input file";
+ return;
+ }
+
+ (void) ini_locateKey (ini, "type");
+ (void) ini_readInt (ini, &type);
+ switch (type)
+ {
+ case 1:
+ readType1 (ini);
+ break;
+
+ case 2:
+ readType2 (ini);
+ break;
+
+ default:
+ m_status = false;
+ m_errorString = "SID Filter: Invalid filter type";
+ break;
+ }
+}
+
+void SidFilter::readType1 (ini_fd_t ini)
+{
+ int points;
+
+ // Does Section exist in ini file
+ if (ini_locateKey (ini, "points") < 0)
+ goto SidFilter_readType1_errorDefinition;
+ if (ini_readInt (ini, &points) < 0)
+ goto SidFilter_readType1_errorDefinition;
+
+ // Make sure there are enough filter points
+ if ((points < 2) || (points > 0x800))
+ goto SidFilter_readType1_errorDefinition;
+ m_filter.points = (uint_least16_t) points;
+
+ // Set the ini reader up for array access
+ if (ini_listDelims (ini, ",") < 0)
+ goto SidFilter_readType1_errorMemory;
+
+ {
+ char key[12];
+ int reg = -1, fc = -1;
+ for (int i = 0; i < m_filter.points; i++)
+ { // First lets read the SID cutoff register value
+ sprintf (key, "point%d", i + 1);
+ ini_locateKey (ini, key);
+ if (ini_readInt (ini, &reg) < 0)
+ goto SidFilter_readType1_errorDefinition;
+ if (ini_readInt (ini, &fc) < 0)
+ goto SidFilter_readType1_errorDefinition;
+
+ // Got valid reg/fc
+ m_filter.cutoff[i][0] = (uint) reg;
+ m_filter.cutoff[i][1] = (uint) fc;
+ }
+ }
+return;
+
+SidFilter_readType1_errorDefinition:
+ clear ();
+ m_errorString = "SID Filter: Invalid Type 1 filter definition";
+ m_status = false;
+return;
+
+SidFilter_readType1_errorMemory:
+ m_errorString = "SID Filter: Out of memory";
+ m_status = false;
+}
+
+void SidFilter::readType2 (ini_fd_t ini)
+{
+ double fs, fm, ft;
+
+ // Read filter parameters
+ ini_locateKey (ini, "fs");
+ if (ini_readDouble (ini, &fs) < 0)
+ goto SidFilter_readType2_errorDefinition;
+ ini_locateKey (ini, "fm");
+ if (ini_readDouble (ini, &fm) < 0)
+ goto SidFilter_readType2_errorDefinition;
+ ini_locateKey (ini, "ft");
+ if (ini_readDouble (ini, &ft) < 0)
+ goto SidFilter_readType2_errorDefinition;
+
+ // Calculate the filter
+ calcType2 (fs, fm, ft);
+return;
+
+SidFilter_readType2_errorDefinition:
+ clear ();
+ m_errorString = "SID Filter: Invalid Type 2 filter definition";
+ m_status = false;
+}
+
+// Calculate a Type 2 filter (Sidplay 1 Compatible)
+void SidFilter::calcType2 (double fs, double fm, double ft)
+{
+ double fcMax = 1.0;
+ double fcMin = 0.01;
+ double fc;
+
+ // Definition from reSID
+ m_filter.points = 0x100;
+
+ // Create filter
+ for (uint i = 0; i < 0x100; i++)
+ {
+ uint rk = i << 3;
+ m_filter.cutoff[i][0] = rk;
+ fc = exp ((double) rk / 0x800 * log (fs)) / fm + ft;
+ if (fc < fcMin)
+ fc = fcMin;
+ if (fc > fcMax)
+ fc = fcMax;
+ m_filter.cutoff[i][1] = (uint) (fc * 4100);
+ }
+}
+
+// Get filter
+const sid_filter_t *SidFilter::provide () const
+{
+ if (!m_status)
+ return NULL;
+ return &m_filter;
+}
+
+// Copy filter from another SidFilter class
+const SidFilter &SidFilter::operator= (const SidFilter &filter)
+{
+ (void) operator= (filter.provide ());
+ return filter;
+}
+
+// Copy sidplay2 sid_filter_t object
+const sid_filter_t &SidFilter::operator= (const sid_filter_t &filter)
+{
+ m_filter = filter;
+ m_status = true;
+ return filter;
+}
+
+const sid_filter_t *SidFilter::operator= (const sid_filter_t *filter)
+{
+ m_status = false;
+ if (filter)
+ (void) operator= (*filter);
+ return filter;
+}
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/SidTuneMod.cpp b/plugins/sid/sidplay-libs/libsidutils/src/SidTuneMod.cpp
new file mode 100644
index 00000000..6af33350
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/SidTuneMod.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <sidplay/sidendian.h>
+#include "config.h"
+#include "SidTuneMod.h"
+#include "MD5/MD5.h"
+
+void SidTuneMod::createMD5(MD5& myMD5)
+{
+ if (status)
+ { // Include C64 data.
+ md5_byte_t tmp[2];
+ myMD5.append (cache.get()+fileOffset,info.c64dataLen);
+ // Include INIT and PLAY address.
+ endian_little16 (tmp,info.initAddr);
+ myMD5.append (tmp,sizeof(tmp));
+ endian_little16 (tmp,info.playAddr);
+ myMD5.append (tmp,sizeof(tmp));
+ // Include number of songs.
+ endian_little16 (tmp,info.songs);
+ myMD5.append (tmp,sizeof(tmp));
+ { // Include song speed for each song.
+ uint_least16_t currentSong = info.currentSong;
+ for (uint_least16_t s = 1; s <= info.songs; s++)
+ {
+ selectSong (s);
+ myMD5.append (&info.songSpeed,sizeof(info.songSpeed));
+ }
+ // Restore old song
+ selectSong (currentSong);
+ }
+ // Deal with PSID v2NG clock speed flags: Let only NTSC
+ // clock speed change the MD5 fingerprint. That way the
+ // fingerprint of a PAL-speed sidtune in PSID v1, v2, and
+ // PSID v2NG format is the same.
+ if (info.clockSpeed == SIDTUNE_CLOCK_NTSC)
+ myMD5.append (&info.clockSpeed,sizeof(info.clockSpeed));
+ // NB! If the fingerprint is used as an index into a
+ // song-lengths database or cache, modify above code to
+ // allow for PSID v2NG files which have clock speed set to
+ // SIDTUNE_CLOCK_ANY. If the SID player program fully
+ // supports the SIDTUNE_CLOCK_ANY setting, a sidtune could
+ // either create two different fingerprints depending on
+ // the clock speed chosen by the player, or there could be
+ // two different values stored in the database/cache.
+ }
+}
+
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/SidUsage.cpp b/plugins/sid/sidplay-libs/libsidutils/src/SidUsage.cpp
new file mode 100644
index 00000000..abeb085d
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/SidUsage.cpp
@@ -0,0 +1,377 @@
+/***************************************************************************
+ SidUsage.cpp - sidusage file support
+ -------------------
+ begin : Tues Nov 19 2002
+ copyright : (C) 2002 by Simon White
+ email : sidplay2@yahoo.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 <sidplay/sidendian.h>
+#include "SidUsage.h"
+#include "smm0.h"
+
+static const char *txt_na = "SID Usage: N/A";
+static const char *txt_file = "SID Usage: Unable to open file";
+static const char *txt_corrupt = "SID Usage: File corrupt";
+static const char *txt_invalid = "SID Usage: Invalid IFF file";
+static const char *txt_missing = "SID Usage: Mandatory chunks missing";
+static const char *txt_supported = "SID Usage: IFF file not supported";
+static const char *txt_reading = "SID Usage: Error reading file";
+static const char *txt_writing = "SID Usage: Error writing file";
+
+static bool readSMM0 (FILE *file, const char **errorString,
+ sid_usage_t &usage,
+ const IffHeader &header);
+static bool writeSMM0 (FILE *file, const char **errorString,
+ const sid_usage_t &usage,
+ const SidTuneInfo &tuneInfo);
+static uint_least32_t readChunk (FILE *file, Chunk &chunk);
+static bool writeChunk (FILE *file, const Chunk &chunk,
+ uint_least32_t type,
+ uint_least32_t length = 0);
+static uint_least32_t skipChunk (FILE *file);
+
+
+SidUsage::SidUsage ()
+:m_status(false)
+{
+ m_errorString = txt_na;
+}
+
+void SidUsage::read (const char *filename, sid_usage_t &usage)
+{
+ FILE *file;
+ uint8_t chunk[4] = {0};
+ IffHeader header;
+ uint_least32_t length;
+
+ m_status = false;
+ file = fopen (filename, "wb");
+ if (file == NULL)
+ {
+ m_errorString = txt_file;
+ goto SidTune_read_error;
+ }
+
+ // Read header chunk
+ fread (&chunk, sizeof (chunk), 1, file);
+ if (endian_big32 (chunk) != FORM_ID)
+ {
+ m_errorString = txt_invalid;
+ goto SidTune_read_error;
+ }
+ length = readChunk (file, header);
+ if (!length)
+ {
+ m_errorString = txt_invalid;
+ goto SidTune_read_error;
+ }
+
+ // Determine SMM version
+ switch (endian_big32 (header.type))
+ {
+ case SMM0_ID:
+ m_status = readSMM0 (file, &m_errorString, usage, header);
+ break;
+
+ case SMM1_ID:
+ case SMM2_ID:
+ case SMM3_ID:
+ case SMM4_ID:
+ case SMM5_ID:
+ case SMM6_ID:
+ case SMM7_ID:
+ case SMM8_ID:
+ case SMM9_ID:
+ m_errorString = txt_invalid;
+ goto SidTune_read_error;
+
+ default:
+ m_errorString = txt_supported;
+ goto SidTune_read_error;
+ }
+ fclose (file);
+ return;
+
+SidTune_read_error:
+ if (file != NULL)
+ fclose (file);
+}
+
+
+void SidUsage::write (const char *filename, const sid_usage_t &usage,
+ SidTuneInfo &tuneInfo)
+{
+ FILE *file;
+
+ m_status = false;
+ file = fopen (filename, "wb");
+ if (file == NULL)
+ {
+ m_errorString = txt_file;
+ return;
+ }
+
+ m_status = writeSMM0 (file, &m_errorString, usage, tuneInfo);
+ fclose (file);
+}
+
+
+bool readSMM0 (FILE *file, const char **errorString,
+ sid_usage_t &usage, const IffHeader &header)
+{
+ Smm_v0 smm;
+ smm.header = header;
+
+ { // Read file
+ long pos = ftell (file);
+ bool error = true;
+
+ for(;;)
+ {
+ size_t ret;
+ uint_least32_t length = 0;
+ uint8_t chunk[4];
+ // Read a chunk header
+ ret = fread (&chunk, sizeof (chunk), 1, file);
+ // If no chunk header assume end of file
+ if (ret != 1)
+ break;
+
+ // Check for a chunk we are interested in
+ switch (endian_big32 (chunk))
+ {
+ case INF0_ID:
+ length = readChunk (file, smm.info);
+ break;
+
+ case ERR0_ID:
+ length = readChunk (file, smm.error);
+ break;
+
+ case MD5_ID:
+ length = readChunk (file, smm.md5);
+ break;
+
+ case TIME_ID:
+ length = readChunk (file, smm.time);
+ break;
+
+ case BODY_ID:
+ length = readChunk (file, smm.body);
+ break;
+
+ default:
+ length = skipChunk (file);
+ }
+
+ if (!length)
+ {
+ error = true;
+ break;
+ }
+
+ // Move past the chunk
+ pos += (long) length + (sizeof(uint8_t) * 8);
+ fseek (file, pos, SEEK_SET);
+ if (ftell (file) != pos)
+ {
+ error = true;
+ break;
+ }
+ error = false;
+ }
+
+ // Check for file reader error
+ if (error)
+ {
+ *errorString = txt_reading;
+ return false;
+ }
+ }
+
+ // Test that all required checks were found
+ if ((smm.info.length == 0) || (smm.error.length == 0) ||
+ (smm.body.length == 0))
+ {
+ *errorString = txt_missing;
+ return false;
+ }
+
+ // Extract usage information
+ {for (int i = 0; i < 0x100; i++)
+ {
+ int addr = smm.body.usage[i].page << 8;
+ if ((addr == 0) && (i != 0))
+ break;
+ memcpy (&usage.memory[addr], smm.body.usage[i].flags, sizeof (uint8_t) * 0x100);
+ }}
+
+ { // File in the load range
+ uint_least16_t load, last;
+ int length;
+ load = endian_big16 (smm.info.startAddr);
+ last = endian_big16 (smm.info.stopAddr);
+ length = (int) (last - load) + 1;
+
+ if (length < 0)
+ {
+ *errorString = txt_corrupt;
+ return false;
+ }
+
+ {for (int i = 0; i < length; i++)
+ usage.memory[load + i] |= SID_LOAD_IMAGE;
+ }
+ }
+ usage.flags = endian_big16(smm.error.flags);
+ return true;
+}
+
+
+bool writeSMM0 (FILE *file, const char **errorString,
+ const sid_usage_t &usage, const SidTuneInfo &tuneInfo)
+{
+ struct Smm_v0 smm0;
+ uint_least32_t headings = 3; /* Mandatory */
+
+ endian_big32 (smm0.header.type, SMM0_ID);
+ endian_big16 (smm0.error.flags, (uint_least16_t) usage.flags);
+
+ // Optional
+ if (usage.length == 0)
+ smm0.time.length = 0;
+ else
+ {
+ endian_big16 (smm0.time.stamp, (uint_least16_t) usage.length);
+ headings++;
+ }
+
+ {
+ uint_least16_t load = tuneInfo.loadAddr;
+ uint_least16_t last = load + (tuneInfo.c64dataLen - 1);
+ endian_big16 (smm0.info.startAddr, load);
+ endian_big16 (smm0.info.stopAddr, last);
+ }
+
+ // Optional
+ if ( usage.md5[0] == '\0' )
+ smm0.md5.length = 0;
+ else
+ {
+ {for (int i = 0; i < 32; i++)
+ smm0.md5.key[i] = usage.md5[i];
+ }
+ headings++;
+ }
+
+ {
+ uint8_t i = 0;
+ smm0.body.length = 0;
+ {for (int page = 0; page < 0x100; page++)
+ {
+ char used = 0;
+ for (int j = 0; j < 0x100; j++)
+ used |= (usage.memory[(page << 8) | j] & 0x7f);
+
+ if (used)
+ {
+ smm0.body.length += 0x101;
+ memcpy (smm0.body.usage[i].flags, &usage.memory[page << 8],
+ 0x100);
+ smm0.body.usage[i].page = (uint8_t) page;
+ i++;
+ }
+ }}
+ }
+
+ uint_least32_t filelength = smm0.header.length + smm0.error.length
+ + smm0.info.length + smm0.md5.length
+ + smm0.time.length + smm0.body.length
+ + (sizeof (uint8_t) * 8 * headings);
+
+ if ( writeChunk (file, smm0.header, FORM_ID, filelength) == false )
+ goto writeSMM0_error;
+ if ( writeChunk (file, smm0.error, ERR0_ID) == false )
+ goto writeSMM0_error;
+ if ( writeChunk (file, smm0.info, INF0_ID) == false )
+ goto writeSMM0_error;
+ if ( writeChunk (file, smm0.md5, MD5_ID) == false )
+ goto writeSMM0_error;
+ if ( writeChunk (file, smm0.time, TIME_ID) == false )
+ goto writeSMM0_error;
+ if ( writeChunk (file, smm0.body, BODY_ID) == false )
+ goto writeSMM0_error;
+ return true;
+
+writeSMM0_error:
+ *errorString = txt_writing;
+ return false;
+}
+
+
+uint_least32_t readChunk (FILE *file, Chunk &chunk)
+{
+ uint8_t tmp[4];
+ size_t ret;
+ uint_least32_t l;
+
+ ret = fread (tmp, sizeof(tmp), 1, file);
+ if ( ret != 1 )
+ return 0;
+
+ l = endian_big32 (tmp);
+ if (l < chunk.length)
+ chunk.length = l;
+ ret = fread ((char *) (&chunk+1), chunk.length, 1, file);
+ if ( ret != 1 )
+ return 0;
+ return l;
+}
+
+
+bool writeChunk (FILE *file, const Chunk &chunk, uint_least32_t type,
+ uint_least32_t length)
+{
+ uint8_t tmp[4];
+ size_t ret;
+
+ if (chunk.length)
+ {
+ endian_big32 (tmp, type);
+ ret = fwrite (tmp, sizeof(tmp), 1, file);
+ if ( ret != 1 )
+ return false;
+ if (length == 0)
+ length = chunk.length;
+ endian_big32 (tmp, length);
+ ret = fwrite (tmp, sizeof(tmp), 1, file);
+ if ( ret != 1 )
+ return false;
+ ret = fwrite ((const char *) (&chunk+1), chunk.length, 1, file);
+ if ( ret != 1 )
+ return false;
+ }
+ return true;
+}
+
+
+uint_least32_t skipChunk (FILE *file)
+{
+ uint8_t tmp[4];
+ uint_least32_t ret;
+ ret = fread (tmp, sizeof(tmp), 1, file);
+ if ( ret != 1 )
+ return 0;
+ return endian_big32 (tmp);
+}
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
diff --git a/plugins/sid/sidplay-libs/libsidutils/src/smm0.h b/plugins/sid/sidplay-libs/libsidutils/src/smm0.h
new file mode 100644
index 00000000..fca61092
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidutils/src/smm0.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ smm0.h - sidusage file support
+ -------------------
+ begin : Tues Nov 19 2002
+ copyright : (C) 2002 by Simon White
+ email : sidplay2@yahoo.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 _smm0_h_
+#define _smm0_h_
+
+#include <string.h>
+
+// IFF IDs
+#define BUILD_ID(a, b, c, d) ((uint) a << 24 | \
+ (uint) b << 16 | \
+ (uint) c << 8 | \
+ (uint) d)
+
+#define FORM_ID BUILD_ID('F','O','R','M')
+#define SMM0_ID BUILD_ID('S','M','M','0')
+#define INF0_ID BUILD_ID('I','N','F','0')
+#define ERR0_ID BUILD_ID('E','R','R','0')
+#define TIME_ID BUILD_ID('T','I','M','E')
+#define MD5_ID BUILD_ID('M','D','5',' ')
+#define BODY_ID BUILD_ID('B','O','D','Y')
+
+// Future Versions
+#define SMM1_ID BUILD_ID('S','M','M','1')
+#define SMM2_ID BUILD_ID('S','M','M','2')
+#define SMM3_ID BUILD_ID('S','M','M','3')
+#define SMM4_ID BUILD_ID('S','M','M','4')
+#define SMM5_ID BUILD_ID('S','M','M','5')
+#define SMM6_ID BUILD_ID('S','M','M','6')
+#define SMM7_ID BUILD_ID('S','M','M','7')
+#define SMM8_ID BUILD_ID('S','M','M','8')
+#define SMM9_ID BUILD_ID('S','M','M','9')
+
+struct Chunk
+{
+ uint_least32_t length;
+};
+
+struct IffHeader: public Chunk
+{
+ uint8_t type[4]; // Should be SMM0
+
+ IffHeader()
+ {
+ memset (this, 0, sizeof (IffHeader));
+ length = sizeof(IffHeader) - sizeof(Chunk);
+ }
+};
+
+struct Inf_v0: public Chunk
+{
+ uint8_t startAddr[2];
+ uint8_t stopAddr[2];
+
+ Inf_v0()
+ {
+ memset (this, 0, sizeof (Inf_v0));
+ length = sizeof(Inf_v0) - sizeof(Chunk);
+ }
+};
+
+struct Err_v0: public Chunk
+{
+ uint8_t flags[2];
+
+ Err_v0()
+ {
+ memset (this, 0, sizeof (Err_v0));
+ length = sizeof(Err_v0) - sizeof(Chunk);
+ }
+};
+
+struct Md5: public Chunk
+{
+ uint8_t key[32];
+
+ Md5()
+ {
+ memset (this, 0, sizeof (Md5));
+ length = sizeof(Md5) - sizeof(Chunk);
+ }
+};
+
+struct Time: public Chunk
+{
+ uint8_t stamp[2];
+
+ Time()
+ {
+ memset (this, 0, sizeof (Time));
+ length = sizeof(Time) - sizeof(Chunk);
+ }
+};
+
+struct Body: public Chunk
+{
+ struct usage
+ {
+ uint8_t page;
+ uint8_t flags[256];
+ } usage[256];
+
+ Body()
+ { // Don't set length as is variable
+ memset (this, 0, sizeof (Body));
+ }
+};
+
+struct Smm_v0
+{
+ IffHeader header;
+ Inf_v0 info;
+ Err_v0 error;
+ Md5 md5;
+ Time time;
+ Body body;
+};
+
+#endif // _smm0_h_