Skip to content

Commit

Permalink
Initial release. DYNAMIC LANGUAGE SUPPORT, BAYBY! Woo.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Dec 2, 1999
1 parent 284d554 commit 7681757
Showing 1 changed file with 212 additions and 0 deletions.
212 changes: 212 additions & 0 deletions BASIClib/Language.c
@@ -0,0 +1,212 @@
/*
* Routines for dynamic loading of internal BASIClib strings. This
* allows language-independence for the guts of BASIClib.
*
* Copyright (c) 1999 Ryan C. Gordon and Gregory S. Read.
* This file written by Ryan C. Gordon.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Language.h"


char *__BASIClibStrings[(__BASIClibStringIndex) _TOTAL_STRING_COUNT_];
static __boolean initializedStrings = false;

static inline char *getDefaultLangFileName(__boolean withDir)
{
# ifdef UNIX
if (withDir == true)
return("/etc/vbslacker.lang");
else
return("vbslacker.lang");
# elif (defined WIN32)
# error needs API to find Windows dir.
# elif (defined OS2)
# error needs API to find OS2 main dir.
# endif
} /* getDefaultLangFileName */


static inline FILE *openLangFile(char *vbHomeDir)
/*
* Open the correct langfile.
*
* The file is read from the vbslacker "user app dir" first, and failing
* that, it is read from /etc/vbslacker.lang or an equivalent. Check
* getDefaultLangFileName() for your platform's default langfile.
*
* params : void.
* returns : ANSI C file stream for reading langfile.
* throws : Runtime error
*
*/
{
FILE *retVal = NULL;
char *langFileName = getDefaultLangFileName(false);
char *langPath = malloc(strlen(vbHomeDir) + strlen(langFileName) + 1);

if (langPath == NULL)
__runtimeError(ERR_OUT_OF_MEMORY);

sprintf(langPath, "%s%s", vbHomeDir, langFileName);
retVal = fopen(langPath, "r");
free(langPath);

if (retVal == NULL)
{
retVal = fopen(getDefaultLangFileName(true), "r");
if (retVal == NULL)
__runtimeError(ERR_CANNOT_CONTINUE); /* !!! better error? */
} /* if */

return(retVal);
} /* openLangFile */


static void trimWhiteSpace(char *str)
{
int end = -1;
int i;
int max = strlen(str);

for (i = 0; end == -1; i++)
{
if ((str[i] != ' ') && (str[i] != '\t'))
end = i;
} /* for */

/* Move string to the left, overwriting whitespace chars... */
if (end != 0)
memmove(str, str + end, strlen(str + end) + 1);

max = strlen(str);
end = -1;

for (i = max; ((i >= 0) && (end == -1)); i--)
{
if ((str[i] != ' ') && (str[i] != '\t'))
end = i;
} /* for */

if (end != -1)
str[end + 1] = '\0'; /* terminate at start of whitespace. */
} /* trimWhiteSpace */


static char *readAndParseLanguageString(FILE *langFileStream)
{
int rc;
int strSize = 0;
int readCount = 0;
char *str = NULL;
__boolean getOut = false;

do
{
if (strSize <= readCount)
{
strSize += 100;
str = realloc(str, strSize);
} /* if */

rc = fgetc(langFileStream);
if ((rc == -1) || ((char) rc == '\r') || ((char) rc == '\n'))
getOut = true;
else
{
str[readCount] = (char) rc;
readCount++;
} /* else */
} while (getOut == false);

str[readCount] = '\0'; /* null-terminate the data we've read. */

trimWhiteSpace(str);

/* comment or blank line? Recursive call gets next line... */
if ((str[0] == '\0') || (str[0] == '#'))
{
free(str);
str = readAndParseLanguageString(langFileStream);
} /* if */
else
realloc(str, strlen(str) + 1);

return(str);
} /* readAndParseLanguageString */


void __initLanguage(char *vbHomeDir)
/*
* Read internal BASIClib strings from a language-independent text file.
*
* The langfile format is discussed in /vbslacker/docs/adding_languages.txt ...
*
* This is called VERY early in the initialization process, so you
* may not use the vast majority of BASIClib's functionality.
* Runtime errors are "preinit" and ugly, but work. The memory manager
* is not available at this point (use malloc().), __getUserAppDir() is
* available, but (vbHomeDir) is what that would return. Generally this is
* one of few places in BASIClib where you are encouraged to use C runtime
* library functions in favor of BASIClib equivalents.
*
* params : vbHomeDir == vb UserAppDir. THIS IS THE ORIGINAL. DO NOT
* MODIFY OR FREE THIS POINTER! READ ONLY!
* returns : void
*/
{
FILE *langFileStream;
int i;

if (initializedStrings == false)
{
langFileStream = openLangFile(vbHomeDir);

for (i = 0; i < (__BASIClibStringIndex) _TOTAL_STRING_COUNT_; i++)
{
__BASIClibStrings[i] = readAndParseLanguageString(langFileStream);
if (ferror(langFileStream))
__runtimeError(ERR_CANNOT_CONTINUE);
if (feof(langFileStream))
{
if (i != (__BASIClibStringIndex) _TOTAL_STRING_COUNT_ - 1)
__runtimeError(ERR_CANNOT_CONTINUE);
} /* if */
} /* for */

fclose(langFileStream);
initializedStrings = true;
} /* if */
} /* __initLanguage */


void __deinitLanguage(void)
/*
* Free up all the allocated language strings.
*
* params : void.
* returns : void.
*/
{
int i;

if (initializedStrings == true)
{
for (i = 0; i < (__BASIClibStringIndex) _TOTAL_STRING_COUNT_; i++)
{
if (__BASIClibStrings[i] != NULL)
{
free(__BASIClibStrings[i]);
__BASIClibStrings[i] = NULL;
} /* if */
} /* for */
} /* if */

initializedStrings = false;
} /* __deinitLanguage */

/* end if Language.c ... */

0 comments on commit 7681757

Please sign in to comment.