/* * 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 #ifdef WIN32 #include #endif #include #include #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; }