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
00309 virtual const char *assign(const char *value) = 0;
00310 };
00311
00319 class __EXPORT flagopt : public Option
00320 {
00321 private:
00322 unsigned counter;
00323 bool single;
00324
00325 virtual const char *assign(const char *value);
00326
00327 public:
00328 flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00329
00330 inline operator bool()
00331 {return counter > 0;};
00332
00333 inline bool operator!()
00334 {return counter == 0;};
00335
00336 inline operator unsigned()
00337 {return counter;};
00338
00339 inline unsigned operator*()
00340 {return counter;};
00341 };
00342
00349 class __EXPORT stringopt : public Option
00350 {
00351 private:
00352 bool used;
00353
00354 protected:
00355 const char *text;
00356
00357 virtual const char *assign(const char *value);
00358
00359 public:
00360 stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00361
00362 inline operator bool()
00363 {return used;};
00364
00365 inline bool operator!()
00366 {return !used;};
00367
00368 inline operator const char *()
00369 {return text;};
00370
00371 inline const char *operator*()
00372 {return text;};
00373
00374 char operator[](size_t index);
00375 };
00376
00383 class __EXPORT charopt : public Option
00384 {
00385 private:
00386 bool used;
00387
00388 protected:
00389 char code;
00390
00391 virtual const char *assign(const char *value);
00392
00393 public:
00394 charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00395
00396 inline operator bool()
00397 {return used;};
00398
00399 inline bool operator!()
00400 {return !used;};
00401
00402 inline operator char()
00403 {return code;};
00404
00405 inline char operator*()
00406 {return code;};
00407 };
00408
00415 class __EXPORT numericopt : public Option
00416 {
00417 private:
00418 bool used;
00419
00420 protected:
00421 long number;
00422
00423 virtual const char *assign(const char *value);
00424
00425 public:
00426 numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00427
00428 inline operator bool()
00429 {return used;};
00430
00431 inline bool operator!()
00432 {return !used;};
00433
00434 inline operator long()
00435 {return number;};
00436
00437 inline long operator*()
00438 {return number;};
00439 };
00440
00448 shell(const char *string, size_t pagesize = 0);
00449
00458 shell(int argc, char **argv, size_t pagesize = 0);
00459
00464 shell(size_t pagesize = 0);
00465
00469 static void help(void);
00470
00478 static int system(const char *command, const char **env = NULL);
00479
00486 static int systemf(const char *format, ...) __PRINTF(1,2);
00487
00493 char **parse(const char *string);
00494
00503 void parse(int argc, char **argv);
00504
00511 inline static char **parse(shell &args, const char *string)
00512 {return args.parse(string);};
00513
00517 inline const char *argv0() const
00518 {return _argv0;};
00519
00525 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00526
00531 static size_t printf(const char *format, ...) __PRINTF(1, 2);
00532
00533 static size_t readln(char *address, size_t size);
00534
00535 static size_t writes(const char *string);
00536
00537 static size_t read(String& string);
00538
00539 inline static size_t write(String& string)
00540 {return writes(string.c_str());};
00541
00548 static size_t printf(pipe_t pipe, const char *format, ...) __PRINTF(2, 3);
00549
00557 static size_t readln(pipe_t pipe, char *buffer, size_t size);
00558
00559 static size_t read(pipe_t pipe, String& string);
00560
00561 static size_t writes(pipe_t pipe, const char *string);
00562
00563 inline static size_t write(pipe_t pipe, String& string)
00564 {return writes(pipe, string.c_str());};
00565
00571 inline unsigned argc(void) const
00572 {return _argc;};
00573
00580 inline char **argv(void) const
00581 {return _argv;};
00582
00588 inline const char *operator[](unsigned offset)
00589 {return _argv[offset];};
00590
00602 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00603
00615 static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00616
00626 int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00627
00633 static int wait(shell::pid_t pid);
00634
00640 static int cancel(shell::pid_t pid);
00641
00648 static int wait(shell::pipe_t pointer);
00649
00655 static int cancel(shell::pipe_t pointer);
00656
00661 inline unsigned operator()(void)
00662 {return _argc;};
00663
00669 static unsigned count(char **argv);
00670
00671 #ifdef _MSWINDOWS_
00672
00673 static inline fd_t input(void)
00674 {return GetStdHandle(STD_INPUT_HANDLE);};
00675
00676 static inline fd_t output(void)
00677 {return GetStdHandle(STD_OUTPUT_HANDLE);};
00678
00679 static inline fd_t error(void)
00680 {return GetStdHandle(STD_ERROR_HANDLE);};
00681
00682 #else
00683 static inline fd_t input(void)
00684 {return 0;};
00685
00686 static inline fd_t output(void)
00687 {return 1;};
00688
00689 static inline fd_t error(void)
00690 {return 2;};
00691 #endif
00692 };
00693
00694 END_NAMESPACE
00695
00696 #endif