root/lang/objective-cplusplus/i3/trunk/src/Common.h @ 35842

Revision 35623, 13.2 kB (checked in by saturday06, 4 years ago)

adfadfadfdf

Line 
1#pragma once
2
3//TODO: config.h
4#ifdef HAVE_CONFIG_H
5#  include "../config.h"
6#else
7#  define PACKAGE_NAME "i3"
8//#  define PACKAGE_VERSION "1.0"
9#  ifndef _WIN32_WCE
10#    define ENABLE_NLS 1
11#  endif
12#  define ICONV_CONST const
13#  define HAVE_PUTENV 1
14//#  define HAVE_WBINDTEXTDOMAIN
15#endif
16
17#ifdef HAVE_MALLOC_H
18#include <malloc.h>
19#endif
20
21#include <iconv.h>
22
23#ifdef ENABLE_NLS
24#  include <libintl.h>
25#  ifdef MIL_OS_WINDOWS
26#    undef printf
27#    undef asprintf
28#    undef fprintf
29#    undef fwprintf
30#    undef sprintf
31#    undef snprintf
32#    undef snwprintf
33#    undef swprintf
34#    undef vprintf
35#    undef vasprintf
36#    undef vfprintf
37#    undef vfwprintf
38#    undef vsprintf
39#    undef vsnprintf
40#    undef vsnwprintf
41#    undef vswprintf
42#  endif
43#endif
44
45//#include <argtable2.h>
46#ifdef HAVE_POPT_H
47#include <popt.h>
48#endif
49
50// countof macro
51#ifndef _countof
52#  define _countof(array) (sizeof(array)/sizeof((array)[0]))
53#endif
54
55// mil
56#include <mil/Mil.h>
57#include <mil/Atomic.h>
58#include <mil/Thread.h>
59#include <mil/DoubleBuffer.h>
60
61namespace i3 {
62struct exit_status {
63    exit_status() : code(0), exit(false) {}
64    exit_status(int code) : code(code), exit(code ? true : false) {}
65    operator bool() {
66        return exit;
67    }
68    static exit_status exit_when_special_argument() {
69        exit_status result;
70        result.code = 0;
71        result.exit = true;
72        return result;
73    }
74    int code;
75private:
76    bool exit;
77};
78}
79
80#ifdef MIL_OS_WINDOWS
81#  include "os-windows/Os.h"
82#else
83#  include "os-unix/Os.h"
84#endif
85
86#ifdef MIL_GUI_WINDOWS
87#  include "gui-windows/Gui.h"
88#elif MIL_GUI_COCOA
89#  include "gui-cocoa/Gui.h"
90#else
91#  include "gui-cocoa/Gui.h"
92#endif
93
94namespace i3 {
95int global_loop();
96exit_status init_os_global_data(int argc, char** argv);
97exit_status init_gui_global_data(int argc, char** argv);
98//void alert(const TCHAR* message);
99void alert(string message);
100int my_setenv(const char * name, const char * value);
101}
102
103// NO include "Mediator.h"
104
105#ifndef _MSC_VER
106#define __try
107#define __except(expression) if (false)
108#endif
109
110#define UTF8_TO_UTF16LE_ALLOCA(data8, data16)                           \
111    wchar_t* data16 = NULL;                                             \
112    for (;;) {                                                          \
113        const char* check = data8; check;                               \
114        unsigned int num_elements = MultiByteToWideChar(CP_UTF8, 0, data8, -1, NULL, 0); \
115        if (num_elements == 0) {                                        \
116            break;                                                      \
117        }                                                               \
118        const size_t data16_bytes = num_elements*sizeof(wchar_t);       \
119        if (data16_bytes > _ALLOCA_S_THRESHOLD) {                       \
120            data16 = NULL;                                              \
121            break;                                                      \
122        }                                                               \
123        __try {                                                         \
124            data16 = (wchar_t*)alloca(data16_bytes);                    \
125        } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?       \
126                    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { \
127            data16 = NULL;                                              \
128            break;                                                      \
129     }                                                               \
130        if (0 == MultiByteToWideChar(CP_UTF8, 0, data8, -1, data16, num_elements)) { \
131            data16 = NULL;                                              \
132            break;                                                      \
133        }                                                               \
134        break;                                                          \
135    }
136
137#define UTF16LE_TO_UTF8_ALLOCA(data16, data8)                           \
138    char* data8 = NULL;                                                 \
139    for (;;) {                                                          \
140        const wchar_t* check = data16; check;                           \
141        unsigned int num_elements = WideCharToMultiByte( CP_UTF8, 0, data16, -1, NULL, 0, 0, 0); \
142        if (num_elements == 0 || num_elements > _ALLOCA_S_THRESHOLD) {  \
143            break;                                                      \
144        }                                                               \
145        __try {                                                         \
146            data8 = (char*)alloca(num_elements*sizeof(char));           \
147        } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?       \
148                    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { \
149            data8 = NULL;                                               \
150            break;                                                      \
151     }                                                               \
152        if (0 == WideCharToMultiByte(CP_UTF8, 0, data16, -1, data8, num_elements, 0, 0)) { \
153            data8 = NULL;                                               \
154            break;                                                      \
155        }                                                               \
156        break;                                                          \
157    }
158
159
160#undef WINDOWS_SEH_TRY
161#undef WINDOWS_SEH_EXCEPT
162
163#ifndef HAVE_POPT_H
164namespace i3 {
165template <typename FP_FUNCTER>
166inline static exit_status execute_popt(int argc, char** argv, FP_FUNCTER fp) {
167    return 0;
168}
169}
170#else
171namespace i3 {
172
173template <typename FP_FUNCTER>
174int usage(poptContext optCon, int exitcode, const char *error, const char *addl, FP_FUNCTER fp) {
175    poptPrintUsage(optCon, fp(), 0);
176    if (error) {
177        fprintf(fp(), "%s: %s0", error, addl);
178    }
179    return exitcode;
180}
181
182template <typename FP_FUNCTER>
183inline static exit_status execute_popt(int argc, char** argv, FP_FUNCTER fp) {
184    int c;            /* used for argument parsing */
185    int i = 0;        /* used for tracking options */
186    int speed = 0;    /* used in argument parsing to set speed */
187    int raw = 0;      /* raw mode? */
188    int version = 0;
189    int j;
190    char buf[BUFSIZ + 1];
191    poptContext optCon;   /* context for parsing command-line options */
192
193
194    struct poptOption optionsTable[] = {
195        /*{ "longname", "shortname", argInfo,      *arg,   int val, description, argment description} */
196        { "version",  'v',         0,            &version, 0,     "version" },
197        { "bps",      'b',         POPT_ARG_INT, &speed,   0,     "signaling rate in bits-per-second", "BPS" },
198        { "crnl",     'c',         0,            0,      'c',     "expand cr characters to cr/lf sequences" },
199        { "hwflow",   'h',         0,            0,      'h',     "use hardware (RTS/CTS) flow control" },
200        { "noflow",   'n',         0,            0,      'n',     "use no flow control" },
201        { "raw",      'r',         0,            &raw,   0,       "don't perform any character conversions" },
202        { "swflow",   's',         0,            0,      's',     "use software (XON/XOF) flow control" } ,
203        POPT_AUTOHELP
204        { "aswflow",   'x',        0,            0,      'x',     "XXXXXXXXXXXXXXXXXXXXXX" } ,
205        { NULL, 0, 0, NULL, 0 }
206    };
207    /*
208      $ a.out --help
209
210      Usage: a.out [OPTIONS]*
211      -b, --bps=BPS   signaling rate in bits-per-second
212      -c, --crnl      expand cr characters to cr/lf sequences
213      -h, --hwflow    use hardware (RTS/CTS) flow control
214      -n, --noflow    use no flow control
215      -r, --raw       don't perform any character conversions
216      -s, --swflow    use software (XON/XOF) flow control
217
218      Help options
219      -?, --help      Show this help message
220      --usage         Display brief usage message
221    */
222
223    const char** argv2 = const_cast<const char**>(argv);
224    optCon = poptGetContext(NULL, argc, argv2, optionsTable, 0);
225    poptSetOtherOptionHelp(optCon, "[OPTIONS]* <port>");
226
227    if (argc < 2) {
228        //poptPrintUsage(optCon, fp(), 0);
229        //return exit_status::exit_when_special_argument();
230        return 0;
231    }
232
233    // Now do options processing, get portname
234    while ((c = poptGetNextOpt(optCon)) >= 0) {
235        switch (c) {
236        case 'c':
237            buf[i++] = 'c';
238            break;
239        case 'h':
240            buf[i++] = 'h';
241            break;
242        case 's':
243            buf[i++] = 's';
244            break;
245        case 'n':
246            buf[i++] = 'n';
247            break;
248        }
249    }
250
251    const char* portname = poptGetArg(optCon);
252
253    if (version) {
254        fprintf(fp(), PACKAGE_NAME " version " PACKAGE_VERSION "\n");
255        goto normal_exit;
256    }
257
258    if ((portname == NULL) || !(poptPeekArg(optCon) == NULL)) {
259        usage(optCon, 1, "Specify a single port", ".e.g., /dev/cua0\n", fp);
260    }
261    if (c < -1) {
262        /* an error occurred during option processing */
263        fprintf(fp(), "%s: %s\n",
264                poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
265                poptStrerror(c));
266        goto error_exit;
267    }
268    fprintf(fp(), "Options  chosen: ");
269    for (j = 0; j < i ; j++) {
270        fprintf(fp(), "-%c ", buf[j]);
271    }
272    if (raw) {
273        fprintf(fp(), "-r ");
274    }
275    if (speed) {
276        fprintf(fp(), "-b %d ", speed);
277    }
278    fprintf(fp(), "\nPortname chosen: %s\n", portname);
279
280    poptFreeContext(optCon);
281    return 0;
282normal_exit:
283    poptFreeContext(optCon);
284    return exit_status::exit_when_special_argument();
285error_exit:
286    poptFreeContext(optCon);
287    return 1;
288
289    /*
290      struct arg_lit  *list    = arg_lit0("lL",NULL,                      gettext("list files"));
291      struct arg_lit  *recurse = arg_lit0("R",NULL,                       gettext("recurse through subdirectories"));
292      struct arg_int  *repeat  = arg_int0("k","scalar",NULL,              gettext("define scalar value k (default is 3)"));
293      struct arg_str  *defines = arg_strn("D","define","MACRO",0,argc+2,  gettext("macro definitions"));
294      struct arg_file *outfile = arg_file0("o",NULL,"<output>",           gettext("output file (default is \"-\")"));
295      struct arg_lit  *verbose = arg_lit0("v","verbose,debug",            gettext("verbose messages"));
296      struct arg_lit  *help    = arg_lit0(NULL,"help",                    gettext("print this help and exit"));
297      struct arg_lit  *version = arg_lit0(NULL,"version",                 gettext("print version information and exit"));
298      //struct arg_file *infiles = arg_filen(NULL,NULL,NULL,1,argc+2,       "input file(s)");
299      struct arg_end  *end     = arg_end(20);
300      //void* argtable[] = {list,recurse,repeat,defines,outfile,verbose,help,version,infiles,end};
301      void* argtable[] = {list,recurse,repeat,defines,outfile,verbose,help,version,end};
302      int nerrors = 0;
303
304
305      // verify the argtable[] entries were allocated sucessfully
306      if (arg_nullcheck(argtable) != 0)
307      {
308      // NULL entries were detected, some allocations must have failed
309      fprintf(fp(), PACKAGE_NAME ": insufficient memory\n");
310      goto error_exit;
311      }
312
313      // set any command line default values prior to parsing
314      repeat->ival[0]=3;
315      outfile->filename[0]="-";
316
317      // Parse the command line as defined by argtable[]
318      nerrors = arg_parse(argc,argv,argtable);
319
320      // special case: '--help' takes precedence over error reporting
321      if (help->count > 0)
322      {
323      arg_print_syntax(fp(),argtable,"\n");
324      arg_print_glossary(fp(),argtable,"  %-25s %s\n");
325      goto normal_exit;
326      }
327
328      // special case: '--version' takes precedence error reporting
329      if (version->count > 0)
330      {
331      fprintf(fp(), PACKAGE_NAME " version " PACKAGE_VERSION "\n");
332      goto normal_exit;
333      }
334
335      // If the parser returned any errors then display them and exit
336      if (nerrors > 0)
337      {
338      // Display the error details contained in the arg_end struct.
339      arg_print_errors(fp(), end, PACKAGE_NAME);
340      goto error_exit;
341      }
342
343      // normal case: take the command line options at face value
344      //    exitcode = mymain(list->count, recurse->count, repeat->ival[0],
345      //                      defines->sval, defines->count,
346      //                      outfile->filename[0], verbose->count,
347      //                      infiles->filename, infiles->count);
348
349
350      arg_freetable(argtable, _countof(argtable));
351      return 0;
352      normal_exit:
353      arg_freetable(argtable, _countof(argtable));
354      return exit_status::exit_when_special_argument();
355      error_exit:
356      arg_freetable(argtable, _countof(argtable));
357    */
358    return 1;
359}
360}
361
362#endif
363
364namespace i3 {
365
366struct stdout_functer {
367    FILE* operator()() {
368        return stdout;
369    }
370};
371
372inline static exit_status execute_popt(size_t argc, char** argv) {
373    stdout_functer f;
374    return execute_popt(argc, argv, f);
375}
376}
377
378int main(int argc, char** argv);
379
Note: See TracBrowser for help on using the browser.