mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[localization] provision of LCIDs for LC_LOCALE, fix line numbers
This commit is contained in:
parent
40d2f02fd9
commit
54bb962ec4
5 changed files with 108 additions and 64 deletions
|
@ -31,7 +31,7 @@ t IDD_MORE_BLURB "Yoda dadada daaddadada"
|
|||
#m IDC_ADVANCED +37 0
|
||||
fake command
|
||||
|
||||
l "zh-CN"
|
||||
l "Chinese (Simplified)" 0x0804, 0x1004, 0x0404, 0x0c04, 0x1404
|
||||
t IDC_START "开始"
|
||||
t IDC_STOP "关闭"
|
||||
t IDS_DEVICE_TXT "设备"
|
||||
|
@ -43,16 +43,16 @@ t IDS_FORMATOPTIONS_TXT "格式选项 "
|
|||
t IDC_BADBLOCKS "检查设备的坏块:"
|
||||
t IDC_QUICKFORMAT "快速格式化"
|
||||
t IDC_BOOT "创建一个可启动的磁盘使用:"
|
||||
r IDC_BOOT +10 0
|
||||
r IDC_BOOT +10,0
|
||||
t IDC_SET_ICON "创建扩展标签和图标文件"
|
||||
m IDC_ADVANCED -24 0
|
||||
m IDC_NBPASSES 8 0
|
||||
m IDC_BOOTTYPE 8 0
|
||||
m IDC_SELECT_ISO 6 0
|
||||
m IDC_ADVANCED -24,0
|
||||
m IDC_NBPASSES 8,0
|
||||
m IDC_BOOTTYPE 8,0
|
||||
m IDC_SELECT_ISO 6,0
|
||||
t IDC_ABOUT "关于..."
|
||||
t IDC_LOG "日志"
|
||||
m IDC_LOG -5 0
|
||||
r IDC_LOG +5 0
|
||||
m IDC_LOG -5,0
|
||||
r IDC_LOG +5,0
|
||||
t IDCANCEL "关闭"
|
||||
t IDC_START "开始"
|
||||
t IDC_ADVANCED_GROUP "高级选项"
|
||||
|
|
|
@ -35,27 +35,41 @@
|
|||
#include "localization.h"
|
||||
#include "localization_data.h"
|
||||
|
||||
/* c control ID (no space, no quotes), s: quoted string, i: 32 bit signed integer, */
|
||||
/* c control ID (no space, no quotes), s: quoted string, i: 32 bit signed integer, u: 32 bit unsigned CSV list */
|
||||
// Remember to update the size of the array in localization.h when adding/removing elements
|
||||
const loc_parse parse_cmd[8] = {
|
||||
{ 'l', LC_LOCALE, "s" },
|
||||
{ 'v', LC_VERSION, "ii" },
|
||||
{ 't', LC_TEXT, "cs" },
|
||||
{ 'p', LC_PARENT, "c" },
|
||||
{ 'r', LC_RESIZE, "cii" },
|
||||
{ 'm', LC_MOVE, "cii" },
|
||||
{ 'f', LC_FONT, "si" },
|
||||
{ 'd', LC_DIRECTION, "i" },
|
||||
const loc_parse parse_cmd[9] = {
|
||||
// Translation name and Windows LCIDs it should apply to
|
||||
{ 'l', LC_LOCALE, "su" }, // l "English (US)" 0x0009,0x1009
|
||||
// Base translation to add on top of (eg. "English (UK)" can be used to build on top of "English (US)"
|
||||
{ 'b', LC_BASE, "s" }, // b "English (US)" // TODO: NOT IMPLEMENTED YET
|
||||
// Version to use for the localization commandset and API
|
||||
{ 'v', LC_VERSION, "ii" }, // v 1.0 // TODO: NOT IMPLEMENTED YET
|
||||
// Translate the text control associated with an ID
|
||||
{ 't', LC_TEXT, "cs" }, // t IDC_CONTROL "Translation"
|
||||
// Set the parent dialog to which the next commands should apply.
|
||||
// Use 'p NONE' for text data that is not bound to a dialog
|
||||
{ 'p', LC_PARENT, "c" }, // p IDD_DIALOG
|
||||
// Resize a dialog (dx dy pixel increment)
|
||||
{ 'r', LC_RESIZE, "cii" }, // t IDC_CONTROL +10 +10
|
||||
// Move a dialog (dx dy pixed displacement)
|
||||
{ 'm', LC_MOVE, "cii" }, // t IDC_CONTROL -5 0
|
||||
// Set the font to use for the text controls that follow
|
||||
// Use f "Default" 0 to reset the font
|
||||
{ 'f', LC_FONT, "si" }, // f "MS Dialog" 10
|
||||
// Set the direction to use for the text controls that follow
|
||||
// 0 = Left to right, 1 = Right to left
|
||||
{ 'd', LC_DIRECTION, "i" }, // d 1 // TODO: NOT IMPLEMENTED YET
|
||||
};
|
||||
int loc_line_nr = 0;
|
||||
int loc_line_nr;
|
||||
char loc_filename[32];
|
||||
|
||||
void free_loc_cmd(loc_cmd* lcmd)
|
||||
{
|
||||
if (lcmd == NULL)
|
||||
return;
|
||||
safe_free(lcmd->text[0]);
|
||||
safe_free(lcmd->text[1]);
|
||||
safe_free(lcmd->txt[0]);
|
||||
safe_free(lcmd->txt[1]);
|
||||
safe_free(lcmd->unum);
|
||||
free(lcmd);
|
||||
}
|
||||
|
||||
|
@ -123,6 +137,7 @@ void apply_localization(int dlg_id, HWND hDlg)
|
|||
if (lcmd->command <= LC_TEXT) { // TODO: should always be the case
|
||||
if (lcmd->ctrl_id == dlg_id) {
|
||||
if (dlg_id == IDD_DIALOG) {
|
||||
loc_line_nr = lcmd->line_nr;
|
||||
luprint("operation forbidden (main dialog title cannot be changed)");
|
||||
continue;
|
||||
}
|
||||
|
@ -133,7 +148,7 @@ void apply_localization(int dlg_id, HWND hDlg)
|
|||
if (hCtrl == NULL) {
|
||||
loc_line_nr = lcmd->line_nr;
|
||||
luprintf("control '%s' is not part of dialog '%s'\n",
|
||||
lcmd->text[0], control_id[dlg_id-IDD_DIALOG].name);
|
||||
lcmd->txt[0], control_id[dlg_id-IDD_DIALOG].name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +156,7 @@ void apply_localization(int dlg_id, HWND hDlg)
|
|||
// NB: For commands that take an ID, ctrl_id is always a valid index at this stage
|
||||
case LC_TEXT:
|
||||
if (hCtrl != NULL) {
|
||||
SetWindowTextU(hCtrl, lcmd->text[1]);
|
||||
SetWindowTextU(hCtrl, lcmd->txt[1]);
|
||||
}
|
||||
break;
|
||||
case LC_MOVE:
|
||||
|
@ -182,19 +197,19 @@ BOOL dispatch_loc_cmd(loc_cmd* lcmd)
|
|||
if (lcmd->command <= LC_TEXT) {
|
||||
// Any command up to LC_TEXT takes a control ID in text[0]
|
||||
for (i=0; i<ARRAYSIZE(control_id); i++) {
|
||||
if (safe_strcmp(lcmd->text[0], control_id[i].name) == 0) {
|
||||
if (safe_strcmp(lcmd->txt[0], control_id[i].name) == 0) {
|
||||
lcmd->ctrl_id = control_id[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lcmd->ctrl_id < 0) {
|
||||
luprintf("unknown control '%s'\n", lcmd->text[0]);
|
||||
luprintf("unknown control '%s'\n", lcmd->txt[0]);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
switch(lcmd->command) {
|
||||
// NB: Form commands that take an ID, ctrl_id is always a valid index at this stage
|
||||
// NB: For commands that take an ID, ctrl_id is always a valid index at this stage
|
||||
case LC_TEXT:
|
||||
case LC_MOVE:
|
||||
case LC_RESIZE:
|
||||
|
@ -202,12 +217,22 @@ BOOL dispatch_loc_cmd(loc_cmd* lcmd)
|
|||
break;
|
||||
case LC_PARENT:
|
||||
if ((lcmd->ctrl_id-IDD_DIALOG) > ARRAYSIZE(loc_dlg)) {
|
||||
luprintf("'%s' is not a dialog ID\n", lcmd->text[0]);
|
||||
luprintf("'%s' is not a dialog ID\n", lcmd->txt[0]);
|
||||
goto err;
|
||||
}
|
||||
dlg_index = lcmd->ctrl_id - IDD_DIALOG;
|
||||
free_loc_cmd(lcmd);
|
||||
break;
|
||||
case LC_VERSION:
|
||||
luprintf("GOT VERSION: %d.%d\n", lcmd->num[0], lcmd->num[1]);
|
||||
free_loc_cmd(lcmd);
|
||||
break;
|
||||
case LC_LOCALE:
|
||||
luprintf("GOT LOCALE \"%s\", with LCIDs:\n", lcmd->txt[0]);
|
||||
for (i=0; i<lcmd->unum_size; i++)
|
||||
luprintf(" 0x%04X\n", lcmd->unum[i]);
|
||||
free_loc_cmd(lcmd);
|
||||
break;
|
||||
default:
|
||||
free_loc_cmd(lcmd);
|
||||
break;
|
||||
|
|
|
@ -22,20 +22,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// What we need for localization
|
||||
// # Comment
|
||||
// v 1 1 // UI target version (major, minor)
|
||||
// p IDD_DIALOG // parent dialog for the following
|
||||
// d 1 // set text direction 0: left to right, 1 right to left
|
||||
// f "MS Dialog" 12 // set font and font size
|
||||
// r IDD_DIALOG +30 +30 // resize dialog (delta_w, delta_h)
|
||||
// m IDC_START -10 0 // move control (delta_x, delta_w)
|
||||
// r IDC_START 0 +1 // resize control
|
||||
// t IDC_START "Demarrer" // Change control text
|
||||
// t IDC_LONG_CONTROL "Some text here"
|
||||
// "some continued text there"
|
||||
// all parsed commands return: cmd, control_id, text, num1, num2
|
||||
|
||||
// TODO: display control name on mouseover
|
||||
// Link to http://www.resedit.net/
|
||||
|
||||
|
@ -120,16 +106,19 @@ enum loc_command_type {
|
|||
LC_TEXT, // Delimits commands that take a Control ID and commands that don't
|
||||
LC_VERSION,
|
||||
LC_LOCALE,
|
||||
LC_BASE,
|
||||
LC_FONT,
|
||||
LC_DIRECTION,
|
||||
};
|
||||
|
||||
typedef struct loc_cmd_struct {
|
||||
int command;
|
||||
int ctrl_id;
|
||||
uint32_t line_nr;
|
||||
char* text[2];
|
||||
int32_t num[2];
|
||||
uint8_t command;
|
||||
uint8_t unum_size;
|
||||
uint16_t line_nr;
|
||||
int ctrl_id;
|
||||
int32_t num[2];
|
||||
uint32_t* unum;
|
||||
char* txt[2];
|
||||
struct list_head list;
|
||||
} loc_cmd;
|
||||
|
||||
|
@ -150,7 +139,7 @@ typedef struct loc_dlg_list_struct {
|
|||
struct list_head list;
|
||||
} loc_dlg_list;
|
||||
|
||||
extern const loc_parse parse_cmd[8];
|
||||
extern const loc_parse parse_cmd[9];
|
||||
int loc_line_nr;
|
||||
char loc_filename[32];
|
||||
|
||||
|
|
58
src/parser.c
58
src/parser.c
|
@ -34,15 +34,14 @@
|
|||
#include "rufus.h"
|
||||
#include "msapi_utf8.h"
|
||||
#include "localization.h"
|
||||
#include "resource.h" // TODO: remove_me - only needed for IDD_DIALOG
|
||||
|
||||
static const wchar_t wspace[] = L" \t";
|
||||
|
||||
// Fill a localization command buffer by parsing the line arguments
|
||||
// The command is allocated and must be freed (by calling free_loc_cmd)
|
||||
static loc_cmd* get_loc_cmd(wchar_t wc, wchar_t* wline) {
|
||||
size_t i, j, k, r, ti = 0, ii = 0;
|
||||
wchar_t *endptr, *expected_endptr;
|
||||
size_t i, j, k, l, r, ti = 0, ii = 0;
|
||||
wchar_t *endptr, *expected_endptr, *wtoken;
|
||||
loc_cmd* lcmd = NULL;
|
||||
|
||||
for (j=0; j<ARRAYSIZE(parse_cmd); j++) {
|
||||
|
@ -68,6 +67,10 @@ static loc_cmd* get_loc_cmd(wchar_t wc, wchar_t* wline) {
|
|||
// Skip leading spaces
|
||||
i += wcsspn(&wline[i], wspace);
|
||||
r = i;
|
||||
if (wline[i] == 0) {
|
||||
luprintf("missing parameter for command '%c'", parse_cmd[j].c);
|
||||
goto err;
|
||||
}
|
||||
switch(parse_cmd[j].arg_type[k]) {
|
||||
case 's': // quoted string
|
||||
// search leading quote
|
||||
|
@ -89,27 +92,51 @@ static loc_cmd* get_loc_cmd(wchar_t wc, wchar_t* wline) {
|
|||
goto err;
|
||||
}
|
||||
wline[i++] = 0;
|
||||
lcmd->text[ti++] = wchar_to_utf8(&wline[r]);
|
||||
lcmd->txt[ti++] = wchar_to_utf8(&wline[r]);
|
||||
break;
|
||||
case 'c': // control ID (single word)
|
||||
while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1]))
|
||||
i++;
|
||||
if (wline[i] != 0)
|
||||
wline[i++] = 0;
|
||||
lcmd->text[ti++] = wchar_to_utf8(&wline[r]);
|
||||
lcmd->txt[ti++] = wchar_to_utf8(&wline[r]);
|
||||
break;
|
||||
case 'i': // 32 bit signed integer
|
||||
while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1]))
|
||||
// allow commas or dots between values
|
||||
if ((wline[i] == L',') || (wline[i] == L'.')) {
|
||||
i += wcsspn(&wline[i+1], wspace);
|
||||
r = i;
|
||||
}
|
||||
while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1])
|
||||
&& (wline[i] != L',') && (wline[i] != L'.'))
|
||||
i++;
|
||||
expected_endptr = &wline[i];
|
||||
if (wline[i] != 0)
|
||||
wline[i++] = 0;
|
||||
lcmd->num[ii++] = (int32_t)wcstol(&wline[r], &endptr, 10);
|
||||
lcmd->num[ii++] = (int32_t)wcstol(&wline[r], &endptr, 0);
|
||||
if (endptr != expected_endptr) {
|
||||
luprint("invalid integer");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case 'u': // comma separated list of unsigned integers (to end of line)
|
||||
// count the number of commas
|
||||
lcmd->unum_size = 1;
|
||||
for (l=i; wline[l] != 0; l++) {
|
||||
if (wline[l] == L',')
|
||||
lcmd->unum_size++;
|
||||
}
|
||||
lcmd->unum = (uint32_t*)malloc(lcmd->unum_size * sizeof(uint32_t));
|
||||
wtoken = wcstok(&wline[i], L",");
|
||||
for (l=0; (l<lcmd->unum_size) && (wtoken != NULL); l++) {
|
||||
lcmd->unum[l] = (int32_t)wcstol(wtoken, &endptr, 0);
|
||||
wtoken = wcstok(NULL, L",");
|
||||
}
|
||||
if ((wtoken != NULL) || (l != lcmd->unum_size)) {
|
||||
luprint("internal error (unexpected number of numeric values)");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
uprintf("localization: unhandled arg_type '%c'\n", parse_cmd[j].arg_type[k]);
|
||||
goto err;
|
||||
|
@ -167,12 +194,12 @@ static __inline void *_reallocf(void *ptr, size_t size)
|
|||
char* get_loc_data_file(const char* filename)
|
||||
{
|
||||
wchar_t *wfilename = NULL, *wbuf = NULL;
|
||||
size_t wbufsize = 1024; // size in wchar_t
|
||||
size_t wbufsize = 1024;
|
||||
FILE* fd = NULL;
|
||||
char *ret = NULL;
|
||||
size_t i = 0;
|
||||
int r = 0, line_nr_incr = 1;
|
||||
wchar_t wc = 0, last_wc;
|
||||
wchar_t wc = 0, last_wc, eol_char = 0;
|
||||
BOOL eol = FALSE;
|
||||
|
||||
if ((filename == NULL) || (filename[0] == 0))
|
||||
|
@ -196,19 +223,22 @@ char* get_loc_data_file(const char* filename)
|
|||
goto out;
|
||||
}
|
||||
|
||||
do { // custom readline handling for string collation, realloc, line number handling, etc.
|
||||
do { // custom readline handling for string collation, realloc, line numbers, etc.
|
||||
last_wc = wc;
|
||||
wc = getwc(fd);
|
||||
switch(wc) {
|
||||
case WEOF:
|
||||
wbuf[i] = 0;
|
||||
loc_line_nr += line_nr_incr;
|
||||
if (!eol)
|
||||
loc_line_nr += line_nr_incr;
|
||||
get_loc_data_line(wbuf);
|
||||
goto out;
|
||||
case L'\r':
|
||||
case L'\n':
|
||||
// Process line numbers
|
||||
if ((last_wc != 0x0D) && (last_wc != 0x0A)) {
|
||||
// This assumes that the EOL sequence is always the same throughout the file
|
||||
if (eol_char == 0)
|
||||
eol_char = wc;
|
||||
if (wc = eol_char) {
|
||||
if (eol) {
|
||||
line_nr_incr++;
|
||||
} else {
|
||||
|
@ -219,7 +249,7 @@ char* get_loc_data_file(const char* filename)
|
|||
wbuf[i] = 0;
|
||||
if (!eol) {
|
||||
// Strip trailing spaces (for string collation)
|
||||
for (r = ((int)i)-1; (r>0) && ((wbuf[r]==0x20)||(wbuf[r]==0x09)); r--);
|
||||
for (r = ((int)i)-1; (r>0) && ((wbuf[r]==wspace[0])||(wbuf[r]==wspace[1])); r--);
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
eol = TRUE;
|
||||
|
|
|
@ -1328,6 +1328,9 @@ void InitDialog(HWND hDlg)
|
|||
}
|
||||
uprintf("Windows version: %s %d-bit\n", PrintWindowsVersion(nWindowsVersion), is_x64?64:32);
|
||||
|
||||
// Detect the LCID
|
||||
uprintf("LCID: 0x%04X\n", GetUserDefaultLCID());
|
||||
|
||||
// Prefer FreeDOS to MS-DOS
|
||||
selection_default = DT_FREEDOS;
|
||||
// Create the status line and initialize the taskbar icon for progress overlay
|
||||
|
@ -1918,9 +1921,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
// Init localization
|
||||
init_localization();
|
||||
|
||||
// TODO: See what happens with this
|
||||
// SetThreadLocale(MAKELCID(LANG_FRENCH, SUBLANG_FRENCH));
|
||||
|
||||
// Reattach the console, if we were started from commandline
|
||||
if (AttachConsole(ATTACH_PARENT_PROCESS) != 0) {
|
||||
attached_console = TRUE;
|
||||
|
|
Loading…
Reference in a new issue