00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 NAMESPACE_UCOMMON
00050
00058 class __EXPORT shell : public mempager
00059 {
00060 private:
00061 char **_argv;
00062 unsigned _argc;
00063 char *_argv0;
00064 LinkedObject *_syms;
00065
00066 static const char *domain;
00067
00068 class __LOCAL args : public OrderedObject
00069 {
00070 public:
00071 char *item;
00072 };
00073
00074 class __LOCAL syms : public LinkedObject
00075 {
00076 public:
00077 const char *name;
00078 const char *value;
00079 };
00080
00086 void collapse(LinkedObject *first);
00087
00091 void set0(char *argv0);
00092
00093 public:
00097 typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE} errmsg_t;
00098
00102 typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG} logmode_t;
00103
00107 typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
00108
00112 typedef bool (*logproc_t)(loglevel_t level, const char *text);
00113
00117 typedef void (*downproc_t)(bool reload);
00118
00119 #ifdef _MSWINDOWS_
00120 typedef HANDLE pid_t;
00121 #else
00122
00125 typedef int pid_t;
00126 #endif
00127
00131 typedef enum {RD = BufferProtocol::BUF_RD, WR = BufferProtocol::BUF_WR, RDWR = BufferProtocol::BUF_RDWR} pmode_t;
00132
00141 class __EXPORT pipeio
00142 {
00143 protected:
00144 friend class shell;
00145
00149 pipeio();
00150
00160 int spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00161
00166 int wait(void);
00167
00173 int cancel(void);
00174
00183 size_t read(void *address, size_t size);
00184
00193 size_t write(const void *address, size_t size);
00194
00195 pid_t pid;
00196 fd_t input, output;
00197 int perror, presult;
00198 };
00199
00206 class __EXPORT iobuf : public BufferProtocol, private pipeio
00207 {
00208 protected:
00209 friend class shell;
00210
00211 int ioerror;
00212
00213 virtual int _err(void) const;
00214 virtual void _clear(void);
00215
00216 virtual size_t _push(const char *address, size_t size);
00217 virtual size_t _pull(char *address, size_t size);
00218
00219 public:
00225 iobuf(size_t size = 0);
00226
00237 iobuf(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00238
00243 ~iobuf();
00244
00253 void open(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00254
00259 void close(void);
00260
00265 void cancel(void);
00266 };
00267
00271 typedef iobuf io_t;
00272
00276 typedef pipeio *pipe_t;
00277
00284 static const char *errmsg(errmsg_t id);
00285
00292 static void errmsg(errmsg_t id, const char *text);
00293
00300 class __EXPORT errormap
00301 {
00302 public:
00303 inline errormap(errmsg_t id, const char *text)
00304 {shell::errmsg(id, text);};
00305 };
00306
00314 class __EXPORT Option : public OrderedObject
00315 {
00316 private:
00317 static OrderedIndex index;
00318
00319 public:
00320 char short_option;
00321 const char *long_option;
00322 const char *uses_option;
00323 const char *help_string;
00324 bool trigger_option;
00325
00333 Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
00334
00335 virtual ~Option();
00336
00337 inline static LinkedObject *first(void)
00338 {return index.begin();};
00339
00344 void disable(void);
00345
00351 virtual const char *assign(const char *value) = 0;
00352
00353 inline static void reset(void)
00354 {index.reset();};
00355 };
00356
00364 class __EXPORT flagopt : public Option
00365 {
00366 private:
00367 unsigned counter;
00368 bool single;
00369
00370 virtual const char *assign(const char *value);
00371
00372 public:
00373 flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00374
00375 inline operator bool()
00376 {return counter > 0;};
00377
00378 inline bool operator!()
00379 {return counter == 0;};
00380
00381 inline operator unsigned()
00382 {return counter;};
00383
00384 inline unsigned operator*()
00385 {return counter;};
00386
00387 inline void set(unsigned value = 1)
00388 {counter = value;};
00389 };
00390
00396 class __EXPORT groupopt : public Option
00397 {
00398 private:
00399 virtual const char *assign(const char *value);
00400
00401 public:
00402 groupopt(const char *help);
00403 };
00404
00411 class __EXPORT stringopt : public Option
00412 {
00413 private:
00414 bool used;
00415
00416 protected:
00417 const char *text;
00418
00419 virtual const char *assign(const char *value);
00420
00421 public:
00422 stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00423
00424 inline void set(const char *string)
00425 {text = string;};
00426
00427 inline operator bool()
00428 {return used;};
00429
00430 inline bool operator!()
00431 {return !used;};
00432
00433 inline operator const char *()
00434 {return text;};
00435
00436 inline const char *operator*()
00437 {return text;};
00438 };
00439
00446 class __EXPORT charopt : public Option
00447 {
00448 private:
00449 bool used;
00450
00451 protected:
00452 char code;
00453
00454 virtual const char *assign(const char *value);
00455
00456 public:
00457 charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00458
00459 inline void set(char value)
00460 {code = value;};
00461
00462 inline operator bool()
00463 {return used;};
00464
00465 inline bool operator!()
00466 {return !used;};
00467
00468 inline operator char()
00469 {return code;};
00470
00471 inline char operator*()
00472 {return code;};
00473 };
00474
00481 class __EXPORT numericopt : public Option
00482 {
00483 private:
00484 bool used;
00485
00486 protected:
00487 long number;
00488
00489 virtual const char *assign(const char *value);
00490
00491 public:
00492 numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00493
00494 inline void set(long value)
00495 {number = value;};
00496
00497 inline operator bool()
00498 {return used;};
00499
00500 inline bool operator!()
00501 {return !used;};
00502
00503 inline operator long()
00504 {return number;};
00505
00506 inline long operator*()
00507 {return number;};
00508 };
00509
00518 class __EXPORT counteropt : public Option
00519 {
00520 private:
00521 bool used;
00522
00523 protected:
00524 long number;
00525
00526 virtual const char *assign(const char *value);
00527
00528 public:
00529 counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00530
00531 inline void set(long value)
00532 {number = value;};
00533
00534 inline operator bool()
00535 {return used;};
00536
00537 inline bool operator!()
00538 {return !used;};
00539
00540 inline operator long()
00541 {return number;};
00542
00543 inline long operator*()
00544 {return number;};
00545 };
00546
00554 shell(const char *string, size_t pagesize = 0);
00555
00564 shell(int argc, char **argv, size_t pagesize = 0);
00565
00570 shell(size_t pagesize = 0);
00571
00575 static void help(void);
00576
00584 static int system(const char *command, const char **env = NULL);
00585
00592 static int systemf(const char *format, ...) __PRINTF(1,2);
00593
00605 static void bind(const char *name);
00606
00616 static void rebind(const char *name = NULL);
00617
00623 char **parse(const char *string);
00624
00633 void parse(int argc, char **argv);
00634
00642 const char *getenv(const char *name, const char *value = NULL);
00643
00650 const char *getsym(const char *name, const char *value = NULL);
00651
00657 void setsym(const char *name, const char *value);
00658
00664 bool issym(const char *name);
00665
00671 char *getargv0(char **argv);
00672
00680 char **getargv(char **argv);
00681
00688 void restart(char *argv0, char **argv, char **list);
00689
00693 void up(void);
00694
00701 inline static char **parse(shell &args, const char *string)
00702 {return args.parse(string);};
00703
00707 inline const char *argv0() const
00708 {return _argv0;};
00709
00715 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00716
00722 static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00723
00729 static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00730
00738 static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
00739
00744 static size_t printf(const char *format, ...) __PRINTF(1, 2);
00745
00746 static size_t readln(char *address, size_t size);
00747
00748 static size_t writes(const char *string);
00749
00750 static size_t read(String& string);
00751
00752 inline static size_t write(String& string)
00753 {return writes(string.c_str());};
00754
00761 static size_t printf(pipe_t pipe, const char *format, ...) __PRINTF(2, 3);
00762
00770 static size_t readln(pipe_t pipe, char *buffer, size_t size);
00771
00772 static size_t read(pipe_t pipe, String& string);
00773
00774 static size_t writes(pipe_t pipe, const char *string);
00775
00776 inline static size_t write(pipe_t pipe, String& string)
00777 {return writes(pipe, string.c_str());};
00778
00784 inline unsigned argc(void) const
00785 {return _argc;};
00786
00793 inline char **argv(void) const
00794 {return _argv;};
00795
00801 inline const char *operator[](unsigned offset)
00802 {return _argv[offset];};
00803
00807 void detach(downproc_t stopreload = (downproc_t)NULL);
00808
00812 void restart(void);
00813
00825 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00826
00838 static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00839
00848 static void priority(int pri = 1);
00849
00859 static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00860
00866 static int wait(shell::pid_t pid);
00867
00873 static int cancel(shell::pid_t pid);
00874
00881 static int wait(shell::pipe_t pointer);
00882
00888 static int cancel(shell::pipe_t pointer);
00889
00894 inline unsigned operator()(void)
00895 {return _argc;};
00896
00909 static const char *text(const char *string);
00910
00920 static const char *texts(const char *singular, const char *plural, unsigned long count);
00921
00927 static unsigned count(char **argv);
00928
00929 #ifdef _MSWINDOWS_
00930
00931 static inline fd_t input(void)
00932 {return GetStdHandle(STD_INPUT_HANDLE);};
00933
00934 static inline fd_t output(void)
00935 {return GetStdHandle(STD_OUTPUT_HANDLE);};
00936
00937 static inline fd_t error(void)
00938 {return GetStdHandle(STD_ERROR_HANDLE);};
00939
00940 #else
00941 static inline fd_t input(void)
00942 {return 0;};
00943
00944 static inline fd_t output(void)
00945 {return 1;};
00946
00947 static inline fd_t error(void)
00948 {return 2;};
00949 #endif
00950 };
00951
00955 typedef shell shell_t;
00956
00960 #undef _TEXT
00961 #undef _STR
00962
00970 inline const char *_TEXT(const char *s)
00971 {return shell::text(s);}
00972
00973 inline const char *_STR(String& s)
00974 {return *s;}
00975
00976 END_NAMESPACE
00977
00978 #endif