mirror of
https://github.com/suloku/savegame-manager.git
synced 2026-04-17 18:46:43 -05:00
333 lines
12 KiB
OpenEdge ABL
333 lines
12 KiB
OpenEdge ABL
/***************************************************************************
|
|
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 "inilist.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 = NULL;
|
|
}
|
|
|
|
// 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 NULL;
|
|
// Handle an empty list
|
|
if (!ini->listLength)
|
|
return "";
|
|
}
|
|
|
|
// Check to see if we are trying to get a value beyond the end of the list
|
|
if (ini->listIndex >= ini->listLength)
|
|
return NULL;
|
|
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;
|
|
|
|
// 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;
|
|
|
|
// 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_listDelims (struct ini_t *ini, const char *delims)
|
|
{
|
|
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 = strdup (delims);
|
|
if (!ini->listDelims)
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// List will need recalculating at some point
|
|
if (ini->list)
|
|
{
|
|
free (ini->list);
|
|
ini->list = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/********************************************************************************************************************
|
|
* Function : ini_listDelims
|
|
* Parameters : fd - 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, const char *delims)
|
|
{
|
|
return __ini_listDelims ((ini_t *) fd, delims);
|
|
}
|
|
|
|
|
|
/********************************************************************************************************************
|
|
* 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;
|
|
if (!ini->listLength)
|
|
return 0;
|
|
}
|
|
|
|
// Now return length
|
|
return strlen (ini->listIndexPtr);
|
|
}
|
|
|
|
#endif // INI_ADD_LIST_SUPPORT
|