📄 gbx_local.c
字号:
/*************************************************************************** local.c The internationalization management routines (c) 2000-2004 Beno� Minisini <gambas@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_LOCAL_C#include "gb_common.h"#include "gb_common_buffer.h"#include "gb_common_case.h"#include "gb_error.h"#include "gbx_value.h"#include "gb_limit.h"#include <locale.h>#include <langinfo.h>#include <time.h>#include <ctype.h>#include <math.h>#include <float.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <libintl.h>#include "gbx_math.h"#include "gbx_date.h"#include "gbx_string.h"#include "gbx_api.h"#include "gb_file.h"#include "gbx_archive.h"#include "gbx_local.h"//#define DEBUG_LANGPUBLIC char *LOCAL_encoding;PUBLIC bool LOCAL_is_UTF8;/* Localisation interne par d�aut */PUBLIC LOCAL_INFO LOCAL_default = { '.', 0, '/', ':', { LO_MONTH, LO_DAY, LO_YEAR }, { LO_HOUR, LO_MINUTE, LO_SECOND }, "dddd mmmm d yyyy", "mmm d yy", "mm/dd/yy", "hh:nn:ss", "hh:nn AM/PM", "hh:nn" };/* Localisation... locale */PUBLIC LOCAL_INFO LOCAL_local;PRIVATE LOCAL_INFO *local_current;PRIVATE bool local_trans = FALSE;PRIVATE char *local_trans_file = NULL;PRIVATE char *env_LC_ALL = NULL;PRIVATE char *env_LANGUAGE = NULL;PRIVATE char *env_LANG = NULL;PRIVATE int my_setenv(const char *name, const char *value, char **ptr){ char *str = NULL; STRING_add(&str, name, 0); STRING_add(&str, "=", 1); STRING_add(&str, value, 0); if (putenv(str)) { STRING_free(&str); return 1; } else { STRING_free(ptr); *ptr = str; return 0; }}PRIVATE void begin(void){ buffer_init(COMMON_buffer, COMMON_BUF_MAX - 4);}PRIVATE void end(char **str, long *len){ *(get_current()) = 0; *str = COMMON_buffer; *len = buffer_pos;}PRIVATE void stradd_sep(char *dst, const char *src, const char *sep){ if (*dst) strcat(dst, sep); strcat(dst, src);}PRIVATE void add_thousand_sep(int *before){ if (before == NULL) return; if ((*before > 1) && ((*before - 1) == (((*before - 1) / 3) * 3))) { if (local_current->thousand_sep != 0) put_char(local_current->thousand_sep); } (*before)--;}/*PRIVATE char *strnadd(char *dst, char *src, int len, int *before)*/PRIVATE void add_string(const char *src, long len, int *before){ while (len > 0) { put_char(*src++); len--; add_thousand_sep(before); }}PRIVATE void add_zero(int zero, int *before){ while (zero > 0) { put_char('0'); zero--; add_thousand_sep(before); }}PRIVATE long search(const char *src, long len, const char *list, long start, boolean not){ long i; char c; for (i = start; i < len; i++) { c = src[i]; if (c == '\\') { i++; continue; } if ((index(list, c) != NULL) ^ not) return i; } return len;}#if 0PRIVATE void old_add_sign(char mode, int sign){ if (sign < 0) put_char('-'); else if (mode != 0) { if (sign > 0) put_char(mode); else put_char(' '); }}#endifstatic void add_sign(char mode, int sign, bool after){ if (after && mode != '(') return; if (sign < 0) { if (mode == '(') put_char(after ? ')' : '('); else put_char('-'); } else if (mode != 0 && mode != '(') { if (sign > 0) put_char(mode); else put_char(' '); }}PRIVATE void unload_translation(void){ if (!local_trans_file) return; unlink(local_trans_file); STRING_free(&local_trans_file);}PRIVATE void load_translation(void){ char *lang_list = NULL; char *lang; char pid[16]; char *src; const char *dst; FILE *file; char *addr; long len; char *test; char c; #ifdef DEBUG_LANG fprintf(stderr, ">> load_translation()\n"); #endif sprintf(pid, "%d", getpid()); STRING_new_temp(&lang, LOCAL_get_lang(), 0); STRING_add(&lang_list, lang, 0); STRING_add(&lang_list, ":", 1); src = index(lang, '_'); if (src) { *src = 0; STRING_add(&lang_list, lang, 0); STRING_add(&lang_list, ":", 1); } /*STRING_add(&lang_list, getenv("LANGUAGE"), 0);*/ #ifdef DEBUG_LANG fprintf(stderr, "Languages = %s\n", lang_list); #endif lang = strtok(lang_list, ":"); for(;;) { if (!lang) { #ifdef DEBUG_LANG fprintf(stderr, "No translation\n"); #endif goto _NOTRANS; } if (*lang) { STRING_new_temp(&test, lang, 0); src = test; for(;;) { c = *src; if (c == 0 || c == '_') break; *src = tolower(c); src++; } dst = FILE_cat(".lang", test, NULL); dst = FILE_set_ext(dst, "mo"); #ifdef DEBUG_LANG fprintf(stderr, "trying %s\n", dst); #endif if (FILE_exist(dst)) break; } lang = strtok(NULL, ":"); } #ifdef DEBUG_LANG fprintf(stderr, "Loading %s\n", dst); #endif if (GB_LoadFile(dst, 0, &addr, &len)) { #ifdef DEBUG_LANG fprintf(stderr, "Cannot load %s\n", dst); #endif goto _ERROR; } /*dst = FILE_cat("/tmp/gambas", NULL); <-- Fait dans FILE_init() mkdir(dst, S_IRWXU);*/ /*sprintf(COMMON_buffer, FILE_TEMP_DIR, getuid());*/ dst = FILE_cat(FILE_make_temp(NULL), lang, NULL); mkdir(dst, S_IRWXU); dst = FILE_cat(dst, "LC_MESSAGES", NULL); mkdir(dst, S_IRWXU); dst = FILE_cat(dst, pid, NULL); dst = FILE_set_ext(dst, "mo"); unlink(dst); unload_translation(); STRING_new(&local_trans_file, dst, 0); #ifdef DEBUG_LANG fprintf(stderr, "Writing to %s\n", dst); #endif file = fopen(dst, "w"); fwrite(addr, len, 1, file); fclose(file); GB_ReleaseFile(&addr, len);_ERROR: #ifdef DEBUG_LANG fprintf(stderr, "bindtextdomain: %s\n", bindtextdomain(pid, FILE_make_temp(NULL))); fprintf(stderr, "bind_textdomain_codeset: %s\n", bind_textdomain_codeset(pid, "UTF-8")); fprintf(stderr, "textdomain: %s\n", textdomain(pid)); #else bindtextdomain(pid, FILE_make_temp(NULL)); #ifdef __sun__ fprintf(stderr, "Warning: bind_textdomain_codeset() unavailable.\n"); #else bind_textdomain_codeset(pid, "UTF-8"); #endif textdomain(pid); #endif_NOTRANS: local_trans = FALSE; STRING_free(&lang_list); #ifdef DEBUG_LANG fprintf(stderr, "<< load_translation()\n"); #endif}PRIVATE void fill_local_info(void){ static struct tm tm = { 0 }; struct lconv *info; char buf[32]; char *p; char c; char *dp; char *tp; /* Localisation courante */ CLEAR(&LOCAL_local); info = localeconv(); LOCAL_local.decimal_point = *(info->decimal_point); LOCAL_local.thousand_sep = *(info->thousands_sep); if (LOCAL_local.thousand_sep == 0) LOCAL_local.thousand_sep = ' '; /* Date */ tm.tm_year = 4; /* 02/03/1904 05:06:07 */ tm.tm_mday = 2; tm.tm_mon = 2; tm.tm_hour = 5; tm.tm_min = 6; tm.tm_sec = 7; strftime(buf, sizeof(buf), "%x %X", &tm); dp = LOCAL_local.date_order; tp = LOCAL_local.time_order; for (p = buf;;) { c = *p++; if (!c) break; switch(c) { case '4': *dp++ = LO_YEAR; stradd_sep(LOCAL_local.long_date, "yyyy", " "); stradd_sep(LOCAL_local.medium_date, "yy", " "); stradd_sep(LOCAL_local.short_date, "yy", "/"); stradd_sep(LOCAL_local.general_date, "yyyy", "/"); break; case '3': *dp++ = LO_MONTH; stradd_sep(LOCAL_local.long_date, "mmmm", " "); stradd_sep(LOCAL_local.medium_date, "mmm", " "); stradd_sep(LOCAL_local.short_date, "mm", "/"); stradd_sep(LOCAL_local.general_date, "mm", "/"); break; case '2': *dp++ = LO_DAY; stradd_sep(LOCAL_local.long_date, "dddd d", " "); stradd_sep(LOCAL_local.medium_date, "dd", " "); stradd_sep(LOCAL_local.short_date, "dd", "/"); stradd_sep(LOCAL_local.general_date, "dd", "/"); break; case '5': *tp++ = LO_HOUR; stradd_sep(LOCAL_local.long_time, "hh", ":"); stradd_sep(LOCAL_local.medium_time, "hh", ":"); stradd_sep(LOCAL_local.short_time, "hh", ":"); break; case '6': *tp++ = LO_MINUTE; stradd_sep(LOCAL_local.long_time, "nn", ":"); stradd_sep(LOCAL_local.medium_time, "nn", ":"); stradd_sep(LOCAL_local.short_time, "nn", ":"); break; case '7': *tp++ = LO_SECOND; stradd_sep(LOCAL_local.long_time, "ss", ":"); break; default: if (!isdigit(c)) { if (tp != LOCAL_local.time_order) { if (LOCAL_local.time_sep == 0) LOCAL_local.time_sep = c; } else { if (LOCAL_local.date_sep == 0) LOCAL_local.date_sep = c; } } } } stradd_sep(LOCAL_local.general_date, LOCAL_local.long_time, " "); stradd_sep(LOCAL_local.medium_time, "AM/PM", " "); /*if (LOCAL_local.date_sep == LOCAL_local.decimal_point) LOCAL_local.date_sep = LOCAL_default.date_sep; if (LOCAL_local.time_sep == LOCAL_local.decimal_point) LOCAL_local.time_sep = LOCAL_default.time_sep;*/#if 0 { char *str; long len; VALUE value; DATE_now(&value); LOCAL_format_date(DATE_split(&value), LF_USER, "ddd dd mmm yyyy hh:mm:ss AM/PM", 0, &str, &len); printf("FORMAT->%s\n", str); }#endif}PUBLIC void LOCAL_init(void){ char *codeset; LOCAL_set_lang(NULL); /* local encoding */ codeset = nl_langinfo(CODESET); if (!codeset || !*codeset) codeset = "US-ASCII"; STRING_new(&LOCAL_encoding, codeset, 0); LOCAL_is_UTF8 = (strcasecmp(LOCAL_encoding, "UTF-8") == 0); #ifdef DEBUG_LANG fprintf(stderr, "LOCAL_encoding = %s\n", LOCAL_encoding); #endif}PUBLIC void LOCAL_exit(void){ unload_translation(); STRING_free(&env_LANG); STRING_free(&env_LC_ALL); STRING_free(&env_LANGUAGE); STRING_free(&LOCAL_encoding);}PUBLIC const char *LOCAL_get_lang(void){ char *lang; lang = getenv("LC_ALL"); if (!lang) lang = getenv("LANG"); if (!lang || !*lang) lang = "en_US"; return lang;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -