209 lines
4.0 KiB
C
209 lines
4.0 KiB
C
/*
|
|
Copyright (c) 2001 by Juliusz Chroboczek
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "luit.h"
|
|
#include "parser.h"
|
|
#include "sys.h"
|
|
|
|
static char keyword[MAX_KEYWORD_LENGTH];
|
|
|
|
static void
|
|
skipEndOfLine(FILE *f, int c)
|
|
{
|
|
if (c == 0)
|
|
c = getc(f);
|
|
|
|
for (;;)
|
|
if (c <= 0 || c == '\n')
|
|
return;
|
|
else
|
|
c = getc(f);
|
|
}
|
|
|
|
static int
|
|
drainWhitespace(FILE *f, int c)
|
|
{
|
|
if (c == 0)
|
|
c = getc(f);
|
|
|
|
while (c == '#' || c == ' ' || c == '\t') {
|
|
if (c <= 0)
|
|
return 0;
|
|
if (c == '#') {
|
|
skipEndOfLine(f, c);
|
|
return '\n';
|
|
}
|
|
c = getc(f);
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
static int
|
|
getString(FILE *f, int string_end, int *c_return)
|
|
{
|
|
int i = 0;
|
|
int c;
|
|
|
|
c = getc(f);
|
|
while (c > 0) {
|
|
if (c == string_end)
|
|
break;
|
|
if (c == '\\') {
|
|
c = getc(f);
|
|
if (c == '\n')
|
|
continue;
|
|
}
|
|
keyword[i++] = (char) c;
|
|
if (i >= MAX_KEYWORD_LENGTH)
|
|
return TOK_ERROR;
|
|
c = getc(f);
|
|
}
|
|
|
|
if (c <= 0)
|
|
return TOK_ERROR;
|
|
keyword[i] = '\0';
|
|
*c_return = c;
|
|
return TOK_KEYWORD;
|
|
}
|
|
|
|
static int
|
|
getToken(FILE *f, int c, int parse_assignments, int *c_return)
|
|
{
|
|
int i;
|
|
c = drainWhitespace(f, c);
|
|
|
|
if (c < 0)
|
|
return TOK_EOF;
|
|
if (c == '\n') {
|
|
*c_return = 0;
|
|
return TOK_EOL;
|
|
}
|
|
|
|
if (parse_assignments && c == '=') {
|
|
*c_return = 0;
|
|
return TOK_EQUALS;
|
|
}
|
|
|
|
if (c == '\'' || c == '"')
|
|
return getString(f, c, c_return);
|
|
|
|
i = 0;
|
|
while (c > 0 && c != ' ' && c != '\t' && c != '\n') {
|
|
if (c == '\\') {
|
|
c = getc(f);
|
|
if (c == '\n')
|
|
continue;
|
|
}
|
|
keyword[i++] = (char) c;
|
|
if (i >= MAX_KEYWORD_LENGTH)
|
|
return TOK_ERROR;
|
|
c = getc(f);
|
|
if (parse_assignments && c == '=')
|
|
break;
|
|
}
|
|
|
|
*c_return = c < 0 ? 0 : c;
|
|
keyword[i] = '\0';
|
|
return TOK_KEYWORD;
|
|
}
|
|
|
|
/* Can parse both the old and new formats for locale.alias */
|
|
static int
|
|
parseTwoTokenLine(FILE *f, char *first, char *second)
|
|
{
|
|
int c = 0;
|
|
int tok;
|
|
|
|
again:
|
|
|
|
tok = getToken(f, c, 0, &c);
|
|
if (tok == TOK_EOF)
|
|
return -1;
|
|
else if (tok == TOK_EOL)
|
|
goto again;
|
|
else if (tok == TOK_KEYWORD) {
|
|
size_t len = strlen(keyword);
|
|
if (keyword[len - 1] == ':')
|
|
keyword[len - 1] = '\0';
|
|
strcpy(first, keyword);
|
|
} else
|
|
return -2;
|
|
|
|
tok = getToken(f, c, 0, &c);
|
|
if (tok == TOK_KEYWORD) {
|
|
strcpy(second, keyword);
|
|
} else
|
|
return -2;
|
|
|
|
tok = getToken(f, c, 0, &c);
|
|
if (tok != TOK_EOL)
|
|
return -2;
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
resolveLocale(const char *locale)
|
|
{
|
|
FILE *f;
|
|
char first[MAX_KEYWORD_LENGTH], second[MAX_KEYWORD_LENGTH];
|
|
char *resolved = NULL;
|
|
int rc;
|
|
int found = 0;
|
|
|
|
f = fopen(locale_alias, "r");
|
|
|
|
if (f != NULL) {
|
|
do {
|
|
rc = parseTwoTokenLine(f, first, second);
|
|
if (rc < -1)
|
|
break;
|
|
if (!strcmp(first, locale)) {
|
|
resolved = strmalloc(second);
|
|
found = 1;
|
|
break;
|
|
}
|
|
} while (rc >= 0);
|
|
|
|
if (!found) {
|
|
if (resolved == NULL) {
|
|
resolved = strmalloc(locale);
|
|
}
|
|
}
|
|
|
|
fclose(f);
|
|
} else {
|
|
perror(locale_alias);
|
|
}
|
|
|
|
return resolved;
|
|
}
|