mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
localization: add locale block and message parsing
* Also add early left-to-right support
This commit is contained in:
parent
c7c297994d
commit
0c8d0e0c60
11 changed files with 299 additions and 98 deletions
|
@ -1,39 +1,29 @@
|
|||
ataak
|
||||
l "en-US"
|
||||
v 2 8
|
||||
# This is a comment
|
||||
t IDD_TEST "OHOH\"OLA\"LA\"BLA\"DI\""
|
||||
t ANY_MORE "国民生活センターの発表によ"
|
||||
# another comment
|
||||
asasas
|
||||
l "English" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809
|
||||
# TODO: replace 'p' with 's' for section
|
||||
p IDD_MESSAGES
|
||||
t MSG_001 "WARNING: ALL DATA ON DEVICE '%s' WILL BE DESTROYED.\n"
|
||||
"To continue with this operation, click OK. To quit click CANCEL."
|
||||
|
||||
sdsadsdaasd 12
|
||||
m IDD_CONTROL -12 +4a5
|
||||
r IDD_CONTROL2 +5 +10
|
||||
t IDD_MORE_BLURB "Yoda dadada daaddadada"
|
||||
"THIS IS PART OF NEXT LINE"
|
||||
" could I have "
|
||||
" ANY MORE LINESUS???"
|
||||
# Test comment
|
||||
# end
|
||||
l "French" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c
|
||||
p IDD_DIALOG
|
||||
t IDS_FORMATOPTIONS_TXT "Options de Formattage "
|
||||
t IDS_LABEL_TXT "Nouveau label"
|
||||
t IDS_FILESYSTEM_TXT "Système de fichier"
|
||||
t IDS_CLUSTERSIZE_TXT "Taille de clusters"
|
||||
t IDS_DEVICE_TXT "Periphérique"
|
||||
t IDS_PARTITION_TYPE_TXT "Type de partition et système de destination"
|
||||
t IDC_BADBLOCKS "Vérification de mauvais blocs:"
|
||||
t IDC_QUICKFORMAT "Formattage rapide"
|
||||
t IDC_BOOT "Disque de démarrage avec:"
|
||||
t IDC_SET_ICON "Ajouter un label étendu et une icône"
|
||||
m IDC_ADVANCED +18 0
|
||||
|
||||
#l "fr-FR"
|
||||
#t IDS_FORMATOPTIONS_TXT "Options de Formattage "
|
||||
#t IDS_LABEL_TXT "Nouveau label"
|
||||
#t IDS_FILESYSTEM_TXT "Système de fichier"
|
||||
#t IDS_CLUSTERSIZE_TXT "Taille de clusters"
|
||||
#t IDS_DEVICE_TXT "Periphérique"
|
||||
#t IDS_PARTITION_TYPE_TXT "Type de partition et système de destination"
|
||||
#t IDC_BADBLOCKS "Vérification de mauvais blocs:"
|
||||
#t IDC_QUICKFORMAT "Formattage rapide"
|
||||
#t IDC_BOOT "Disque de démarrage avec:"
|
||||
#t IDC_SET_ICON "Ajouter un label étendu et une icône"
|
||||
#m IDC_ADVANCED +37 0
|
||||
fake command
|
||||
p IDD_MESSAGES
|
||||
t MSG_001 "ATTENTION: TOUTES LES DONNEES SUR LE VOLUME '%s' VONT ETRE EFFACEES.\n"
|
||||
"Pour continuer cette operation, cliquez sur OK.\nPour quitter cliquez sur ANNULER."
|
||||
|
||||
l "Chinese (Simplified)" 0x0804, 0x1004, 0x0404, 0x0c04, 0x1404
|
||||
t IDC_START "开始"
|
||||
t IDC_STOP "关闭"
|
||||
l "Chinese (Traditional)" 0x0404, 0x0804, 0x0c04, 0x1004, 0x1404
|
||||
p IDD_DIALOG
|
||||
t IDS_DEVICE_TXT "设备"
|
||||
t IDS_PARTITION_TYPE_TXT "分区计划和目标系统类型"
|
||||
t IDS_FILESYSTEM_TXT "文件系统"
|
||||
|
@ -59,7 +49,6 @@ t IDC_ADVANCED_GROUP "高级选项"
|
|||
t IDC_ENABLE_FIXED_DISKS "列表固定(非flash)或USB磁盘分区"
|
||||
t IDC_EXTRA_PARTITION "添加修复旧的BIOS(额外的分区,校准等等)"
|
||||
t IDC_RUFUS_MBR "使用 Rufus MBR BIOS ID:"
|
||||
t IDD_DIALOG "Does this work?"
|
||||
|
||||
p IDD_ABOUTBOX
|
||||
t IDD_ABOUTBOX "关于 Rufus"
|
||||
|
|
|
@ -40,12 +40,12 @@
|
|||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
@ -62,6 +62,7 @@ const loc_parse parse_cmd[9] = {
|
|||
};
|
||||
int loc_line_nr;
|
||||
char loc_filename[32];
|
||||
struct list_head locale_list = {NULL, NULL};
|
||||
|
||||
void free_loc_cmd(loc_cmd* lcmd)
|
||||
{
|
||||
|
@ -91,13 +92,23 @@ void free_loc_dlg(void)
|
|||
for (i=0; i<ARRAYSIZE(loc_dlg); i++) {
|
||||
if (list_empty(&loc_dlg[i].list))
|
||||
continue;
|
||||
list_for_each_entry_safe(lcmd, next, &loc_dlg[i].list, list, loc_cmd) {
|
||||
list_for_each_entry_safe(lcmd, next, &loc_dlg[i].list, loc_cmd, list) {
|
||||
list_del(&lcmd->list);
|
||||
free_loc_cmd(lcmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void free_locale_list(void)
|
||||
{
|
||||
loc_cmd *lcmd, *next;
|
||||
|
||||
list_for_each_entry_safe(lcmd, next, &locale_list, loc_cmd, list) {
|
||||
list_del(&lcmd->list);
|
||||
free_loc_cmd(lcmd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to initialize the command lists
|
||||
*/
|
||||
|
@ -106,6 +117,12 @@ void init_localization(void) {
|
|||
|
||||
for (i=0; i<ARRAYSIZE(loc_dlg); i++)
|
||||
list_init(&loc_dlg[i].list);
|
||||
list_init(&locale_list);
|
||||
}
|
||||
|
||||
void exit_localization(void) {
|
||||
free_loc_dlg();
|
||||
free_locale_list();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -118,6 +135,9 @@ void apply_localization(int dlg_id, HWND hDlg)
|
|||
loc_cmd* lcmd;
|
||||
HWND hCtrl = NULL;
|
||||
int id_start = IDD_DIALOG, id_end = IDD_DIALOG + ARRAYSIZE(loc_dlg);
|
||||
LONG_PTR style;
|
||||
BOOL left_to_right = FALSE;
|
||||
|
||||
|
||||
if ((dlg_id >= id_start) && (dlg_id < id_end)) {
|
||||
// If we have a valid dialog_id, just process that one dialog
|
||||
|
@ -133,10 +153,11 @@ void apply_localization(int dlg_id, HWND hDlg)
|
|||
if ((!IsWindow(hDlg)) || (list_empty(&loc_dlg[dlg_id-IDD_DIALOG].list)))
|
||||
continue;
|
||||
|
||||
list_for_each_entry(lcmd, &loc_dlg[dlg_id-IDD_DIALOG].list, list, loc_cmd) {
|
||||
// TODO: storing the messages in an array indexed on the message ID - 3000 would be faster
|
||||
list_for_each_entry(lcmd, &loc_dlg[dlg_id-IDD_DIALOG].list, loc_cmd, list) {
|
||||
if (lcmd->command <= LC_TEXT) { // TODO: should always be the case
|
||||
if (lcmd->ctrl_id == dlg_id) {
|
||||
if (dlg_id == IDD_DIALOG) {
|
||||
if ((dlg_id == IDD_DIALOG) && (lcmd->txt[1] != NULL) && (lcmd->txt[1][0] != 0)) {
|
||||
loc_line_nr = lcmd->line_nr;
|
||||
luprint("operation forbidden (main dialog title cannot be changed)");
|
||||
continue;
|
||||
|
@ -156,7 +177,14 @@ 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->txt[1]);
|
||||
if ((lcmd->txt[1] != NULL) && (lcmd->txt[1][0] != 0))
|
||||
SetWindowTextU(hCtrl, lcmd->txt[1]);
|
||||
if (left_to_right) {
|
||||
style = GetWindowLongPtr(hCtrl, GWL_EXSTYLE);
|
||||
style |= WS_EX_LAYOUTRTL; // WS_EX_RIGHT | WS_EX_RTLREADING
|
||||
SetWindowLongPtr(hCtrl, GWL_EXSTYLE, style);
|
||||
InvalidateRect(hCtrl, NULL, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LC_MOVE:
|
||||
|
@ -181,7 +209,7 @@ void reset_localization(int dlg_id)
|
|||
loc_dlg[dlg_id-IDD_DIALOG].hDlg = NULL;
|
||||
}
|
||||
|
||||
// TODO: we need to store a revert for every action we execute here,
|
||||
// TODO: Do we need to store a revert for every action we execute here,
|
||||
// or do we want to reinstantiate the dialogs?
|
||||
BOOL dispatch_loc_cmd(loc_cmd* lcmd)
|
||||
{
|
||||
|
@ -191,9 +219,6 @@ BOOL dispatch_loc_cmd(loc_cmd* lcmd)
|
|||
if (lcmd == NULL)
|
||||
return FALSE;
|
||||
|
||||
// uprintf("cmd #%d: ('%s', '%s') (%d, %d)\n",
|
||||
// lcmd->command, lcmd->text[0], lcmd->text[1], lcmd->num[0], lcmd->num[1]);
|
||||
|
||||
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++) {
|
||||
|
@ -227,12 +252,6 @@ BOOL dispatch_loc_cmd(loc_cmd* lcmd)
|
|||
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;
|
||||
|
@ -243,3 +262,59 @@ err:
|
|||
free_loc_cmd(lcmd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char* get_loc_msg(int msg_id)
|
||||
{
|
||||
loc_cmd* lcmd;
|
||||
|
||||
list_for_each_entry(lcmd, &loc_dlg[IDD_MESSAGES-IDD_DIALOG].list, loc_cmd, list) {
|
||||
if ((lcmd->command == LC_TEXT) && (lcmd->ctrl_id == msg_id) && (lcmd->txt[1] != NULL)) {
|
||||
return lcmd->txt[1];
|
||||
}
|
||||
}
|
||||
// TODO: print the message ID or something
|
||||
return "UNTRANSLATED MESSAGE";
|
||||
}
|
||||
|
||||
loc_cmd* get_locale_from_lcid(int lcid)
|
||||
{
|
||||
loc_cmd* lcmd = NULL;
|
||||
int i;
|
||||
|
||||
if (list_empty(&locale_list)) {
|
||||
uprintf("localization: the locale list is empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
|
||||
for (i=0; i<lcmd->unum_size; i++) {
|
||||
if (lcmd->unum[i] == lcid) {
|
||||
return lcmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lcmd = list_entry(locale_list.next, loc_cmd, list);
|
||||
// If we couldn't find a supported locale, just pick the first one (usually English)
|
||||
uprintf("localization: could not find locale for LCID: 0x%04X. Will default to '%s'\n", lcid, lcmd->txt[0]);
|
||||
return lcmd;
|
||||
}
|
||||
|
||||
loc_cmd* get_locale_from_name(char* locale_name)
|
||||
{
|
||||
loc_cmd* lcmd = NULL;
|
||||
|
||||
if (list_empty(&locale_list)) {
|
||||
uprintf("localization: the locale list is empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
|
||||
if (safe_strcmp(lcmd->txt[0], locale_name) == 0)
|
||||
return lcmd;
|
||||
}
|
||||
|
||||
lcmd = list_entry(locale_list.next, loc_cmd, list);
|
||||
uprintf("localization: could not find locale for name '%s'. Will default to '%s'\n", locale_name, lcmd->txt[0]);
|
||||
return lcmd;
|
||||
}
|
||||
|
|
|
@ -53,13 +53,13 @@ struct list_head {
|
|||
* member - the list_head element in "pos"
|
||||
* type - the type of the first parameter
|
||||
*/
|
||||
#define list_for_each_entry(pos, head, member, type) \
|
||||
#define list_for_each_entry(pos, head, type, member) \
|
||||
for (pos = list_entry((head)->next, type, member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, type, member))
|
||||
|
||||
|
||||
#define list_for_each_entry_safe(pos, n, head, member, type) \
|
||||
#define list_for_each_entry_safe(pos, n, head, type, member) \
|
||||
for (pos = list_entry((head)->next, type, member), \
|
||||
n = list_entry(pos->member.next, type, member); \
|
||||
&pos->member != (head); \
|
||||
|
@ -140,12 +140,20 @@ typedef struct loc_dlg_list_struct {
|
|||
} loc_dlg_list;
|
||||
|
||||
extern const loc_parse parse_cmd[9];
|
||||
extern struct list_head locale_list;
|
||||
int loc_line_nr;
|
||||
char loc_filename[32];
|
||||
|
||||
void free_loc_cmd(loc_cmd* lcmd);
|
||||
BOOL dispatch_loc_cmd(loc_cmd* lcmd);
|
||||
void init_localization(void);
|
||||
void exit_localization(void);
|
||||
void apply_localization(int dlg_id, HWND hDlg);
|
||||
void reset_localization(int dlg_id);
|
||||
void free_loc_dlg(void);
|
||||
char* get_loc_msg(int id);
|
||||
BOOL get_supported_locales(const char* filename);
|
||||
char* get_loc_data_file(const char* filename, long offset, long end_offset);
|
||||
void free_locale_list(void);
|
||||
loc_cmd* get_locale_from_lcid(int lcid);
|
||||
loc_cmd* get_locale_from_name(char* locale_name);
|
||||
|
|
|
@ -35,6 +35,7 @@ const loc_control_id control_id[] = {
|
|||
LOC_CTRL(IDD_LOG),
|
||||
LOC_CTRL(IDD_UPDATE_POLICY),
|
||||
LOC_CTRL(IDD_NEW_VERSION),
|
||||
LOC_CTRL(IDD_MESSAGES),
|
||||
LOC_CTRL(IDC_DEVICE),
|
||||
LOC_CTRL(IDC_FILESYSTEM),
|
||||
LOC_CTRL(IDC_START),
|
||||
|
@ -96,6 +97,8 @@ const loc_control_id control_id[] = {
|
|||
LOC_CTRL(IDS_NEW_VERSION_AVAIL_TXT),
|
||||
LOC_CTRL(IDS_NEW_VERSION_DOWNLOAD_TXT),
|
||||
LOC_CTRL(IDS_NEW_VERSION_NOTES_TXT),
|
||||
LOC_CTRL(MSG_000),
|
||||
LOC_CTRL(MSG_001),
|
||||
LOC_CTRL(IDOK),
|
||||
LOC_CTRL(IDCANCEL),
|
||||
LOC_CTRL(IDABORT),
|
||||
|
@ -119,4 +122,5 @@ loc_dlg_list loc_dlg[] = {
|
|||
LOC_DLG(IDD_LOG),
|
||||
LOC_DLG(IDD_UPDATE_POLICY),
|
||||
LOC_DLG(IDD_NEW_VERSION),
|
||||
LOC_DLG(IDD_MESSAGES),
|
||||
};
|
||||
|
|
|
@ -39,8 +39,8 @@ cat > cmd.sed <<\_EOF
|
|||
const loc_control_id control_id[] = {\
|
||||
// The dialog IDs must come first
|
||||
|
||||
# Add the control entries - must be in IDD_, IDC_ or IDS_
|
||||
s/^#define \(ID[D|C|S][^ ]*\) .*/\ LOC_CTRL(\1),/
|
||||
# Add the control entries - must be in IDD_, IDC_, IDS_ or MSG_
|
||||
s/^#define \([I|M][D|S][D|C|S|G]_[^ ]*\) .*/\ LOC_CTRL(\1),/
|
||||
|
||||
# Add standard IDs from windows.h and close table
|
||||
$a\
|
||||
|
@ -73,7 +73,7 @@ cat > cmd.sed <<\_EOF
|
|||
loc_dlg_list loc_dlg[] = {
|
||||
|
||||
# Add the dialog entries - must start with IDD_
|
||||
s/^#define \(IDD[^ ]*\) .*/\ LOC_DLG(\1),/
|
||||
s/^#define \(IDD_[^ ]*\) .*/\ LOC_DLG(\1),/
|
||||
|
||||
# Close the table
|
||||
$a\
|
||||
|
|
165
src/parser.c
165
src/parser.c
|
@ -143,6 +143,7 @@ static loc_cmd* get_loc_cmd(char c, char* line) {
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return lcmd;
|
||||
|
||||
err:
|
||||
|
@ -152,35 +153,34 @@ err:
|
|||
|
||||
|
||||
// Parse an UTF-8 localization command line
|
||||
static void* get_loc_data_line(char* line)
|
||||
static void get_loc_data_line(char* line)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t i;
|
||||
loc_cmd* lcmd = NULL;
|
||||
char t;
|
||||
// char* locale = "en-US";
|
||||
// BOOL seek_locale = TRUE;
|
||||
|
||||
if ((line == NULL) || (line[0] == 0))
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
// Skip leading spaces
|
||||
i += strspn(&line[i], space);
|
||||
i = strspn(line, space);
|
||||
|
||||
// Read token (NUL character will be read if EOL)
|
||||
t = line[i++];
|
||||
if (t == '#') // Comment
|
||||
return NULL;
|
||||
return;
|
||||
if ((t == 0) || ((line[i] != space[0]) && (line[i] != space[1]))) {
|
||||
luprint("syntax error");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
lcmd = get_loc_cmd(t, &line[i]);
|
||||
// TODO: process LC_LOCALE in seek_locale mode
|
||||
// TODO: check return value?
|
||||
dispatch_loc_cmd(lcmd);
|
||||
|
||||
return NULL;
|
||||
if ((lcmd != NULL) && (lcmd->command != LC_LOCALE))
|
||||
// TODO: check return value?
|
||||
dispatch_loc_cmd(lcmd);
|
||||
else
|
||||
free_loc_cmd(lcmd);
|
||||
}
|
||||
|
||||
static __inline void *_reallocf(void *ptr, size_t size)
|
||||
|
@ -191,8 +191,83 @@ static __inline void *_reallocf(void *ptr, size_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* First pass of parsing the locale file, to construct the list
|
||||
* of locales available. The locale file must be UTF-8 with NO BOM.
|
||||
* TODO: merge this with the next call or factorize fopen
|
||||
*/
|
||||
BOOL get_supported_locales(const char* filename)
|
||||
{
|
||||
wchar_t *wfilename = NULL;
|
||||
FILE* fd = NULL;
|
||||
BOOL r = FALSE;
|
||||
char line[1024];
|
||||
size_t i;
|
||||
loc_cmd *lcmd = NULL, *last_lcmd = NULL;
|
||||
long end_of_block;
|
||||
|
||||
safe_strcpy(loc_filename, sizeof(loc_filename), filename);
|
||||
wfilename = utf8_to_wchar(filename);
|
||||
if (wfilename == NULL) {
|
||||
uprintf("localization: could not convert '%s' filename to UTF-16\n", filename);
|
||||
goto out;
|
||||
}
|
||||
fd = _wfopen(wfilename, L"r");
|
||||
if (fd == NULL) {
|
||||
uprintf("localization: could not open '%s'\n", filename);
|
||||
goto out;
|
||||
}
|
||||
|
||||
loc_line_nr = 0;
|
||||
line[0] = 0;
|
||||
free_locale_list();
|
||||
do {
|
||||
// adjust the last block
|
||||
end_of_block = ftell(fd);
|
||||
if (fgets(line, sizeof(line), fd) == NULL)
|
||||
break;
|
||||
loc_line_nr++;
|
||||
// Skip leading spaces
|
||||
i = strspn(line, space);
|
||||
if (line[i] != 'l')
|
||||
continue;
|
||||
// uprintf("Found potential start of loc at line %d\n", loc_line_nr);
|
||||
// line[i] is not NUL so i+1 is safe to access
|
||||
lcmd = get_loc_cmd(line[i], &line[i+1]);
|
||||
if ((lcmd == NULL) || (lcmd->command != LC_LOCALE)) {
|
||||
free_loc_cmd(lcmd);
|
||||
continue;
|
||||
}
|
||||
// we use num[0] and num[1] as block delimiter index for this locale in the file
|
||||
if (last_lcmd != NULL) {
|
||||
last_lcmd->num[1] = (int32_t)end_of_block;
|
||||
// uprintf("ended locale block at offset %d\n", last_lcmd->num[1]);
|
||||
}
|
||||
lcmd->num[0] = (int32_t)ftell(fd);
|
||||
// uprintf("started locale block for '%s' at offset %d\n", lcmd->txt[0], lcmd->num[0]);
|
||||
// Add our locale command to the locale list
|
||||
list_add_tail(&lcmd->list, &locale_list);
|
||||
uprintf("localization: found locale '%s'\n", lcmd->txt[0]);
|
||||
last_lcmd = lcmd;
|
||||
} while (1);
|
||||
if (last_lcmd != NULL)
|
||||
last_lcmd->num[1] = (int32_t)ftell(fd);
|
||||
// uprintf("ended locale block at offset %d\n", last_lcmd->num[1]);
|
||||
r = !list_empty(&locale_list);
|
||||
if (r == FALSE)
|
||||
uprintf("localization: '%s' contains no locale sections\n", filename);
|
||||
|
||||
out:
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
safe_free(wfilename);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Parse a Rufus localization command file (UTF-8, no BOM)
|
||||
char* get_loc_data_file(const char* filename)
|
||||
// TODO: detect if locale could not be found and fallback to En
|
||||
// TODO: change the return value and return an error if locale was not found
|
||||
char* get_loc_data_file(const char* filename, long offset, long end_offset)
|
||||
{
|
||||
wchar_t *wfilename = NULL;
|
||||
size_t bufsize = 1024;
|
||||
|
@ -201,7 +276,7 @@ char* get_loc_data_file(const char* filename)
|
|||
size_t i = 0;
|
||||
int r = 0, line_nr_incr = 1;
|
||||
int c = 0, eol_char = 0;
|
||||
BOOL eol = FALSE;
|
||||
BOOL eol = FALSE, escape_sequence = FALSE;
|
||||
|
||||
if ((filename == NULL) || (filename[0] == 0))
|
||||
return NULL;
|
||||
|
@ -226,7 +301,13 @@ char* get_loc_data_file(const char* filename)
|
|||
goto out;
|
||||
}
|
||||
|
||||
fseek(fd, offset, SEEK_SET);
|
||||
|
||||
do { // custom readline handling for string collation, realloc, line numbers, etc.
|
||||
if (offset++ > end_offset) {
|
||||
// uprintf("found end of section at offset %d\n", end_offset);
|
||||
goto out;
|
||||
}
|
||||
c = getc(fd);
|
||||
switch(c) {
|
||||
case EOF:
|
||||
|
@ -235,8 +316,16 @@ char* get_loc_data_file(const char* filename)
|
|||
loc_line_nr += line_nr_incr;
|
||||
get_loc_data_line(buf);
|
||||
goto out;
|
||||
case '\\':
|
||||
if (!escape_sequence)
|
||||
escape_sequence = TRUE;
|
||||
break;
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (escape_sequence) {
|
||||
escape_sequence = FALSE;
|
||||
break;
|
||||
}
|
||||
// This assumes that the EOL sequence is always the same throughout the file
|
||||
if (eol_char == 0)
|
||||
eol_char = c;
|
||||
|
@ -259,27 +348,48 @@ char* get_loc_data_file(const char* filename)
|
|||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (escape_sequence) {
|
||||
escape_sequence = FALSE;
|
||||
break;
|
||||
}
|
||||
if (!eol) {
|
||||
buf[i++] = (char)c;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Collate multiline strings
|
||||
if ((eol) && (c == '"') && (buf[r] == '"')) {
|
||||
i = r;
|
||||
eol = FALSE;
|
||||
break;
|
||||
if (escape_sequence) {
|
||||
switch (c) {
|
||||
case 'n': // \n -> CRLF
|
||||
buf[i++] = '\r';
|
||||
buf[i++] = '\n';
|
||||
break;
|
||||
case '"': // \" carried as is
|
||||
buf[i++] = '\\';
|
||||
buf[i++] = '"';
|
||||
break;
|
||||
default: // ignore any other escape sequence
|
||||
break;
|
||||
}
|
||||
escape_sequence = FALSE;
|
||||
} else {
|
||||
// Collate multiline strings
|
||||
if ((eol) && (c == '"') && (buf[r] == '"')) {
|
||||
i = r;
|
||||
eol = FALSE;
|
||||
break;
|
||||
}
|
||||
if (eol) {
|
||||
get_loc_data_line(buf);
|
||||
eol = FALSE;
|
||||
i = 0;
|
||||
r = 0;
|
||||
}
|
||||
buf[i++] = (char)c;
|
||||
}
|
||||
if (eol) {
|
||||
get_loc_data_line(buf);
|
||||
eol = FALSE;
|
||||
i = 0;
|
||||
r = 0;
|
||||
}
|
||||
buf[i++] = (char)c;
|
||||
break;
|
||||
}
|
||||
if (i >= bufsize-1) {
|
||||
// Have at least 2 chars extra, for \r\n sequences
|
||||
if (i >= bufsize-2) {
|
||||
bufsize *= 2;
|
||||
if (bufsize > 32768) {
|
||||
uprintf("localization: requested line buffer is larger than 32K!\n");
|
||||
|
@ -294,6 +404,7 @@ char* get_loc_data_file(const char* filename)
|
|||
} while(1);
|
||||
|
||||
out:
|
||||
// TODO: do we really need this here?
|
||||
apply_localization(-1, NULL);
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define IDD_LOG 106
|
||||
#define IDD_UPDATE_POLICY 107
|
||||
#define IDD_NEW_VERSION 108
|
||||
#define IDD_MESSAGES 109
|
||||
#define IDI_ICON 110
|
||||
#define IDI_UP 111
|
||||
#define IDI_DOWN 112
|
||||
|
@ -107,6 +108,8 @@
|
|||
#define IDS_NEW_VERSION_AVAIL_TXT 2009
|
||||
#define IDS_NEW_VERSION_DOWNLOAD_TXT 2010
|
||||
#define IDS_NEW_VERSION_NOTES_TXT 2011
|
||||
#define MSG_000 3000
|
||||
#define MSG_001 3001
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
|
22
src/rufus.c
22
src/rufus.c
|
@ -1448,8 +1448,6 @@ static void PrintStatus2000(const char* str, BOOL val)
|
|||
}
|
||||
|
||||
|
||||
// TODO: remove me
|
||||
extern char* get_loc_data_file(const char* filename);
|
||||
/*
|
||||
* Main dialog callback
|
||||
*/
|
||||
|
@ -1463,6 +1461,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
char tmp[128], str[MAX_PATH];
|
||||
static UINT uBootChecked = BST_CHECKED, uQFChecked;
|
||||
static BOOL first_log_display = TRUE, user_changed_label = FALSE;
|
||||
loc_cmd* selected_locale;
|
||||
|
||||
switch (message) {
|
||||
|
||||
|
@ -1595,7 +1594,17 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
break;
|
||||
#ifdef RUFUS_TEST
|
||||
case IDC_TEST:
|
||||
get_loc_data_file("rufus.loc");
|
||||
if ( (!get_supported_locales("rufus.loc"))
|
||||
// || ((selected_locale = get_locale_from_lcid(GetUserDefaultLCID())) == NULL) ) {
|
||||
|| ((selected_locale = get_locale_from_name("French")) == NULL) ) {
|
||||
uprintf("FATAL: Could not get a default locale!\n");
|
||||
MessageBoxU(NULL, "Default locale is missing - the application will now exit",
|
||||
"Localization failure", MB_ICONSTOP);
|
||||
break;
|
||||
}
|
||||
uprintf("Will use locale '%s'\n", selected_locale->txt[0]);
|
||||
get_loc_data_file("rufus.loc", (long)selected_locale->num[0], (long)selected_locale->num[1]);
|
||||
apply_localization(IDD_DIALOG, hDlg);
|
||||
break;
|
||||
#endif
|
||||
case IDC_ADVANCED:
|
||||
|
@ -1777,8 +1786,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
break;
|
||||
}
|
||||
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
|
||||
_snprintf(str, ARRAYSIZE(str), "WARNING: ALL DATA ON DEVICE '%s'\r\nWILL BE DESTROYED.\r\n"
|
||||
"To continue with this operation, click OK. To quit click CANCEL.", tmp);
|
||||
_snprintf(str, ARRAYSIZE(str), get_loc_msg(MSG_001), tmp);
|
||||
if (MessageBoxU(hMainDialog, str, APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) {
|
||||
format_op_in_progress = FALSE;
|
||||
break;
|
||||
|
@ -2035,6 +2043,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
GetTempPathU(sizeof(loc_path), loc_path);
|
||||
safe_strcat(loc_path, sizeof(loc_name), loc_name);
|
||||
|
||||
// TODO: make sure we fail if we can't extract the file as we'll miss all the messages
|
||||
|
||||
// Force Chinese localization from embedded rufus.loc file
|
||||
// TODO: REMOVE ME!
|
||||
hFile = CreateFileU(loc_path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
|
@ -2118,7 +2128,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
|
||||
out:
|
||||
DestroyAllTooltips();
|
||||
free_loc_dlg();
|
||||
exit_localization();
|
||||
safe_free(iso_path);
|
||||
safe_free(update.download_url);
|
||||
safe_free(update.release_notes);
|
||||
|
|
18
src/rufus.rc
18
src/rufus.rc
|
@ -39,21 +39,21 @@ BEGIN
|
|||
PUSHBUTTON "Log",IDC_LOG,62,291,18,14
|
||||
PUSHBUTTON "T",IDC_TEST,80,291,12,14,NOT WS_VISIBLE
|
||||
COMBOBOX IDC_DEVICE,8,17,190,33,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,188,8
|
||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,186,8
|
||||
COMBOBOX IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "File system",IDS_FILESYSTEM_TXT,9,64,188,10
|
||||
LTEXT "File system",IDS_FILESYSTEM_TXT,9,64,186,10
|
||||
COMBOBOX IDC_PARTITION_SCHEME,8,46,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Partition scheme and target system type",IDS_PARTITION_TYPE_TXT,9,35,188,8
|
||||
LTEXT "Partition scheme and target system type",IDS_PARTITION_TYPE_TXT,9,35,186,8
|
||||
COMBOBOX IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Cluster size",IDS_CLUSTERSIZE_TXT,9,93,189,10
|
||||
LTEXT "Cluster size",IDS_CLUSTERSIZE_TXT,9,93,186,10
|
||||
GROUPBOX "Format Options ",IDS_FORMATOPTIONS_TXT,7,149,192,66
|
||||
LTEXT "New volume label",IDS_LABEL_TXT,9,121,188,10
|
||||
LTEXT "New volume label",IDS_LABEL_TXT,9,121,186,10
|
||||
EDITTEXT IDC_LABEL,7,131,190,13,ES_AUTOHSCROLL
|
||||
CONTROL "Check device for bad blocks:",IDC_BADBLOCKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,161,101,10
|
||||
CONTROL "Quick format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,173,184,10
|
||||
CONTROL "Quick format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,173,181,10
|
||||
CONTROL "Create a bootable disk using:",IDC_BOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,185,104,10
|
||||
CONTROL "Create extended label and icon files",IDC_SET_ICON,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,198,183,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,198,181,10
|
||||
CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,8,272,189,9
|
||||
COMBOBOX IDC_NBPASSES,119,159,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_BOOTTYPE,119,183,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
@ -63,9 +63,9 @@ BEGIN
|
|||
GROUPBOX "Advanced Options",IDC_ADVANCED_GROUP,7,210,192,54
|
||||
COMBOBOX IDC_DISK_ID,119,246,73,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Add fixes for old BIOSes (extra partition, align, etc.)",IDC_EXTRA_PARTITION,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,184,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,181,10
|
||||
CONTROL "List fixed (non-flash) or unpartitioned USB disks",IDC_ENABLE_FIXED_DISKS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,222,185,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,222,181,10
|
||||
END
|
||||
|
||||
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 201
|
||||
|
|
|
@ -573,6 +573,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
|
|||
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
apply_localization(IDD_NOTIFICATION, hDlg);
|
||||
white_brush = CreateSolidBrush(WHITE);
|
||||
separator_brush = CreateSolidBrush(SEPARATOR_GREY);
|
||||
SetTitleBarIcon(hDlg);
|
||||
|
|
Loading…
Reference in a new issue