This repository has been archived on 2024-03-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
gtkmeat/rcfuncs.c
2024-03-20 09:25:47 -05:00

336 lines
6.2 KiB
C

/*
* rcfuncs - routines to parse generic RC files
* tengel@sonic.net
*
* This is taken from the LiteStep Shell Source code
* (http://www.litestep.net) and modified a bunch to meet
* our RC needs along with using gdk. It is released under
* the GPL and any litestep licensing restrictions.
*/
#include <gdk/gdk.h>
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <string.h>
#include "rcfuncs.h"
#ifndef MAX_BUFF
#define MAX_BUFF 1024
#endif
static gchar **RCBuffer = NULL;
static gint RCLen = 0;
FILE* RCOpen(const gchar *szFile)
{
FILE *f = NULL;
if (!szFile)
return f;
/* make sure to open in text mode; in MS ANSI C,
* this will map our \n and \r\n for us. Valid
* in unix? */
f = fopen(szFile, "rt");
if (f)
fseek(f, 0, SEEK_SET);
return f;
}
BOOL RCClose(FILE *f)
{
if (f)
fclose (f);
return TRUE;
}
/* Parses szString, splitting it up into tokens. Pays
* attention to single and double quotes. */
gint RCTokenize(const gchar *szString, gchar **lpszBuffers, DWORD dwNumBuffers, gchar *szExtraParameters)
{
gint index = 0;
gchar quoteChar = 0;
gchar buffer[MAX_BUFF];
gchar output[MAX_BUFF];
gchar *pOutput = NULL;
DWORD dwBufferCount = 0;
strcpy(buffer, szString);
pOutput = output;
while (buffer[index] && dwBufferCount < dwNumBuffers) {
BOOL skipWhitespace = FALSE;
switch (buffer[index]) {
case '"':
case '\'':
{
if (!quoteChar) {
quoteChar = buffer[index];
break;
} else {
if (quoteChar == buffer[index]) {
quoteChar = 0;
strcpy (*lpszBuffers, output);
lpszBuffers++;
dwBufferCount++;
if (dwBufferCount < dwNumBuffers)
(*lpszBuffers)[0] = '\0';
pOutput = output;
*pOutput = '\0';
skipWhitespace = TRUE;
break;
} else {
*pOutput++ = buffer[index];
*pOutput = '\0';
break;
}
}
}
case ' ':
case '\t':
{
if (!quoteChar) {
if (strlen (output)) {
strcpy (*lpszBuffers, output);
lpszBuffers++;
dwBufferCount++;
if (dwBufferCount < dwNumBuffers)
(*lpszBuffers)[0] = '\0';
pOutput = output;
*pOutput = '\0';
skipWhitespace = TRUE;
}
} else {
*pOutput++ = buffer[index];
*pOutput = '\0';
}
break;
}
default:
{
*pOutput++ = buffer[index];
*pOutput = '\0';
break;
}
}
index++;
if (skipWhitespace) {
while(isspace(buffer[index])) {
index++;
}
}
}
if (strlen (output)) {
if (dwBufferCount < dwNumBuffers) {
dwBufferCount++;
strcat(*lpszBuffers, output);
}
}
if (szExtraParameters && dwBufferCount == dwNumBuffers)
strcpy (szExtraParameters, buffer + index);
return dwBufferCount;
}
gchar* RCFindLine(const gchar *lpKeyName)
{
gint i;
gint l = strlen(lpKeyName);
for (i = 0; i < RCLen; i++) {
#ifdef WIN32
if (!strnicmp(RCBuffer[i], lpKeyName, l))
#else
if (!strncasecmp(RCBuffer[i], lpKeyName, l))
#endif
return RCBuffer[i];
}
return (gchar *) 0;
}
gint RCGetInt(const gchar *lpKeyName, gint nDefault)
{
gint val = nDefault;
gchar *line = NULL;
gchar token1[MAX_BUFF], token2[MAX_BUFF];
gchar *tokens[2];
tokens[0] = token1;
tokens[1] = token2;
line = RCFindLine(lpKeyName);
if (line) {
gint count = 0;
token1[0] = token2[0] = '\0';
count = RCTokenize(line, tokens, 2, NULL);
if (count < 2)
return val;
val = atoi(token2);
}
return val;
}
BOOL RCGetBool(const gchar *lpKeyName, BOOL ifFound)
{
gchar token1[MAX_BUFF], token2[MAX_BUFF];
gchar *tokens[2];
gchar *line = NULL;
tokens[0] = token1;
tokens[1] = token2;
line = RCFindLine(lpKeyName);
if (line) {
gint count = 0;
token1[0] = token2[0] = '\0';
count = RCTokenize (line, tokens, 2, NULL);
if (count < 2)
return ifFound;
#ifdef WIN32
if (strnicmp (token2, "OFF", 3) == 0)
#else
if (strncasecmp (token2, "OFF", 3) == 0)
#endif
return FALSE;
else
return TRUE; /* ON */
}
return (ifFound);
}
BOOL RCGetString(const gchar *lpKeyName, gchar *value, const gchar *defStr, gint maxLen)
{
gchar token1[MAX_BUFF], token2[MAX_BUFF];
gchar *tokens[2];
gchar *line = NULL;
tokens[0] = token1;
tokens[1] = token2;
strncpy(value, defStr, maxLen);
line = RCFindLine(lpKeyName);
if (line) {
gint count = 0;
token1[0] = token2[0] = '\0';
count = RCTokenize (line, tokens, 2, NULL);
if (count < 2)
return FALSE;
RCVarExpansion(value, token2);
return TRUE;
}
return FALSE;
}
void RCVarExpansion(gchar *buffer, const gchar *value)
{
gint i=0, j=0;
gchar *startDollar, *endDollar;
gchar *string1;
gchar buf[255];
gchar buf2[255];
strcpy(buffer, value);
if ((startDollar = strchr(value, '$'))) {
if ((endDollar = strchr(&startDollar[1], '$'))) {
i = strlen(startDollar) - strlen(endDollar) - 1;
j = strlen(value) - strlen(startDollar);
string1 = startDollar;
string1++;
strncpy(buf, string1, i);
buf[i]='\0';
RCGetString(buf, buf2, buf, 255);
if (value != startDollar) {
strncpy(buffer, value, j);
buffer[j] = '\0';
} else {
strcpy(buffer, "");
}
strcat(buffer, buf2);
strcat(buffer, ++endDollar);
}
}
}
BOOL RCReadNextLine (FILE *f, gchar *szBuffer, DWORD dwLength)
{
while (f && !feof (f)) {
gint length;
if (!fgets(szBuffer, dwLength, f))
break;
length = strlen(szBuffer);
// Skip any leading and trailing whitespace
while (length && isspace(szBuffer[0])) {
length--;
strcpy(szBuffer, szBuffer + 1);
}
while (length && isspace(szBuffer[length-1]))
szBuffer[--length] = '\0';
if (length && szBuffer[0] != '#')
return TRUE;
}
return FALSE;
}
BOOL RCInit(const gchar *szPath)
{
FILE* rc;
gchar buffer[MAX_BUFF];
if (RCLen)
return FALSE;
rc = RCOpen(szPath);
if (!(rc))
return FALSE;
while (RCReadNextLine(rc, buffer, sizeof (buffer))) {
gchar *temp;
if (buffer[0] == '*')
continue;
temp = g_malloc(strlen(buffer) + 1);
strcpy(temp, buffer);
if (!RCBuffer)
RCBuffer = g_malloc((RCLen + 1) * sizeof(gchar *));
else
RCBuffer = g_realloc(RCBuffer, (RCLen + 1) * sizeof(gchar *));
RCBuffer[RCLen++] = temp;
}
return RCClose(rc);
}
void RCShutDown(void)
{
gint loop;
for (loop = 0; loop < RCLen; ++loop)
g_free(RCBuffer[loop]);
if (RCBuffer) {
g_free(RCBuffer);
RCBuffer = NULL;
}
RCLen = 0;
}