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
00065 class __LOCAL args : public OrderedObject
00066 {
00067 public:
00068 char *item;
00069 };
00070
00076 void collapse(LinkedObject *first);
00077
00081 void set0(char *argv0);
00082
00083 public:
00087 typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE} errmsg_t;
00088
00089 #ifdef _MSWINDOWS_
00090 typedef HANDLE pid_t;
00091 #else
00092
00095 typedef int pid_t;
00096 #endif
00097
00101 typedef enum {RD = IOBuffer::BUF_RD, WR = IOBuffer::BUF_WR, RDWR = IOBuffer::BUF_RDWR} pmode_t;
00102
00111 class __EXPORT pipeio
00112 {
00113 protected:
00114 friend class shell;
00115
00119 pipeio();
00120
00130 int spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00131
00136 int wait(void);
00137
00143 int cancel(void);
00144
00153 size_t read(void *address, size_t size);
00154
00163 size_t write(const void *address, size_t size);
00164
00165 pid_t pid;
00166 fd_t input, output;
00167 int perror, presult;
00168 };
00169
00176 class __EXPORT iobuf : public IOBuffer, protected pipeio
00177 {
00178 protected:
00179 friend class shell;
00180
00181 virtual size_t _push(const char *address, size_t size);
00182 virtual size_t _pull(char *address, size_t size);
00183
00184 public:
00190 iobuf(size_t size = 0);
00191
00202 iobuf(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00203
00208 ~iobuf();
00209
00218 void open(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00219
00224 void close(void);
00225
00230 void cancel(void);
00231 };
00232
00236 typedef iobuf io_t;
00237
00241 typedef pipeio *pipe_t;
00242
00249 static const char *errmsg(errmsg_t id);
00250
00257 static void errmsg(errmsg_t id, const char *text);
00258
00265 class __EXPORT errormap
00266 {
00267 public:
00268 inline errormap(errmsg_t id, const char *text)
00269 {shell::errmsg(id, text);};
00270 };
00271
00279 class __EXPORT Option : public OrderedObject
00280 {
00281 private:
00282 static OrderedIndex index;
00283
00284 public:
00285 char short_option;
00286 const char *long_option;
00287 const char *uses_option;
00288 const char *help_string;
00289
00297 Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
00298
00299 virtual ~Option();
00300
00301 inline static LinkedObject *first(void)
00302 {return index.begin();};
00303
00308 void disable(void);
00309
00315 virtual const char *assign(const char *value) = 0;
00316 };
00317
00325 class __EXPORT flagopt : public Option
00326 {
00327 private:
00328 unsigned counter;
00329 bool single;
00330
00331 virtual const char *assign(const char *value);
00332
00333 public:
00334 flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00335
00336 inline operator bool()
00337 {return counter > 0;};
00338
00339 inline bool operator!()
00340 {return counter == 0;};
00341
00342 inline operator unsigned()
00343 {return counter;};
00344
00345 inline unsigned operator*()
00346 {return counter;};
00347 };
00348
00355 class __EXPORT stringopt : public Option
00356 {
00357 private:
00358 bool used;
00359
00360 protected:
00361 const char *text;
00362
00363 virtual const char *assign(const char *value);
00364
00365 public:
00366 stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00367
00368 inline operator bool()
00369 {return used;};
00370
00371 inline bool operator!()
00372 {return !used;};
00373
00374 inline operator const char *()
00375 {return text;};
00376
00377 inline const char *operator*()
00378 {return text;};
00379
00380 char operator[](size_t index);
00381 };
00382
00389 class __EXPORT charopt : public Option
00390 {
00391 private:
00392 bool used;
00393
00394 protected:
00395 char code;
00396
00397 virtual const char *assign(const char *value);
00398
00399 public:
00400 charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00401
00402 inline operator bool()
00403 {return used;};
00404
00405 inline bool operator!()
00406 {return !used;};
00407
00408 inline operator char()
00409 {return code;};
00410
00411 inline char operator*()
00412 {return code;};
00413 };
00414
00421 class __EXPORT numericopt : public Option
00422 {
00423 private:
00424 bool used;
00425
00426 protected:
00427 long number;
00428
00429 virtual const char *assign(const char *value);
00430
00431 public:
00432 numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00433
00434 inline operator bool()
00435 {return used;};
00436
00437 inline bool operator!()
00438 {return !used;};
00439
00440 inline operator long()
00441 {return number;};
00442
00443 inline long operator*()
00444 {return number;};
00445 };
00446
00454 shell(const char *string, size_t pagesize = 0);
00455
00464 shell(int argc, char **argv, size_t pagesize = 0);
00465
00470 shell(size_t pagesize = 0);
00471
00475 static void help(void);
00476
00484 static int system(const char *command, const char **env = NULL);
00485
00492 static int systemf(const char *format, ...) __PRINTF(1,2);
00493
00499 char **parse(const char *string);
00500
00509 void parse(int argc, char **argv);
00510
00518 const char *getenv(const char *name, const char *value = NULL);
00519
00525 char *getargv0(char **argv);
00526
00534 char **getargv(char **argv);
00535
00542 inline static char **parse(shell &args, const char *string)
00543 {return args.parse(string);};
00544
00548 inline const char *argv0() const
00549 {return _argv0;};
00550
00556 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00557
00562 static size_t printf(const char *format, ...) __PRINTF(1, 2);
00563
00564 static size_t readln(char *address, size_t size);
00565
00566 static size_t writes(const char *string);
00567
00568 static size_t read(String& string);
00569
00570 inline static size_t write(String& string)
00571 {return writes(string.c_str());};
00572
00579 static size_t printf(pipe_t pipe, const char *format, ...) __PRINTF(2, 3);
00580
00588 static size_t readln(pipe_t pipe, char *buffer, size_t size);
00589
00590 static size_t read(pipe_t pipe, String& string);
00591
00592 static size_t writes(pipe_t pipe, const char *string);
00593
00594 inline static size_t write(pipe_t pipe, String& string)
00595 {return writes(pipe, string.c_str());};
00596
00602 inline unsigned argc(void) const
00603 {return _argc;};
00604
00611 inline char **argv(void) const
00612 {return _argv;};
00613
00619 inline const char *operator[](unsigned offset)
00620 {return _argv[offset];};
00621
00633 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00634
00646 static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00647
00657 int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00658
00664 static int wait(shell::pid_t pid);
00665
00671 static int cancel(shell::pid_t pid);
00672
00679 static int wait(shell::pipe_t pointer);
00680
00686 static int cancel(shell::pipe_t pointer);
00687
00692 inline unsigned operator()(void)
00693 {return _argc;};
00694
00700 static unsigned count(char **argv);
00701
00702 #ifdef _MSWINDOWS_
00703
00704 static inline fd_t input(void)
00705 {return GetStdHandle(STD_INPUT_HANDLE);};
00706
00707 static inline fd_t output(void)
00708 {return GetStdHandle(STD_OUTPUT_HANDLE);};
00709
00710 static inline fd_t error(void)
00711 {return GetStdHandle(STD_ERROR_HANDLE);};
00712
00713 #else
00714 static inline fd_t input(void)
00715 {return 0;};
00716
00717 static inline fd_t output(void)
00718 {return 1;};
00719
00720 static inline fd_t error(void)
00721 {return 2;};
00722 #endif
00723 };
00724
00725 END_NAMESPACE
00726
00727 #endif