summaryrefslogtreecommitdiff
path: root/pl/dwmainc.c
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-06-04 22:04:12 +0100
committerRobin Watts <Robin.Watts@artifex.com>2011-06-05 00:06:14 +0100
commit0ea739147fd02ee0e63e58c036bb63fa841ddd3c (patch)
treec619becda3fa482903864064c27e1a577293d5fe /pl/dwmainc.c
parent4aff3e0d813cb00eb62db9720cf99b2d419f999a (diff)
Bug 691222: Make windows build use UTF-8 encoding.
We change the windows builds to use the 'wmain' rather than 'main' entrypoints. This means we get the command line supplied in 'wchar_t's rather than chars. We convert back to chars using UTF-8 encoding, and call (what was) the main entrypoint. This means that we can cope with unicode filenames/paths etc. To match the encoding, we therefore need to wrap every use of the filenames with the associated utf-8 -> wchar_t conversion and use the unicode file access functions (_wfopen instead of fopen etc) instead. Simple testing seems to indicate that this works. I think I've got every occurence of file access, but it's possible I've missed some. If so I'll fix them piecemeal as they are reported. This should solve bug 691222, and hopefully 691117.
Diffstat (limited to 'pl/dwmainc.c')
-rw-r--r--pl/dwmainc.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/pl/dwmainc.c b/pl/dwmainc.c
index ca1ad742d..82148b015 100644
--- a/pl/dwmainc.c
+++ b/pl/dwmainc.c
@@ -338,13 +338,51 @@ display_callback display = {
*/
/*********************************************************************/
+/* Would be nicer to have this in the DLL, but we haven't loaded the
+ * DLL by the time this is required.
+ */
+static int wchar_to_utf8(char *out, const wchar_t *in)
+{
+ unsigned int i;
+ unsigned int len = 1;
+
+ if (out) {
+ while (i = (unsigned int)*in++) {
+ if (i < 0x80) {
+ *out++ = (char)i;
+ len++;
+ } else if (i < 0x800) {
+ *out++ = 0xC0 | ( i>> 6 );
+ *out++ = 0x80 | ( i & 0x3F);
+ len++;
+ } else /* if (i < 0x10000) */ {
+ *out++ = 0xE0 | ( i>>12 );
+ *out++ = 0x80 | ((i>> 6) & 0x3F);
+ *out++ = 0x80 | ( i & 0x3F);
+ len++;
+ }
+ }
+ *out = 0;
+ } else {
+ while (i = (unsigned int)*in++) {
+ if (i < 0x80) {
+ len++;
+ } else if (i < 0x800) {
+ len += 2;
+ } else /* if (i < 0x10000) */ {
+ len += 3;
+ }
+ }
+ }
+ return len;
+}
/* Our 'main' routine sets up the separate thread to look after the
* display window, and inserts the relevant defaults for the display device.
* If the user specifies a different device, or different parameters to
* the display device, the later ones should take precedence.
*/
-int main(int argc, char *argv[])
+static int main_utf8(int argc, char *argv[])
{
int code, code1;
int exit_code;
@@ -432,3 +470,35 @@ int main(int argc, char *argv[])
return exit_status;
}
+
+int wmain(int argc, wchar_t *argv[], wchar_t *envp[]) {
+ /* Duplicate args as utf8 */
+ char **nargv;
+ int i, code;
+
+ nargv = calloc(argc, sizeof(nargv[0]));
+ if (nargv == NULL)
+ goto err;
+ for (i=0; i < argc; i++) {
+ nargv[i] = malloc(wchar_to_utf8(NULL, argv[i]));
+ if (nargv[i] == NULL)
+ goto err;
+ (void)wchar_to_utf8(nargv[i], argv[i]);
+ }
+ code = main_utf8(argc, nargv);
+
+ if (0) {
+err:
+ wprintf(L"Ghostscript failed to initialise due to malloc failure\n");
+ code = -1;
+ }
+
+ if (nargv) {
+ for (i=0; i<argc; i++) {
+ free(nargv[i]);
+ }
+ free(nargv);
+ }
+
+ return code;
+}