summaryrefslogtreecommitdiff
path: root/sid/sidplay-libs-2.1.0/libsidutils/src/ini/keys.i
diff options
context:
space:
mode:
Diffstat (limited to 'sid/sidplay-libs-2.1.0/libsidutils/src/ini/keys.i')
-rw-r--r--sid/sidplay-libs-2.1.0/libsidutils/src/ini/keys.i397
1 files changed, 397 insertions, 0 deletions
diff --git a/sid/sidplay-libs-2.1.0/libsidutils/src/ini/keys.i b/sid/sidplay-libs-2.1.0/libsidutils/src/ini/keys.i
new file mode 100644
index 00000000..5507b95d
--- /dev/null
+++ b/sid/sidplay-libs-2.1.0/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;
+}