1/* 2Copyright (c) 2001 by Juliusz Chroboczek 3 4Permission is hereby granted, free of charge, to any person obtaining a copy 5of this software and associated documentation files (the "Software"), to deal 6in the Software without restriction, including without limitation the rights 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the Software is 9furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20THE SOFTWARE. 21*/ 22 23#ifdef HAVE_CONFIG_H 24# include "config.h" 25#endif 26 27#include <stdlib.h> 28#include <stdio.h> 29#include <string.h> 30 31#include "luit.h" 32#include "parser.h" 33#include "sys.h" 34 35static char keyword[MAX_KEYWORD_LENGTH]; 36 37static void 38skipEndOfLine(FILE *f, int c) 39{ 40 if (c == 0) 41 c = getc(f); 42 43 for (;;) 44 if (c <= 0 || c == '\n') 45 return; 46 else 47 c = getc(f); 48} 49 50static int 51drainWhitespace(FILE *f, int c) 52{ 53 if (c == 0) 54 c = getc(f); 55 56 while (c == '#' || c == ' ' || c == '\t') { 57 if (c <= 0) 58 return 0; 59 if (c == '#') { 60 skipEndOfLine(f, c); 61 return '\n'; 62 } 63 c = getc(f); 64 } 65 66 return c; 67} 68 69static int 70getString(FILE *f, int string_end, int *c_return) 71{ 72 int i = 0; 73 int c; 74 75 c = getc(f); 76 while (c > 0) { 77 if (c == string_end) 78 break; 79 if (c == '\\') { 80 c = getc(f); 81 if (c == '\n') 82 continue; 83 } 84 keyword[i++] = (char) c; 85 if (i >= MAX_KEYWORD_LENGTH) 86 return TOK_ERROR; 87 c = getc(f); 88 } 89 90 if (c <= 0) 91 return TOK_ERROR; 92 keyword[i] = '\0'; 93 *c_return = c; 94 return TOK_KEYWORD; 95} 96 97static int 98getToken(FILE *f, int c, int parse_assignments, int *c_return) 99{ 100 int i; 101 c = drainWhitespace(f, c); 102 103 if (c < 0) 104 return TOK_EOF; 105 if (c == '\n') { 106 *c_return = 0; 107 return TOK_EOL; 108 } 109 110 if (parse_assignments && c == '=') { 111 *c_return = 0; 112 return TOK_EQUALS; 113 } 114 115 if (c == '\'' || c == '"') 116 return getString(f, c, c_return); 117 118 i = 0; 119 while (c > 0 && c != ' ' && c != '\t' && c != '\n') { 120 if (c == '\\') { 121 c = getc(f); 122 if (c == '\n') 123 continue; 124 } 125 keyword[i++] = (char) c; 126 if (i >= MAX_KEYWORD_LENGTH) 127 return TOK_ERROR; 128 c = getc(f); 129 if (parse_assignments && c == '=') 130 break; 131 } 132 133 *c_return = c < 0 ? 0 : c; 134 keyword[i] = '\0'; 135 return TOK_KEYWORD; 136} 137 138/* Can parse both the old and new formats for locale.alias */ 139static int 140parseTwoTokenLine(FILE *f, char *first, char *second) 141{ 142 int c = 0; 143 int tok; 144 145 again: 146 147 tok = getToken(f, c, 0, &c); 148 if (tok == TOK_EOF) 149 return -1; 150 else if (tok == TOK_EOL) 151 goto again; 152 else if (tok == TOK_KEYWORD) { 153 size_t len = strlen(keyword); 154 if (keyword[len - 1] == ':') 155 keyword[len - 1] = '\0'; 156 strcpy(first, keyword); 157 } else 158 return -2; 159 160 tok = getToken(f, c, 0, &c); 161 if (tok == TOK_KEYWORD) { 162 strcpy(second, keyword); 163 } else 164 return -2; 165 166 tok = getToken(f, c, 0, &c); 167 if (tok != TOK_EOL) 168 return -2; 169 170 return 0; 171} 172 173char * 174resolveLocale(const char *locale) 175{ 176 FILE *f; 177 char first[MAX_KEYWORD_LENGTH], second[MAX_KEYWORD_LENGTH]; 178 char *resolved = NULL; 179 int rc; 180 int found = 0; 181 182 f = fopen(locale_alias, "r"); 183 184 if (f != NULL) { 185 do { 186 rc = parseTwoTokenLine(f, first, second); 187 if (rc < -1) 188 break; 189 if (!strcmp(first, locale)) { 190 resolved = strmalloc(second); 191 found = 1; 192 break; 193 } 194 } while (rc >= 0); 195 196 if (!found) { 197 if (resolved == NULL) { 198 resolved = strmalloc(locale); 199 } 200 } 201 202 fclose(f); 203 } else { 204 perror(locale_alias); 205 } 206 207 return resolved; 208} 209