#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "string.h"
#include "language.h"
static cups_lang_t *lang_cache = NULL;
static char *lang_blank = "";
static char *lang_encodings[] =
{
"us-ascii",
"iso-8859-1",
"iso-8859-2",
"iso-8859-3",
"iso-8859-4",
"iso-8859-5",
"iso-8859-6",
"iso-8859-7",
"iso-8859-8",
"iso-8859-9",
"iso-8859-10",
"utf-8",
"iso-8859-13",
"iso-8859-14",
"iso-8859-15",
"windows-874",
"windows-1250",
"windows-1251",
"windows-1252",
"windows-1253",
"windows-1254",
"windows-1255",
"windows-1256",
"windows-1257",
"windows-1258",
"koi8-r",
"koi8-u"
};
static char *lang_default[] =
{
#include "cups_C.h"
NULL
};
char *
cupsLangEncoding(cups_lang_t *lang)
{
if (lang == NULL)
return (lang_encodings[0]);
else
return (lang_encodings[lang->encoding]);
}
void
cupsLangFlush(void)
{
int i;
cups_lang_t *lang,
*next;
for (lang = lang_cache; lang != NULL; lang = next)
{
for (i = 0; i < CUPS_MSG_MAX; i ++)
if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
free(lang->messages[i]);
next = lang->next;
free(lang);
}
}
void
cupsLangFree(cups_lang_t *lang)
{
if (lang != NULL && lang->used > 0)
lang->used --;
}
cups_lang_t *
cupsLangGet(const char *language)
{
int i, count;
char langname[32],
*langptr,
real[32],
*realptr,
filename[1024],
*localedir;
FILE *fp;
char line[1024];
cups_msg_t msg;
char *text;
cups_lang_t *lang;
if (language == NULL || language[0] == '\0' ||
strcmp(language, "POSIX") == 0)
strcpy(langname, "C");
else
{
strlcpy(langname, language, sizeof(langname));
}
if (strlen(langname) < 2)
strcpy(real, "C");
else
{
real[0] = tolower(langname[0]);
real[1] = tolower(langname[1]);
realptr = real + 2;
langptr = langname + 2;
if (*langptr == '_' || *langptr == '-')
{
*realptr++ = '_';
langptr ++;
*realptr++ = toupper(*langptr++);
*realptr++ = toupper(*langptr++);
}
if (*langptr == '.')
{
*langptr++ = '\0';
*realptr++ = '.';
while (*langptr)
{
if ((realptr - real) < (sizeof(real) - 1) &&
*langptr != '-' && *langptr != '_')
*realptr++ = tolower(*langptr++);
else
langptr ++;
}
}
*realptr = '\0';
}
for (lang = lang_cache; lang != NULL; lang = lang->next)
if (strcmp(lang->language, langname) == 0)
{
lang->used ++;
return (lang);
}
if ((localedir = getenv("LOCALEDIR")) == NULL)
localedir = CUPS_LOCALEDIR;
for (fp = NULL; fp == NULL;)
{
snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir,
real, real);
if ((fp = fopen(filename, "r")) == NULL)
{
if ((realptr = strchr(real, '.')) != NULL)
*realptr = '\0';
else if ((realptr = strchr(real, '_')) != NULL)
*realptr = '\0';
else
break;
}
}
if (fp == NULL)
strlcpy(line, lang_default[0], sizeof(line));
else if (fgets(line, sizeof(line), fp) == NULL)
{
fclose(fp);
return (NULL);
}
i = strlen(line) - 1;
if (line[i] == '\n')
line[i] = '\0';
for (lang = lang_cache; lang != NULL; lang = lang->next)
if (lang->used == 0)
break;
if (lang == NULL)
{
if ((lang = calloc(sizeof(cups_lang_t), 1)) == NULL)
{
fclose(fp);
return (NULL);
}
lang->next = lang_cache;
lang_cache = lang;
}
for (i = 0; i < CUPS_MSG_MAX; i ++)
{
if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
free(lang->messages[i]);
lang->messages[i] = lang_blank;
}
lang->used ++;
strlcpy(lang->language, langname, sizeof(lang->language));
for (i = 0; i < (sizeof(lang_encodings) / sizeof(lang_encodings[0])); i ++)
if (strcmp(lang_encodings[i], line) == 0)
{
lang->encoding = (cups_encoding_t)i;
break;
}
msg = (cups_msg_t)-1;
count = 1;
for (;;)
{
if (fp == NULL)
{
if (lang_default[count] == NULL)
break;
strlcpy(line, lang_default[count], sizeof(line));
}
else if (fgets(line, sizeof(line), fp) == NULL)
break;
count ++;
i = strlen(line) - 1;
if (line[i] == '\n')
line[i] = '\0';
if (line[0] == '\0')
continue;
if (isdigit(line[0]))
msg = (cups_msg_t)atoi(line);
else
msg ++;
if (msg < 0 || msg >= CUPS_MSG_MAX)
continue;
text = line;
while (isdigit(*text))
text ++;
while (isspace(*text))
text ++;
lang->messages[msg] = strdup(text);
}
if (fp != NULL)
fclose(fp);
return (lang);
}