parser.c revision 77683534
1a8fdb4bcSmrg/* 2a8fdb4bcSmrgCopyright (c) 2001 by Juliusz Chroboczek 3a8fdb4bcSmrg 4a8fdb4bcSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 5a8fdb4bcSmrgof this software and associated documentation files (the "Software"), to deal 6a8fdb4bcSmrgin the Software without restriction, including without limitation the rights 7a8fdb4bcSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8a8fdb4bcSmrgcopies of the Software, and to permit persons to whom the Software is 9a8fdb4bcSmrgfurnished to do so, subject to the following conditions: 10a8fdb4bcSmrg 11a8fdb4bcSmrgThe above copyright notice and this permission notice shall be included in 12a8fdb4bcSmrgall copies or substantial portions of the Software. 13a8fdb4bcSmrg 14a8fdb4bcSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15a8fdb4bcSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16a8fdb4bcSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17a8fdb4bcSmrgAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18a8fdb4bcSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19a8fdb4bcSmrgOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20a8fdb4bcSmrgTHE SOFTWARE. 21a8fdb4bcSmrg*/ 2277683534Smrg 2377683534Smrg#ifdef HAVE_CONFIG_H 2477683534Smrg# include "config.h" 2577683534Smrg#endif 26a8fdb4bcSmrg 27a8fdb4bcSmrg#include <stdlib.h> 28a8fdb4bcSmrg#include <stdio.h> 29a8fdb4bcSmrg#include <string.h> 30a8fdb4bcSmrg 3177683534Smrg#include "luit.h" 32a8fdb4bcSmrg#include "parser.h" 3377683534Smrg#include "sys.h" 34a8fdb4bcSmrg 35a8fdb4bcSmrgstatic char keyword[MAX_KEYWORD_LENGTH]; 36a8fdb4bcSmrg 37a8fdb4bcSmrgstatic void 38a8fdb4bcSmrgskipEndOfLine(FILE *f, int c) 39a8fdb4bcSmrg{ 4077683534Smrg if (c == 0) 4177683534Smrg c = getc(f); 4277683534Smrg 4377683534Smrg for (;;) 4477683534Smrg if (c <= 0 || c == '\n') 4577683534Smrg return; 4677683534Smrg else 4777683534Smrg c = getc(f); 48a8fdb4bcSmrg} 49a8fdb4bcSmrg 50a8fdb4bcSmrgstatic int 51a8fdb4bcSmrgdrainWhitespace(FILE *f, int c) 52a8fdb4bcSmrg{ 5377683534Smrg if (c == 0) 5477683534Smrg c = getc(f); 55a8fdb4bcSmrg 56a8fdb4bcSmrg while (c == '#' || c == ' ' || c == '\t') { 5777683534Smrg if (c <= 0) 5877683534Smrg return 0; 5977683534Smrg if (c == '#') { 6077683534Smrg skipEndOfLine(f, c); 6177683534Smrg return '\n'; 6277683534Smrg } 6377683534Smrg c = getc(f); 64a8fdb4bcSmrg } 65a8fdb4bcSmrg 66a8fdb4bcSmrg return c; 67a8fdb4bcSmrg} 68a8fdb4bcSmrg 69a8fdb4bcSmrgstatic int 70a8fdb4bcSmrggetString(FILE *f, int string_end, int *c_return) 71a8fdb4bcSmrg{ 72a8fdb4bcSmrg int i = 0; 73a8fdb4bcSmrg int c; 74a8fdb4bcSmrg 75a8fdb4bcSmrg c = getc(f); 7677683534Smrg while (c > 0) { 7777683534Smrg if (c == string_end) 7877683534Smrg break; 7977683534Smrg if (c == '\\') { 8077683534Smrg c = getc(f); 8177683534Smrg if (c == '\n') 8277683534Smrg continue; 8377683534Smrg } 8477683534Smrg keyword[i++] = (char) c; 8577683534Smrg if (i >= MAX_KEYWORD_LENGTH) 8677683534Smrg return TOK_ERROR; 8777683534Smrg c = getc(f); 88a8fdb4bcSmrg } 89a8fdb4bcSmrg 9077683534Smrg if (c <= 0) 9177683534Smrg return TOK_ERROR; 92a8fdb4bcSmrg keyword[i] = '\0'; 93a8fdb4bcSmrg *c_return = c; 94a8fdb4bcSmrg return TOK_KEYWORD; 95a8fdb4bcSmrg} 96a8fdb4bcSmrg 97a8fdb4bcSmrgstatic int 98a8fdb4bcSmrggetToken(FILE *f, int c, int parse_assignments, int *c_return) 99a8fdb4bcSmrg{ 100a8fdb4bcSmrg int i; 101a8fdb4bcSmrg c = drainWhitespace(f, c); 102a8fdb4bcSmrg 10377683534Smrg if (c < 0) 10477683534Smrg return TOK_EOF; 10577683534Smrg if (c == '\n') { 10677683534Smrg *c_return = 0; 10777683534Smrg return TOK_EOL; 108a8fdb4bcSmrg } 109a8fdb4bcSmrg 11077683534Smrg if (parse_assignments && c == '=') { 11177683534Smrg *c_return = 0; 11277683534Smrg return TOK_EQUALS; 113a8fdb4bcSmrg } 114a8fdb4bcSmrg 11577683534Smrg if (c == '\'' || c == '"') 11677683534Smrg return getString(f, c, c_return); 117a8fdb4bcSmrg 118a8fdb4bcSmrg i = 0; 11977683534Smrg while (c > 0 && c != ' ' && c != '\t' && c != '\n') { 12077683534Smrg if (c == '\\') { 12177683534Smrg c = getc(f); 12277683534Smrg if (c == '\n') 12377683534Smrg continue; 12477683534Smrg } 12577683534Smrg keyword[i++] = (char) c; 12677683534Smrg if (i >= MAX_KEYWORD_LENGTH) 12777683534Smrg return TOK_ERROR; 12877683534Smrg c = getc(f); 12977683534Smrg if (parse_assignments && c == '=') 13077683534Smrg break; 131a8fdb4bcSmrg } 132a8fdb4bcSmrg 13377683534Smrg *c_return = c < 0 ? 0 : c; 134a8fdb4bcSmrg keyword[i] = '\0'; 135a8fdb4bcSmrg return TOK_KEYWORD; 136a8fdb4bcSmrg} 137a8fdb4bcSmrg 138a8fdb4bcSmrg/* Can parse both the old and new formats for locale.alias */ 139a8fdb4bcSmrgstatic int 140a8fdb4bcSmrgparseTwoTokenLine(FILE *f, char *first, char *second) 141a8fdb4bcSmrg{ 142a8fdb4bcSmrg int c = 0; 143a8fdb4bcSmrg int tok; 144a8fdb4bcSmrg 145a8fdb4bcSmrg again: 14677683534Smrg 147a8fdb4bcSmrg tok = getToken(f, c, 0, &c); 14877683534Smrg if (tok == TOK_EOF) 14977683534Smrg return -1; 15077683534Smrg else if (tok == TOK_EOL) 15177683534Smrg goto again; 15277683534Smrg else if (tok == TOK_KEYWORD) { 15377683534Smrg size_t len = strlen(keyword); 15477683534Smrg if (keyword[len - 1] == ':') 15577683534Smrg keyword[len - 1] = '\0'; 15677683534Smrg strcpy(first, keyword); 157a8fdb4bcSmrg } else 15877683534Smrg return -2; 159a8fdb4bcSmrg 160a8fdb4bcSmrg tok = getToken(f, c, 0, &c); 16177683534Smrg if (tok == TOK_KEYWORD) { 16277683534Smrg strcpy(second, keyword); 163a8fdb4bcSmrg } else 16477683534Smrg return -2; 165a8fdb4bcSmrg 166a8fdb4bcSmrg tok = getToken(f, c, 0, &c); 16777683534Smrg if (tok != TOK_EOL) 16877683534Smrg return -2; 169a8fdb4bcSmrg 170a8fdb4bcSmrg return 0; 171a8fdb4bcSmrg} 172a8fdb4bcSmrg 173a8fdb4bcSmrgchar * 174a8fdb4bcSmrgresolveLocale(const char *locale) 175a8fdb4bcSmrg{ 176a8fdb4bcSmrg FILE *f; 177a8fdb4bcSmrg char first[MAX_KEYWORD_LENGTH], second[MAX_KEYWORD_LENGTH]; 178a8fdb4bcSmrg char *resolved = NULL; 179a8fdb4bcSmrg int rc; 18077683534Smrg int found = 0; 18177683534Smrg 18277683534Smrg f = fopen(locale_alias, "r"); 18377683534Smrg 18477683534Smrg if (f != NULL) { 18577683534Smrg do { 18677683534Smrg rc = parseTwoTokenLine(f, first, second); 18777683534Smrg if (rc < -1) 18877683534Smrg break; 18977683534Smrg if (!strcmp(first, locale)) { 19077683534Smrg resolved = strmalloc(second); 19177683534Smrg found = 1; 19277683534Smrg break; 19377683534Smrg } 19477683534Smrg } while (rc >= 0); 19577683534Smrg 19677683534Smrg if (!found) { 19777683534Smrg if (resolved == NULL) { 19877683534Smrg resolved = strmalloc(locale); 19977683534Smrg } 20077683534Smrg } 20177683534Smrg 20277683534Smrg fclose(f); 20377683534Smrg } else { 20477683534Smrg perror(locale_alias); 205a8fdb4bcSmrg } 206a8fdb4bcSmrg 207a8fdb4bcSmrg return resolved; 208a8fdb4bcSmrg} 209