|
26 | 26 |
|
27 | 27 | #include "lauxlib.h" |
28 | 28 |
|
| 29 | +#if defined(LUA_USE_WINDOWS) /* PREMAKE: UTF-8 support on Windows */ |
| 30 | +#include <windows.h> |
| 31 | +#endif |
29 | 32 |
|
30 | 33 | /* |
31 | 34 | ** {====================================================== |
@@ -706,19 +709,34 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, |
706 | 709 | int status, readstatus; |
707 | 710 | int c; |
708 | 711 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ |
| 712 | +#if defined(LUA_USE_WINDOWS) /* PREMAKE: UTF-8 character support on windows */ |
| 713 | + const wchar_t *wfilename = NULL; |
| 714 | +#endif |
709 | 715 | if (filename == NULL) { |
710 | 716 | lua_pushliteral(L, "=stdin"); |
711 | 717 | lf.f = stdin; |
712 | 718 | } |
713 | 719 | else { |
714 | 720 | lua_pushfstring(L, "@%s", filename); |
| 721 | +#if defined(LUA_USE_WINDOWS) /* PREMAKE: UTF-8 character support on windows */ |
| 722 | + wfilename = luaL_convertstring(L, filename); |
| 723 | + lf.f = wfilename ? _wfopen(wfilename, L"r") : NULL; |
| 724 | + if (wfilename) lua_pop(L, 1); |
| 725 | +#else |
715 | 726 | lf.f = fopen(filename, "r"); |
| 727 | +#endif |
716 | 728 | if (lf.f == NULL) return errfile(L, "open", fnameindex); |
717 | 729 | } |
718 | 730 | if (skipcomment(&lf, &c)) /* read initial portion */ |
719 | 731 | lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ |
720 | 732 | if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ |
| 733 | +#if defined(LUA_USE_WINDOWS) /* PREMAKE: UTF-8 character support on windows */ |
| 734 | + wfilename = luaL_convertstring(L, filename); |
| 735 | + lf.f = wfilename ? _wfreopen(wfilename, L"rb", lf.f) : NULL; /* reopen in binary mode */ |
| 736 | + if (wfilename) lua_pop(L, 1); |
| 737 | +#else |
721 | 738 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
| 739 | +#endif |
722 | 740 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
723 | 741 | skipcomment(&lf, &c); /* re-read initial portion */ |
724 | 742 | } |
@@ -988,6 +1006,36 @@ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, |
988 | 1006 | } |
989 | 1007 |
|
990 | 1008 |
|
| 1009 | +LUALIB_API const char *luaL_getenv (lua_State *L, const char *name) { |
| 1010 | +#if defined(LUA_USE_WINDOWS) |
| 1011 | + const wchar_t *wname = luaL_convertstring(L, name); |
| 1012 | + const char *s; |
| 1013 | + wchar_t *wvar; |
| 1014 | + DWORD rc; |
| 1015 | + luaL_Buffer wbuf; |
| 1016 | + if (wname == NULL) return NULL; |
| 1017 | + rc = GetEnvironmentVariableW(wname, NULL, 0); |
| 1018 | + if (!rc) { |
| 1019 | + lua_pop(L, 1); |
| 1020 | + return NULL; |
| 1021 | + } |
| 1022 | + wvar = (wchar_t *)luaL_buffinitsize(L, &wbuf, rc * sizeof(wchar_t)); |
| 1023 | + GetEnvironmentVariableW(wname, wvar, rc); |
| 1024 | + luaL_pushresultsize(&wbuf, rc * sizeof(wchar_t)); |
| 1025 | + wvar = (wchar_t *)lua_tostring(L, -1); |
| 1026 | + s = luaL_convertlwstring(L, wvar, rc - 1, NULL); |
| 1027 | + lua_remove(L, -2); /* remove the string from wbuf */ |
| 1028 | + lua_remove(L, -2); /* remove the string from wname */ |
| 1029 | + return s; |
| 1030 | +#else |
| 1031 | + const char *value = getenv(name); |
| 1032 | + if (!value) return NULL; |
| 1033 | + lua_pushstring(L, value); |
| 1034 | + return lua_tostring(L, -1); |
| 1035 | +#endif |
| 1036 | +} |
| 1037 | + |
| 1038 | + |
991 | 1039 | LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, |
992 | 1040 | const char *r) { |
993 | 1041 | const char *wild; |
@@ -1041,3 +1089,116 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { |
1041 | 1089 | (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v); |
1042 | 1090 | } |
1043 | 1091 |
|
| 1092 | +/* |
| 1093 | +** {====================================================== |
| 1094 | +** Lua wide-string support (Windows only) |
| 1095 | +** ======================================================= |
| 1096 | +*/ |
| 1097 | +#if defined(LUA_USE_WINDOWS) |
| 1098 | +typedef struct UWideString { |
| 1099 | + size_t len; |
| 1100 | + wchar_t s[1]; /* actual size is len + 1 */ |
| 1101 | +} UWideString; |
| 1102 | + |
| 1103 | +#define LUA_WIDESTRING "LUA_WIDESTRING" |
| 1104 | + |
| 1105 | +static UWideString *newwidestr (lua_State *L, const wchar_t *s, size_t len) { |
| 1106 | + UWideString *ws = (UWideString *)lua_newuserdata(L, sizeof(UWideString) + len * sizeof(wchar_t)); |
| 1107 | + luaL_newmetatable(L, LUA_WIDESTRING); |
| 1108 | + lua_setmetatable(L, -2); |
| 1109 | + if (s) memcpy(ws->s, s, len * sizeof(wchar_t)); |
| 1110 | + ws->s[len] = L'\0'; |
| 1111 | + ws->len = len; |
| 1112 | + return ws; |
| 1113 | +} |
| 1114 | + |
| 1115 | +LUALIB_API const wchar_t *luaL_convertlstringi (lua_State *L, int idx, size_t *len) |
| 1116 | +{ |
| 1117 | + size_t nlen; |
| 1118 | + const char *s = lua_tolstring(L, idx, &nlen); |
| 1119 | + return luaL_convertlstring(L, s, nlen, len); |
| 1120 | +} |
| 1121 | + |
| 1122 | +LUALIB_API const char *luaL_convertlwstring (lua_State *L, const wchar_t *ws, size_t wlen, size_t *len) |
| 1123 | +{ |
| 1124 | + int size; |
| 1125 | + luaL_Buffer buf; |
| 1126 | + char *s; |
| 1127 | + if (ws == NULL) { |
| 1128 | + if (len != NULL) *len = 0; |
| 1129 | + return NULL; |
| 1130 | + } |
| 1131 | + size = WideCharToMultiByte(CP_UTF8, 0, ws, wlen, NULL, 0, NULL, NULL); |
| 1132 | + if (size == 0) { /* conversion failure */ |
| 1133 | + if (len != NULL) *len = 0; |
| 1134 | + return NULL; |
| 1135 | + } |
| 1136 | + s = luaL_buffinitsize(L, &buf, size); |
| 1137 | + WideCharToMultiByte(CP_UTF8, 0, ws, wlen, s, size, NULL, NULL); |
| 1138 | + luaL_pushresultsize(&buf, size); |
| 1139 | + if (len != NULL) *len = size; |
| 1140 | + return lua_tostring(L, -1); |
| 1141 | +} |
| 1142 | + |
| 1143 | +LUALIB_API const wchar_t *luaL_convertlstring (lua_State *L, const char *s, size_t nlen, size_t *len) |
| 1144 | +{ |
| 1145 | + int size; |
| 1146 | + UWideString *ws; |
| 1147 | + if (s == NULL) { |
| 1148 | + if (len != NULL) *len = 0; |
| 1149 | + return NULL; |
| 1150 | + } |
| 1151 | + size = MultiByteToWideChar(CP_UTF8, 0, s, nlen, NULL, 0); |
| 1152 | + if (size == 0) { /* conversion failure */ |
| 1153 | + if (len != NULL) *len = 0; |
| 1154 | + return NULL; |
| 1155 | + } |
| 1156 | + |
| 1157 | + ws = newwidestr(L, NULL, size); |
| 1158 | + MultiByteToWideChar(CP_UTF8, 0, s, nlen, ws->s, size); |
| 1159 | + if (len != NULL) *len = size; |
| 1160 | + return ws->s; |
| 1161 | +} |
| 1162 | + |
| 1163 | +LUALIB_API const char *(luaL_convertwstring) (lua_State *L, const wchar_t *ws, size_t *len) |
| 1164 | +{ |
| 1165 | + int size, wlen; |
| 1166 | + luaL_Buffer buf; |
| 1167 | + char *s; |
| 1168 | + if (ws == NULL) { |
| 1169 | + if (len != NULL) *len = 0; |
| 1170 | + return NULL; |
| 1171 | + } |
| 1172 | + wlen = wcslen(ws); |
| 1173 | + size = WideCharToMultiByte(CP_UTF8, 0, ws, wlen, NULL, 0, NULL, NULL); |
| 1174 | + if (size == 0) { /* conversion failure */ |
| 1175 | + if (len != NULL) *len = 0; |
| 1176 | + return NULL; |
| 1177 | + } |
| 1178 | + s = luaL_buffinitsize(L, &buf, size); |
| 1179 | + WideCharToMultiByte(CP_UTF8, 0, ws, wlen, s, size, NULL, NULL); |
| 1180 | + luaL_pushresultsize(&buf, size); |
| 1181 | + if (len != NULL) *len = size; |
| 1182 | + return lua_tostring(L, -1); |
| 1183 | +} |
| 1184 | + |
| 1185 | +LUALIB_API const wchar_t *luaL_checkconvertlstring (lua_State *L, int idx, size_t *len) |
| 1186 | +{ |
| 1187 | + size_t nlen; |
| 1188 | + const char *s = luaL_checklstring(L, idx, &nlen); |
| 1189 | + const wchar_t *ws = luaL_convertlstring(L, s, nlen, len); |
| 1190 | + if (ws == NULL) luaL_error(L, "conversion failure"); |
| 1191 | + return ws; |
| 1192 | +} |
| 1193 | + |
| 1194 | +LUALIB_API const wchar_t *luaL_optconvertlstring (lua_State *L, int idx, const wchar_t *def, size_t *len) |
| 1195 | +{ |
| 1196 | + if (lua_isnoneornil(L, idx)) { |
| 1197 | + if (len != NULL) *len = (def ? wcslen(def) : 0); |
| 1198 | + return def; |
| 1199 | + } |
| 1200 | + return luaL_checkconvertlstring(L, idx, len); |
| 1201 | +} |
| 1202 | + |
| 1203 | +#endif |
| 1204 | +/* }====================================================== */ |
0 commit comments