root/lang/objective-cplusplus/i3/trunk/src/os-windows/Os.cpp @ 34041

Revision 34041, 10.9 kB (checked in by saturday06, 5 years ago)

oajiofda

Line 
1#include <PrecompiledHeaders.h>
2#include "Common.h"
3#include <malloc.h>
4
5namespace i3
6{
7
8TCHAR config_dir_path[WINDOWS_MAX_PATH] = {};
9
10void init_config_dir_path()
11{
12#ifndef _WIN32_WCE
13    LPITEMIDLIST pidl = NULL;
14    IMalloc* pMalloc = NULL;
15
16    if (SHGetMalloc(&pMalloc) != S_OK)
17    {
18        // error
19        return;
20    }
21
22    if (FAILED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl)))
23    {
24        // error
25        pMalloc->Release();
26        return;
27    }
28
29    if (SHGetPathFromIDList(pidl, config_dir_path) != TRUE)
30    {
31        // error
32        pMalloc->Free(pidl);
33        pMalloc->Release();
34        return;
35    }
36
37    pMalloc->Free(pidl);
38    pMalloc->Release();
39
40    if (_tcscat_s(config_dir_path, _countof(config_dir_path), _T("\\") _T(PACKAGE_NAME)) != 0)
41    {
42        memset(config_dir_path, 0, sizeof(config_dir_path));
43        return;
44    }
45
46    //TODO:
47    //if (!PathFileExists(config_dir_path) && _tmkdir(config_dir_path)) {
48    //    // error
49    //    memset(config_dir_path, 0, sizeof(config_dir_path));
50    //    return;
51    //}// else if (!PathIsDirectory(config_dir_path)) {
52    //    return;
53    //}
54#endif
55}
56
57const TCHAR* get_config_dir_path()
58{
59    if (_tcsnlen(config_dir_path, _countof(config_dir_path)) == 0)
60    {
61        return NULL;
62    }
63    return config_dir_path;
64}
65
66
67exit_status init_os_global_data(int argc, char** argv)
68{
69    //_fmode = _O_BINARY;
70    //_set_fmode(_O_BINARY);
71
72    if (!i3::hInstance)
73    {
74        i3::hInstance = GetModuleHandle(NULL);
75    }
76
77#ifdef ENABLE_NLS
78#undef LOCALEDIR
79    using namespace std;
80
81    if (setlocale(LC_ALL, "") == NULL)
82    {
83        return 0;
84    }
85
86    TCHAR locale_dir[WINDOWS_MAX_PATH] = {};
87    DWORD result = GetModuleFileName(
88                       GetModuleHandle(NULL),
89                       locale_dir,
90                       _countof(locale_dir) - 1);
91    if (result == 0 || result == _countof(locale_dir) - 1)
92    {
93        return 0;
94    }
95
96    if (PathRemoveFileSpec(locale_dir) == FALSE)
97    {
98        return 0;
99    }
100
101    const TCHAR more[] = _T("locale");
102    if (_countof(locale_dir) <= _tcslen(more) + _tcslen(locale_dir) + 1)
103    {
104        return 0;
105    }
106
107    if (PathAppend(locale_dir, more) == FALSE)
108    {
109        return 0;
110    }
111
112#if defined(UNICODE) || defined(_UNICODE)
113#ifdef HAVE_WBINDTEXTDOMAIN
114    wbindtextdomain(PACKAGE_NAME, locale_dir);
115#else
116    {
117        int acp = GetACP();
118        int num_elements = WideCharToMultiByte(acp, 0, locale_dir, -1, NULL, 0, 0, 0);
119        if (num_elements == 0)
120        {
121            return 0;
122        }
123
124        char* locale_dir8 = (char*)calloc(num_elements, 1);
125        if (!locale_dir8)
126        {
127            return 0;
128        }
129
130        if (WideCharToMultiByte(acp, 0, locale_dir, -1, locale_dir8, num_elements, 0, 0))
131        {
132            bindtextdomain(PACKAGE_NAME, locale_dir8);
133        }
134        free (locale_dir8);
135    }
136#endif
137#else
138    bindtextdomain(PACKAGE_NAME, locale_dir);
139#endif
140    textdomain(PACKAGE_NAME);
141#endif
142
143
144#ifdef HAVE_POPT_H
145#if defined(UNICODE) || defined(_UNICODE)
146    return check_args();
147#else
148    return execute_popt(argc, argv, boost::lambda::constant(stdout));
149#endif
150#endif
151
152    return 0;
153}
154extern HINSTANCE hInstance;
155}
156
157int APIENTRY _tWinMain(HINSTANCE hInstance,
158                       HINSTANCE hPrevInstance,
159                       LPTSTR    lpCmdLine,
160                       int       nCmdShow)
161{
162    UNREFERENCED_PARAMETER(hPrevInstance);
163    UNREFERENCED_PARAMETER(lpCmdLine);
164    UNREFERENCED_PARAMETER(nCmdShow);
165
166    i3::hInstance = hInstance;
167
168#ifdef __GNUC__
169    MessageBoxA(NULL, "GCC de WinMain !", "GCC de WinMain !", MB_OK);
170#endif
171
172    int main(int argc,char *argv[]);
173    return main(0, 0);
174}
175
176// -----------------------------------------------------------------
177//
178// argument
179//
180// -----------------------------------------------------------------
181//#ifndef _MSC_VER
182#ifdef HAVE_POPT_H
183#include <boost/spirit/include/classic.hpp>
184#include <boost/bind.hpp>
185#include "Utf8ToUtf16Stream.h"
186
187using namespace boost::spirit::classic;
188
189namespace i3
190{
191namespace windows_execute_popt
192{
193
194template <int Mode, typename Result>
195struct calc : public grammar<calc<Mode, Result> >
196{
197    Result& data;
198    calc(Result& data) : data(data) {}
199    void operator()(const char* first, const char* last) const;
200    template<typename S> struct definition
201    {
202        rule<S> args, raw, quated;
203        definition(const calc<Mode, Result>& self)
204        {
205            args   = (*space_p) >> (+(quated | raw))[self] >> (+space_p) >> args;
206            quated = ch_p('"') >> (*((ch_p('\\') >> (anychar_p | str_p("\r\n"))) | (anychar_p - ch_p('"')          ))) >> (ch_p('"') | end_p);
207            raw    =              (+((ch_p('\\') >> (anychar_p | str_p("\r\n"))) | (anychar_p - ch_p('"') - space_p)));
208        }
209        const rule<S>& start() const
210        {
211            return args;
212        }
213    };
214};
215
216template <>
217void calc<0, size_t>::operator()(const char* first, const char* last) const
218{
219    data++;
220}
221
222template <>
223void calc<1, size_t*>::operator()(const char* first, const char* last) const
224{
225    *data = last - first + 1;
226    data++;
227}
228
229struct calc2 : public grammar<calc2>
230{
231    char*& data;
232    calc2(char*& data) : data(data) {}
233    void operator()(char c) const
234    {
235        *data = c;
236        data++;
237    }
238    template<typename S> struct definition
239    {
240        rule<S> args;
241        definition(const calc2& self)
242        {
243            args   = (+((ch_p("\\") >> anychar_p[self]) | ch_p('"') | anychar_p[self]));
244        }
245        const rule<S>& start() const
246        {
247            return args;
248        }
249    };
250};
251
252void calc2_helper(char* got, char* cleaned)
253{
254    calc2 c(cleaned);
255    parse_info<> r = boost::spirit::classic::parse(got, c);
256}
257
258template <>
259void calc<2, char**>::operator()(const char* first, const char* last) const
260{
261    size_t buf_size = last - first + 1;
262    char* got = NULL;
263    char* cleaned = NULL;
264
265    memset((void*)(*data), 0, buf_size);
266
267    if (buf_size > _ALLOCA_S_THRESHOLD)
268    {
269        data++;
270        return;
271    }
272
273    __try
274    {
275        got = (char*)alloca(buf_size);
276    } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
277                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
278    {
279        data++;
280        return;
281    }
282
283    __try
284    {
285        cleaned = (char*)alloca(buf_size);
286    } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
287                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
288    {
289        data++;
290        return;
291    }
292
293    char* cleaned_begin = cleaned;
294    memset(got, 0, buf_size);
295    memset(cleaned, 0, buf_size);
296    memcpy(got, first, last - first);
297
298    calc2_helper(got, cleaned);
299
300    memcpy((void*)(*data), cleaned_begin, buf_size);
301    data++;
302}
303
304size_t get_argc(const char* line)
305{
306    size_t argc = 0; // must zero.
307    calc<0, size_t> c(argc);
308    parse_info<> r = parse(line, c);
309
310    return argc;
311}
312
313void get_size_list(const char* line,
314                   size_t* size_list,
315                   size_t argc)
316{
317
318    calc<1, size_t*> c(size_list);
319    parse_info<> r = parse(line, c);
320}
321
322void get_argv(const char* line,
323              const size_t* size_list,
324              char** argv, size_t argc)
325{
326
327    calc<2, char**> c(argv);
328    parse_info<> r = parse(line, c);
329}
330
331struct fp_func
332{
333    Utf8ToUtf16Stream& s;
334    FILE* operator()()
335    {
336        return s.get();
337    }
338};
339
340exit_status check_args2(int argc, char** argv)
341{
342#if defined(UNICODE) || defined(_UNICODE)
343#ifdef ENABLE_NLS
344    Utf8ToUtf16Stream s(stderr);
345    struct fp_func fp_func = {s};
346    bind_textdomain_codeset(PACKAGE_NAME,"UTF-8");
347    exit_status e = i3::execute_popt((size_t)argc, (const char**)argv, fp_func);
348    bind_textdomain_codeset(PACKAGE_NAME,"UTF-16LE");
349#else
350    exit_status e = i3::execute_popt((size_t)argc, (const char**)argv, boost::lambda::constant(stdout));
351#endif
352#else
353#ifdef ENABLE_NLS
354    const char* codeset = bind_textdomain_codeset(PACKAGE_NAME,NULL);
355    bind_textdomain_codeset(PACKAGE_NAME,"UTF-8");
356    exit_status e = i3::execute_popt((size_t)argc, (const char**)argv, boost::lambda::constant(stdout));
357    bind_textdomain_codeset(PACKAGE_NAME,codeset);
358#else
359    exit_status e = i3::execute_popt((size_t)argc, (const char**)argv, boost::lambda::constant(stdout));
360#endif
361#endif
362    return e;
363}
364
365}
366
367
368#if defined(UNICODE) || defined(_UNICODE)
369exit_status check_args()
370{
371    using namespace i3::windows_execute_popt;
372
373    // --------------------------------------------
374    // phase 1
375    size_t argc = 0;
376    UTF16LE_TO_UTF8_ALLOCA(GetCommandLine(), line);
377    if (!line)
378    {
379        return 1;
380    }
381    {
382        argc = get_argc(line);
383        if (argc == 0 || argc == 1)
384        {
385            return 0;
386        }
387    }
388
389    // --------------------------------------------
390    // phase 2
391    size_t* size_list = NULL;
392    {
393        const size_t size_list_bytes = argc*sizeof(size_t);
394        if (size_list_bytes > _ALLOCA_S_THRESHOLD)
395        {
396            return 1;
397        }
398        __try
399        {
400            size_list = (size_t*)alloca(size_list_bytes);
401        } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
402                    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
403        {
404            return 1;
405        }
406    }
407
408    // --------------------------------------------
409    // phase 3
410    char** argv = NULL;
411    {
412        get_size_list(line, size_list, argc);
413        const size_t argv_bytes = argc*sizeof(char*);
414        if (argv_bytes > _ALLOCA_S_THRESHOLD)
415        {
416            return 1;
417        }
418        __try
419        {
420            argv = (char**)alloca(argv_bytes);
421        } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
422                    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
423        {
424            return 1;
425        }
426    }
427
428    // --------------------------------------------
429    // phase 4
430    {
431        size_t argv_total_bytes = 0;
432        for (size_t i = 0; i < argc; i++)
433        {
434            argv_total_bytes += size_list[i];
435        }
436        if (argv_total_bytes > _ALLOCA_S_THRESHOLD)
437        {
438            return 1;
439        }
440        char* argv_pool = NULL;
441        __try
442        {
443            argv_pool = (char*)alloca(argv_total_bytes);
444        } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
445                    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
446        {
447            return 1;
448        }
449        for (size_t i = 0; i < argc; i++)
450        {
451            argv[i] = argv_pool;
452            argv_pool += size_list[i];
453        }
454        get_argv(line, size_list, argv, argc);
455    }
456    return check_args2(argc, argv);
457}
458#endif
459
460}
461#endif
Note: See TracBrowser for help on using the browser.