unicode.h 4.0 KB

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