ucommon
|
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00017 00028 #ifndef _UCOMMON_STRING_H_ 00029 #include <ucommon/string.h> 00030 #endif 00031 00032 #ifndef _UCOMMON_MEMORY_H_ 00033 #include <ucommon/memory.h> 00034 #endif 00035 00036 #ifndef _UCOMMON_BUFFER_H_ 00037 #include <ucommon/buffer.h> 00038 #endif 00039 00040 #ifndef _UCOMMON_SHELL_H_ 00041 #define _UCOMMON_SHELL_H_ 00042 00043 #ifdef _MSWINDOWS_ 00044 #define INVALID_PID_VALUE INVALID_HANDLE_VALUE 00045 #else 00046 #define INVALID_PID_VALUE -1 00047 #endif 00048 00049 #ifdef ERR 00050 #undef ERR 00051 #endif 00052 00053 namespace ucommon { 00054 00062 class __EXPORT shell : public mempager 00063 { 00064 private: 00065 char **_argv; 00066 unsigned _argc; 00067 char *_argv0; 00068 char *_exedir; 00069 LinkedObject *_syms; 00070 00071 class __LOCAL args : public OrderedObject 00072 { 00073 public: 00074 char *item; 00075 }; 00076 00077 class __LOCAL syms : public LinkedObject 00078 { 00079 public: 00080 const char *name; 00081 const char *value; 00082 }; 00083 00089 void collapse(LinkedObject *first); 00090 00094 void set0(char *argv0); 00095 00096 public: 00100 typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t; 00101 00105 typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t; 00106 00110 typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t; 00111 00115 typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t; 00116 00120 typedef enum { 00121 PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SERVICE_CONTROL, 00122 USER_HOME = USER_DEFAULTS + 3, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE, 00123 SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC, 00124 SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS, 00125 PROGRAM_TEMP} path_t; 00126 00130 typedef bool (*logproc_t)(loglevel_t level, const char *text); 00131 00135 typedef cpr_service_t mainproc_t; 00136 00140 typedef void (*exitproc_t)(void); 00141 00142 #ifdef _MSWINDOWS_ 00143 typedef HANDLE pid_t; 00144 #else 00145 00148 typedef int pid_t; 00149 #endif 00150 00157 static const char *errmsg(errmsg_t id); 00158 00165 static void errmsg(errmsg_t id, const char *text); 00166 00173 class __EXPORT errormap 00174 { 00175 public: 00176 inline errormap(errmsg_t id, const char *text) 00177 {shell::errmsg(id, text);} 00178 }; 00179 00187 class __EXPORT Option : public LinkedObject 00188 { 00189 public: 00190 char short_option; 00191 const char *long_option; 00192 const char *uses_option; 00193 const char *help_string; 00194 bool trigger_option; 00195 00203 Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL); 00204 00205 virtual ~Option(); 00206 00207 static LinkedObject *first(void); 00208 00213 void disable(void); 00214 00220 virtual const char *assign(const char *value) = 0; 00221 00222 static void reset(void); 00223 }; 00224 00232 class __EXPORT flagopt : public Option 00233 { 00234 private: 00235 unsigned counter; 00236 bool single; 00237 00238 virtual const char *assign(const char *value); 00239 00240 public: 00241 flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true); 00242 00243 inline operator bool() 00244 {return counter > 0;} 00245 00246 inline bool operator!() 00247 {return counter == 0;} 00248 00249 inline operator unsigned() 00250 {return counter;} 00251 00252 inline unsigned operator*() 00253 {return counter;} 00254 00255 inline void set(unsigned value = 1) 00256 {counter = value;} 00257 }; 00258 00264 class __EXPORT groupopt : public Option 00265 { 00266 private: 00267 virtual const char *assign(const char *value); 00268 00269 public: 00270 groupopt(const char *help); 00271 }; 00272 00279 class __EXPORT stringopt : public Option 00280 { 00281 private: 00282 bool used; 00283 00284 protected: 00285 const char *text; 00286 00287 virtual const char *assign(const char *value); 00288 00289 public: 00290 stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL); 00291 00292 inline void set(const char *string) 00293 {text = string;} 00294 00295 inline operator bool() 00296 {return used;} 00297 00298 inline bool operator!() 00299 {return !used;} 00300 00301 inline operator const char *() 00302 {return text;} 00303 00304 inline const char *operator*() 00305 {return text;} 00306 }; 00307 00314 class __EXPORT charopt : public Option 00315 { 00316 private: 00317 bool used; 00318 00319 protected: 00320 char code; 00321 00322 virtual const char *assign(const char *value); 00323 00324 public: 00325 charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' '); 00326 00327 inline void set(char value) 00328 {code = value;} 00329 00330 inline operator bool() 00331 {return used;} 00332 00333 inline bool operator!() 00334 {return !used;} 00335 00336 inline operator char() 00337 {return code;} 00338 00339 inline char operator*() 00340 {return code;} 00341 }; 00342 00349 class __EXPORT numericopt : public Option 00350 { 00351 private: 00352 bool used; 00353 00354 protected: 00355 long number; 00356 00357 virtual const char *assign(const char *value); 00358 00359 public: 00360 numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0); 00361 00362 inline void set(long value) 00363 {number = value;} 00364 00365 inline operator bool() 00366 {return used;} 00367 00368 inline bool operator!() 00369 {return !used;} 00370 00371 inline operator long() 00372 {return number;} 00373 00374 inline long operator*() 00375 {return number;} 00376 }; 00377 00386 class __EXPORT counteropt : public Option 00387 { 00388 private: 00389 bool used; 00390 00391 protected: 00392 long number; 00393 00394 virtual const char *assign(const char *value); 00395 00396 public: 00397 counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0); 00398 00399 inline void set(long value) 00400 {number = value;} 00401 00402 inline operator bool() 00403 {return used;} 00404 00405 inline bool operator!() 00406 {return !used;} 00407 00408 inline operator long() 00409 {return number;} 00410 00411 inline long operator*() 00412 {return number;} 00413 }; 00414 00422 shell(const char *string, size_t pagesize = 0); 00423 00432 shell(int argc, char **argv, size_t pagesize = 0); 00433 00438 shell(size_t pagesize = 0); 00439 00440 static void setNumeric(numeric_t); 00441 00442 static long getNumeric(void); 00443 00447 static void help(void); 00448 00456 static int system(const char *command, const char **env = NULL); 00457 00464 static int systemf(const char *format, ...) __PRINTF(1,2); 00465 00470 static void relocate(const char *argv0); 00471 00478 static String path(path_t id); 00479 00484 static String userid(void); 00485 00492 static String path(path_t id, const char *directory); 00493 00499 static String path(String& prefix, const char *directory); 00500 00512 static void bind(const char *name); 00513 00523 static void rebind(const char *name = NULL); 00524 00530 char **parse(const char *string); 00531 00540 void parse(int argc, char **argv); 00541 00549 const char *env(const char *name, const char *value = NULL); 00550 00551 inline const char *getenv(const char *name, const char *value = NULL) 00552 {return env(name, value);} 00553 00560 const char *get(const char *name, const char *value = NULL); 00561 00562 inline const char *getsym(const char *name, const char *value = NULL) 00563 {return get(name, value);} 00564 00570 void set(const char *name, const char *value); 00571 00572 inline void setsym(const char *name, const char *value) 00573 {return set(name, value);} 00574 00580 bool is_sym(const char *name); 00581 00587 char *getargv0(char **argv); 00588 00596 char **getargv(char **argv); 00597 00604 void restart(char *argv0, char **argv, char **list); 00605 00609 inline const char *argv0() const 00610 {return _argv0;} 00611 00615 inline const char *execdir() const 00616 {return _exedir;} 00617 00622 static void error(const char *format, ...) __PRINTF(1, 2); 00623 00629 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3); 00630 00631 00637 static inline int condition(bool test, int exitcode) 00638 { return (test) ? exitcode : 0;} 00639 00645 static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3); 00646 00652 static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3); 00653 00659 static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3); 00660 00668 static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL); 00669 00674 static size_t printf(const char *format, ...) __PRINTF(1, 2); 00675 00676 static size_t readln(char *address, size_t size); 00677 00678 static size_t writes(const char *string); 00679 00680 static size_t read(String& string); 00681 00682 inline static size_t write(String& string) 00683 {return writes(string.c_str());} 00684 00690 inline unsigned argc(void) const 00691 {return _argc;} 00692 00699 inline char **argv(void) const 00700 {return _argv;} 00701 00707 inline const char *operator[](unsigned offset) 00708 {return _argv[offset];} 00709 00710 static void exiting(exitproc_t); 00711 00715 void detach(mainproc_t mainentry = (mainproc_t)NULL); 00716 00720 void restart(void); 00721 00733 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL); 00734 00743 static void priority(int pri = 1); 00744 00754 static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL); 00755 00760 static void release(int exit_code = 0); 00761 00767 static int wait(shell::pid_t pid); 00768 00774 static int cancel(shell::pid_t pid); 00775 00780 inline unsigned operator()(void) 00781 {return _argc;} 00782 00795 static const char *text(const char *string); 00796 00806 static const char *texts(const char *singular, const char *plural, unsigned long count); 00807 00813 static unsigned count(char **argv); 00814 00815 #ifdef _MSWINDOWS_ 00816 00817 static inline fd_t input(void) 00818 {return GetStdHandle(STD_INPUT_HANDLE);} 00819 00820 static inline fd_t output(void) 00821 {return GetStdHandle(STD_OUTPUT_HANDLE);} 00822 00823 static inline fd_t error(void) 00824 {return GetStdHandle(STD_ERROR_HANDLE);} 00825 00826 #else 00827 static inline fd_t input(void) 00828 {return 0;} 00829 00830 static inline fd_t output(void) 00831 {return 1;} 00832 00833 static inline fd_t error(void) 00834 {return 2;} 00835 #endif 00836 00837 static int inkey(const char *prompt = NULL); 00838 00839 static char *getpass(const char *prompt, char *buffer, size_t size); 00840 00841 static char *getline(const char *prompt, char *buffer, size_t size); 00842 00843 }; 00844 00848 typedef shell shell_t; 00849 00853 #undef _TEXT 00854 #undef _STR 00855 #define _STR(x) (const char *)(x) 00856 00864 inline const char *_TEXT(const char *s) 00865 {return shell::text(s);} 00866 00867 } // namespace ucommon 00868 00869 #endif