diff --git a/src/.msvc/rufus.loc b/src/.msvc/rufus.loc
new file mode 100644
index 00000000..a90b3a40
--- /dev/null
+++ b/src/.msvc/rufus.loc
@@ -0,0 +1,20 @@
+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
+
+ 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
+f "MS Dialog" 23
+
\ No newline at end of file
diff --git a/src/.msvc/rufus.vcxproj b/src/.msvc/rufus.vcxproj
index bb3ba460..b35a6ee3 100644
--- a/src/.msvc/rufus.vcxproj
+++ b/src/.msvc/rufus.vcxproj
@@ -169,6 +169,7 @@
+
@@ -185,6 +186,7 @@
+
diff --git a/src/.msvc/rufus.vcxproj.filters b/src/.msvc/rufus.vcxproj.filters
index e77ebd51..242e73fa 100644
--- a/src/.msvc/rufus.vcxproj.filters
+++ b/src/.msvc/rufus.vcxproj.filters
@@ -60,6 +60,9 @@
Source Files
+
+ Source Files
+
@@ -101,6 +104,9 @@
Header Files
+
+ Header Files
+
diff --git a/src/locale.c b/src/locale.c
new file mode 100644
index 00000000..615801c2
--- /dev/null
+++ b/src/locale.c
@@ -0,0 +1,64 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * Localization functions, a.k.a. "Everybody is doing it wrong but me!"
+ * Copyright © 2013 Pete Batard
+ *
+ * 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 3 of the License, 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, see .
+ */
+
+/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
+#ifdef _CRTDBG_MAP_ALLOC
+#include
+#include
+#endif
+
+#include
+#include
+#include
+#include
+
+#include "rufus.h"
+#include "msapi_utf8.h"
+#include "locale.h"
+
+/* s: quoted string, i: 32 bit signed integer, w single word (no space) */
+loc_parse parse_cmd[] = {
+ { 'v', LC_VERSION, "ii" },
+ { 'l', LC_LOCALE, "s" },
+ { 'f', LC_FONT, "si" },
+ { 'p', LC_PARENT, "w" },
+ { 'd', LC_DIRECTION, "i" },
+ { 'r', LC_RESIZE, "wii" },
+ { 'm', LC_MOVE, "wii" },
+ { 't', LC_TEXT, "ws" }
+};
+size_t PARSE_CMD_SIZE = ARRAYSIZE(parse_cmd);
+
+void free_loc_cmd(loc_cmd* lcmd)
+{
+ if (lcmd == NULL)
+ return;
+ safe_free(lcmd->text[0]);
+ safe_free(lcmd->text[1]);
+ free(lcmd);
+}
+
+BOOL execute_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]);
+ return TRUE;
+}
diff --git a/src/locale.h b/src/locale.h
new file mode 100644
index 00000000..80b9447f
--- /dev/null
+++ b/src/locale.h
@@ -0,0 +1,66 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * Localization functions, a.k.a. "Everybody is doing it wrong but me!"
+ * Copyright © 2013 Pete Batard
+ *
+ * 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 3 of the License, 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, see .
+ */
+
+#include
+
+// 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/
+
+enum loc_command_type {
+ LC_VERSION,
+ LC_LOCALE,
+ LC_FONT,
+ LC_PARENT,
+ LC_DIRECTION,
+ LC_RESIZE,
+ LC_MOVE,
+ LC_TEXT
+};
+
+typedef struct loc_cmd_struct {
+ int command;
+ char* text[2];
+ int32_t num[2];
+} loc_cmd;
+
+typedef struct loc_parse_struct {
+ char c;
+ enum loc_command_type cmd;
+ char* arg_type;
+} loc_parse;
+
+loc_parse parse_cmd[];
+size_t PARSE_CMD_SIZE;
+
+void free_loc_cmd(loc_cmd* lcmd);
+BOOL execute_loc_cmd(loc_cmd* lcmd);
diff --git a/src/parser.c b/src/parser.c
index 29ecc8a7..a2d34e0c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -33,56 +33,47 @@
#include "rufus.h"
#include "msapi_utf8.h"
-
-
-// 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/
-
-typedef struct localization_command {
- int command;
- wchar_t* text1;
- wchar_t* text2;
- int32_t num1;
- int32_t num2;
-} loc_cmd;
+#include "locale.h"
int loc_line_nr = 0;
char loc_filename[32];
#define luprintf(msg) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr);
-// Parse localization command arguments and fill a localization command structure
-static void get_loc_data_args(char* arg_type, wchar_t* wline) {
+// 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) {
const wchar_t wspace[] = L" \t";
- size_t i, r, arg_index;
- char str[1024]; // Fot testing only
- long n;
+ size_t i, j, k, r, ti = 0, ii = 0;
wchar_t *endptr, *expected_endptr;
+ loc_cmd* lcmd = NULL;
+
+ for (j=0; j= PARSE_CMD_SIZE) {
+ luprintf("unknown command");
+ return NULL;
+ }
+
+ lcmd = (loc_cmd*)calloc(sizeof(loc_cmd), 1);
+ if (lcmd == NULL) {
+ luprintf("could not allocate command");
+ return NULL;
+ }
+ lcmd->command = parse_cmd[j].cmd;
i = 0;
- for (arg_index=0; arg_type[arg_index] != 0; arg_index++) {
+ for (k = 0; parse_cmd[j].arg_type[k] != 0; k++) {
// Skip leading spaces
i += wcsspn(&wline[i], wspace);
r = i;
- switch(arg_type[arg_index]) {
+ switch(parse_cmd[j].arg_type[k]) {
case 's': // quoted string
// search leading quote
if (wline[i++] != L'"') {
- luprintf("missing leading quote");
- return;
+ luprintf("no start quote");
+ goto err;
}
r = i;
// locate ending quote
@@ -94,82 +85,76 @@ static void get_loc_data_args(char* arg_type, wchar_t* wline) {
}
}
if (wline[i] == 0) {
- luprintf("missing ending quote");
- return;
+ luprintf("no end quote");
+ goto err;
}
wline[i++] = 0;
- wchar_to_utf8_no_alloc(&wline[r], str, sizeof(str));
- uprintf("Got string: '%s'\n", str);
+ lcmd->text[ti++] = wchar_to_utf8(&wline[r]);
break;
case 'w': // single word
while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1]))
i++;
if (wline[i] != 0)
wline[i++] = 0;
- wchar_to_utf8_no_alloc(&wline[r], str, sizeof(str));
- uprintf("Got word: %s\n", str);
+ lcmd->text[ti++] = wchar_to_utf8(&wline[r]);
break;
- case 'i': // integer
+ case 'i': // 32 bit signed integer
while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1]))
i++;
expected_endptr = &wline[i];
if (wline[i] != 0)
wline[i++] = 0;
- n = wcstol(&wline[r], &endptr, 10);
+ lcmd->num[ii++] = (int32_t)wcstol(&wline[r], &endptr, 10);
if (endptr != expected_endptr) {
- luprintf("could not read integer data");
- return;
- } else {
- uprintf("Got integer: %d\n", n);
+ luprintf("invalid integer");
+ goto err;
}
break;
default:
- uprintf("localization: unhandled arg_type '%c'\n", arg_type[arg_index]);
- break;
+ uprintf("localization: unhandled arg_type '%c'\n", parse_cmd[j].arg_type[k]);
+ goto err;
}
}
+ return lcmd;
+
+err:
+ free_loc_cmd(lcmd);
+ return NULL;
}
+
// Parse an UTF-16 localization command line
static void* get_loc_data_line(wchar_t* wline)
{
const wchar_t wspace[] = L" \t";
- size_t i;
+ size_t i = 0;
wchar_t t;
- BOOLEAN quoteth = FALSE;
- char line[8192];
+ loc_cmd* lcmd = NULL;
+ char* locale = "en-US";
+ BOOL seek_locale = TRUE;
if ((wline == NULL) || (wline[0] == 0))
return NULL;
- i = 0;
-
// Skip leading spaces
i += wcsspn(&wline[i], wspace);
// Read token (NUL character will be read if EOL)
t = wline[i++];
- switch (t) {
- case 't':
- get_loc_data_args("ws", &wline[i]);
+ if (t == L'#') // Comment
return NULL;
- case 'f':
- get_loc_data_args("si", &wline[i]);
- return NULL;
- case 'r':
- case 'm':
- get_loc_data_args("wii", &wline[i]);
- return NULL;
- case 'v':
- get_loc_data_args("ii", &wline[i]);
- return NULL;
- case '#': // comment
- return NULL;
- default:
- wchar_to_utf8_no_alloc(wline, line, sizeof(line));
+ if ((t == 0) || ((wline[i] != wspace[0]) && (wline[i] != wspace[1]))) {
luprintf("syntax error");
return NULL;
}
+
+ lcmd = get_loc_cmd(t, &wline[i]);
+ // TODO: process LC_LOCALE in seek_locale mode
+ // TODO: check return value?
+ execute_loc_cmd(lcmd);
+ free_loc_cmd(lcmd);
+
+ return NULL;
}
static __inline void *_reallocf(void *ptr, size_t size)