#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "parser.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++] = 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++] = 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;
}
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) {
int 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(char *locale)
{
FILE *f;
char first[MAX_KEYWORD_LENGTH], second[MAX_KEYWORD_LENGTH];
char *resolved = NULL;
int rc;
f = fopen(LOCALE_ALIAS_FILE, "r");
if(f == NULL)
goto bail;
do {
rc = parseTwoTokenLine(f, first, second);
if(rc < -1)
goto bail;
if(!strcmp(first, locale)) {
resolved = malloc(strlen(second) + 1);
if(resolved == NULL)
goto bail;
strcpy(resolved, second);
break;
}
} while(rc >= 0);
if(resolved == NULL) {
resolved = malloc(strlen(locale) + 1);
if(resolved == NULL)
goto bail;
strcpy(resolved, locale);
}
fclose(f);
return resolved;
bail:
if(f != NULL)
fclose(f);
if(resolved != NULL)
free(resolved);
return NULL;
}