1*b2055c35SXin Li // Copyright 2018 Google Inc. All Rights Reserved. 2*b2055c35SXin Li // 3*b2055c35SXin Li // Use of this source code is governed by a BSD-style license 4*b2055c35SXin Li // that can be found in the COPYING file in the root of the source 5*b2055c35SXin Li // tree. An additional intellectual property rights grant can be found 6*b2055c35SXin Li // in the file PATENTS. All contributing project authors may 7*b2055c35SXin Li // be found in the AUTHORS file in the root of the source tree. 8*b2055c35SXin Li // ----------------------------------------------------------------------------- 9*b2055c35SXin Li // 10*b2055c35SXin Li // Unicode support for Windows. The main idea is to maintain an array of Unicode 11*b2055c35SXin Li // arguments (wargv) and use it only for file paths. The regular argv is used 12*b2055c35SXin Li // for everything else. 13*b2055c35SXin Li // 14*b2055c35SXin Li // Author: Yannis Guyon ([email protected]) 15*b2055c35SXin Li 16*b2055c35SXin Li #ifndef WEBP_EXAMPLES_UNICODE_H_ 17*b2055c35SXin Li #define WEBP_EXAMPLES_UNICODE_H_ 18*b2055c35SXin Li 19*b2055c35SXin Li #include <stdio.h> 20*b2055c35SXin Li 21*b2055c35SXin Li #if defined(_WIN32) && defined(_UNICODE) 22*b2055c35SXin Li 23*b2055c35SXin Li // wchar_t is used instead of TCHAR because we only perform additional work when 24*b2055c35SXin Li // Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t. 25*b2055c35SXin Li 26*b2055c35SXin Li #include <fcntl.h> 27*b2055c35SXin Li #include <io.h> 28*b2055c35SXin Li #include <wchar.h> 29*b2055c35SXin Li #include <windows.h> 30*b2055c35SXin Li #include <shellapi.h> 31*b2055c35SXin Li 32*b2055c35SXin Li // Create a wchar_t array containing Unicode parameters. 33*b2055c35SXin Li #define INIT_WARGV(ARGC, ARGV) \ 34*b2055c35SXin Li int wargc; \ 35*b2055c35SXin Li const W_CHAR** const wargv = \ 36*b2055c35SXin Li (const W_CHAR**)CommandLineToArgvW(GetCommandLineW(), &wargc); \ 37*b2055c35SXin Li do { \ 38*b2055c35SXin Li if (wargv == NULL || wargc != (ARGC)) { \ 39*b2055c35SXin Li fprintf(stderr, "Error: Unable to get Unicode arguments.\n"); \ 40*b2055c35SXin Li FREE_WARGV_AND_RETURN(-1); \ 41*b2055c35SXin Li } \ 42*b2055c35SXin Li } while (0) 43*b2055c35SXin Li 44*b2055c35SXin Li // Use this to get a Unicode argument (e.g. file path). 45*b2055c35SXin Li #define GET_WARGV(UNUSED, C) wargv[C] 46*b2055c35SXin Li // For cases where argv is shifted by one compared to wargv. 47*b2055c35SXin Li #define GET_WARGV_SHIFTED(UNUSED, C) wargv[(C) + 1] 48*b2055c35SXin Li #define GET_WARGV_OR_NULL() wargv 49*b2055c35SXin Li 50*b2055c35SXin Li // Release resources. LocalFree() is needed after CommandLineToArgvW(). 51*b2055c35SXin Li #define FREE_WARGV() LOCAL_FREE((W_CHAR** const)wargv) 52*b2055c35SXin Li #define LOCAL_FREE(WARGV) \ 53*b2055c35SXin Li do { \ 54*b2055c35SXin Li if ((WARGV) != NULL) LocalFree(WARGV); \ 55*b2055c35SXin Li } while (0) 56*b2055c35SXin Li 57*b2055c35SXin Li #define W_CHAR wchar_t // WCHAR without underscore might already be defined. 58*b2055c35SXin Li #define TO_W_CHAR(STR) (L##STR) 59*b2055c35SXin Li 60*b2055c35SXin Li #define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT)) 61*b2055c35SXin Li 62*b2055c35SXin Li #define WFPRINTF(STREAM, STR, ...) \ 63*b2055c35SXin Li do { \ 64*b2055c35SXin Li int prev_mode; \ 65*b2055c35SXin Li fflush(STREAM); \ 66*b2055c35SXin Li prev_mode = _setmode(_fileno(STREAM), _O_U8TEXT); \ 67*b2055c35SXin Li fwprintf(STREAM, TO_W_CHAR(STR), __VA_ARGS__); \ 68*b2055c35SXin Li fflush(STREAM); \ 69*b2055c35SXin Li (void)_setmode(_fileno(STREAM), prev_mode); \ 70*b2055c35SXin Li } while (0) 71*b2055c35SXin Li #define WPRINTF(STR, ...) WFPRINTF(stdout, STR, __VA_ARGS__) 72*b2055c35SXin Li 73*b2055c35SXin Li #define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME) 74*b2055c35SXin Li #define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR)) 75*b2055c35SXin Li #define WSTRRCHR(FILENAME, STR) wcsrchr((const W_CHAR*)FILENAME, TO_W_CHAR(STR)) 76*b2055c35SXin Li #define WSNPRINTF(A, B, STR, ...) _snwprintf(A, B, TO_W_CHAR(STR), __VA_ARGS__) 77*b2055c35SXin Li 78*b2055c35SXin Li #else 79*b2055c35SXin Li 80*b2055c35SXin Li #include <string.h> 81*b2055c35SXin Li 82*b2055c35SXin Li // Unicode file paths work as is on Unix platforms, and no extra work is done on 83*b2055c35SXin Li // Windows either if Unicode is disabled. 84*b2055c35SXin Li 85*b2055c35SXin Li #define INIT_WARGV(ARGC, ARGV) 86*b2055c35SXin Li 87*b2055c35SXin Li #define GET_WARGV(ARGV, C) (ARGV)[C] 88*b2055c35SXin Li #define GET_WARGV_SHIFTED(ARGV, C) (ARGV)[C] 89*b2055c35SXin Li #define GET_WARGV_OR_NULL() NULL 90*b2055c35SXin Li 91*b2055c35SXin Li #define FREE_WARGV() 92*b2055c35SXin Li #define LOCAL_FREE(WARGV) 93*b2055c35SXin Li 94*b2055c35SXin Li #define W_CHAR char 95*b2055c35SXin Li #define TO_W_CHAR(STR) (STR) 96*b2055c35SXin Li 97*b2055c35SXin Li #define WFOPEN(ARG, OPT) fopen(ARG, OPT) 98*b2055c35SXin Li 99*b2055c35SXin Li #define WPRINTF(STR, ...) printf(STR, __VA_ARGS__) 100*b2055c35SXin Li #define WFPRINTF(STREAM, STR, ...) fprintf(STREAM, STR, __VA_ARGS__) 101*b2055c35SXin Li 102*b2055c35SXin Li #define WSTRLEN(FILENAME) strlen(FILENAME) 103*b2055c35SXin Li #define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR) 104*b2055c35SXin Li #define WSTRRCHR(FILENAME, STR) strrchr(FILENAME, STR) 105*b2055c35SXin Li #define WSNPRINTF(A, B, STR, ...) snprintf(A, B, STR, __VA_ARGS__) 106*b2055c35SXin Li 107*b2055c35SXin Li #endif // defined(_WIN32) && defined(_UNICODE) 108*b2055c35SXin Li 109*b2055c35SXin Li // Don't forget to free wargv before returning (e.g. from main). 110*b2055c35SXin Li #define FREE_WARGV_AND_RETURN(VALUE) \ 111*b2055c35SXin Li do { \ 112*b2055c35SXin Li FREE_WARGV(); \ 113*b2055c35SXin Li return (VALUE); \ 114*b2055c35SXin Li } while (0) 115*b2055c35SXin Li 116*b2055c35SXin Li #endif // WEBP_EXAMPLES_UNICODE_H_ 117