ucommon

ucommon/shell.h

Go to the documentation of this file.
00001 // Copyright (C) 2006-2010 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 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     class __LOCAL args : public OrderedObject
00067     {
00068     public:
00069         char *item;
00070     };
00071 
00072     class __LOCAL syms : public LinkedObject
00073     {
00074     public:
00075         const char *name;
00076         const char *value;
00077     };
00078 
00084     void collapse(LinkedObject *first);
00085 
00089     void set0(char *argv0);
00090 
00091 public:
00095     typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE} errmsg_t;
00096 
00100     typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
00101 
00105     typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
00106 
00110     typedef bool (*logproc_t)(loglevel_t level, const char *text);
00111 
00115     typedef cpr_service_t   mainproc_t;
00116 
00120     typedef void (*exitproc_t)(void);
00121 
00122 #ifdef  _MSWINDOWS_
00123     typedef HANDLE pid_t;
00124 #else
00125 
00128     typedef int pid_t;
00129 #endif
00130 
00134     typedef enum {RD = BufferProtocol::BUF_RD, WR = BufferProtocol::BUF_WR, RDWR = BufferProtocol::BUF_RDWR} pmode_t;
00135 
00144     class __EXPORT pipeio
00145     {
00146     protected:
00147         friend class shell;
00148 
00152         pipeio();
00153 
00163         int spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00164 
00169         int wait(void);
00170 
00176         int cancel(void);
00177 
00186         size_t read(void *address, size_t size);
00187 
00196         size_t write(const void *address, size_t size);
00197 
00198         pid_t pid;
00199         fd_t input, output; // input to and output from child process...
00200         int perror, presult;
00201     };
00202 
00209     class __EXPORT iobuf : public BufferProtocol, private pipeio
00210     {
00211     protected:
00212         friend class shell;
00213 
00214         int ioerror;
00215 
00216         virtual int _err(void) const;
00217         virtual void _clear(void);
00218 
00219         virtual size_t _push(const char *address, size_t size);
00220         virtual size_t _pull(char *address, size_t size);
00221 
00222     public:
00228         iobuf(size_t size = 0);
00229 
00240         iobuf(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00241 
00246         ~iobuf();
00247 
00256         void open(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00257 
00262         void close(void);
00263 
00268         void cancel(void);
00269     };
00270 
00274     typedef iobuf io_t;
00275 
00279     typedef pipeio *pipe_t;
00280 
00287     static const char *errmsg(errmsg_t id);
00288 
00295     static void errmsg(errmsg_t id, const char *text);
00296 
00303     class __EXPORT errormap
00304     {
00305     public:
00306         inline errormap(errmsg_t id, const char *text)
00307             {shell::errmsg(id, text);};
00308     };
00309 
00317     class __EXPORT Option : public OrderedObject
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         static LinkedObject *first(void);
00338 
00343         void disable(void);
00344 
00350         virtual const char *assign(const char *value) = 0;
00351 
00352         static void reset(void);
00353     };
00354 
00362     class __EXPORT flagopt : public Option
00363     {
00364     private:
00365         unsigned counter;
00366         bool single;
00367 
00368         virtual const char *assign(const char *value);
00369 
00370     public:
00371         flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00372 
00373         inline operator bool()
00374             {return counter > 0;};
00375 
00376         inline bool operator!()
00377             {return counter == 0;};
00378 
00379         inline operator unsigned()
00380             {return counter;};
00381 
00382         inline unsigned operator*()
00383             {return counter;};
00384 
00385         inline void set(unsigned value = 1)
00386             {counter = value;};
00387     };
00388 
00394     class __EXPORT groupopt : public Option
00395     {
00396     private:
00397         virtual const char *assign(const char *value);
00398 
00399     public:
00400         groupopt(const char *help);
00401     };
00402 
00409     class __EXPORT stringopt : public Option
00410     {
00411     private:
00412         bool used;
00413 
00414     protected:
00415         const char *text;
00416 
00417         virtual const char *assign(const char *value);
00418 
00419     public:
00420         stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00421 
00422         inline void set(const char *string)
00423             {text = string;};
00424 
00425         inline operator bool()
00426             {return used;};
00427 
00428         inline bool operator!()
00429             {return !used;};
00430 
00431         inline operator const char *()
00432             {return text;};
00433 
00434         inline const char *operator*()
00435             {return text;};
00436     };
00437 
00444     class __EXPORT charopt : public Option
00445     {
00446     private:
00447         bool used;
00448 
00449     protected:
00450         char code;
00451 
00452         virtual const char *assign(const char *value);
00453 
00454     public:
00455         charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00456 
00457         inline void set(char value)
00458             {code = value;};
00459 
00460         inline operator bool()
00461             {return used;};
00462 
00463         inline bool operator!()
00464             {return !used;};
00465 
00466         inline operator char()
00467             {return code;};
00468 
00469         inline char operator*()
00470             {return code;};
00471     };
00472 
00479     class __EXPORT numericopt : public Option
00480     {
00481     private:
00482         bool used;
00483 
00484     protected:
00485         long number;
00486 
00487         virtual const char *assign(const char *value);
00488 
00489     public:
00490         numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00491 
00492         inline void set(long value)
00493             {number = value;};
00494 
00495         inline operator bool()
00496             {return used;};
00497 
00498         inline bool operator!()
00499             {return !used;};
00500 
00501         inline operator long()
00502             {return number;};
00503 
00504         inline long operator*()
00505             {return number;};
00506     };
00507 
00516     class __EXPORT counteropt : public Option
00517     {
00518     private:
00519         bool used;
00520 
00521     protected:
00522         long number;
00523 
00524         virtual const char *assign(const char *value);
00525 
00526     public:
00527         counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00528 
00529         inline void set(long value)
00530             {number = value;};
00531 
00532         inline operator bool()
00533             {return used;};
00534 
00535         inline bool operator!()
00536             {return !used;};
00537 
00538         inline operator long()
00539             {return number;};
00540 
00541         inline long operator*()
00542             {return number;};
00543     };
00544 
00552     shell(const char *string, size_t pagesize = 0);
00553 
00562     shell(int argc, char **argv, size_t pagesize = 0);
00563 
00568     shell(size_t pagesize = 0);
00569 
00573     static void help(void);
00574 
00582     static int system(const char *command, const char **env = NULL);
00583 
00590     static int systemf(const char *format, ...) __PRINTF(1,2);
00591 
00603     static void bind(const char *name);
00604 
00614     static void rebind(const char *name = NULL);
00615 
00621     char **parse(const char *string);
00622 
00631     void parse(int argc, char **argv);
00632 
00640     const char *getenv(const char *name, const char *value = NULL);
00641 
00648     const char *getsym(const char *name, const char *value = NULL);
00649 
00655     void setsym(const char *name, const char *value);
00656 
00662     bool issym(const char *name);
00663 
00669     char *getargv0(char **argv);
00670 
00678     char **getargv(char **argv);
00679 
00686     void restart(char *argv0, char **argv, char **list);
00687 
00694     inline static char **parse(shell &args, const char *string)
00695         {return args.parse(string);};
00696 
00700     inline const char *argv0() const
00701         {return _argv0;};
00702 
00708     static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00709 
00715     static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00716 
00722     static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00723 
00729     static void security(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 
00804     static void exiting(exitproc_t);
00805 
00809     void detach(mainproc_t mainentry = (mainproc_t)NULL);
00810 
00814     void restart(void);
00815 
00827     static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00828 
00840     static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00841 
00850     static void priority(int pri = 1);
00851 
00861     static int  detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00862 
00868     static int wait(shell::pid_t pid);
00869 
00875     static int cancel(shell::pid_t pid);
00876 
00883     static int wait(shell::pipe_t pointer);
00884 
00890     static int cancel(shell::pipe_t pointer);
00891 
00896     inline unsigned operator()(void)
00897         {return _argc;};
00898 
00911     static const char *text(const char *string);
00912 
00922     static const char *texts(const char *singular, const char *plural, unsigned long count);
00923 
00929     static unsigned count(char **argv);
00930 
00931 #ifdef  _MSWINDOWS_
00932 
00933     static inline fd_t input(void)
00934         {return GetStdHandle(STD_INPUT_HANDLE);};
00935 
00936     static inline fd_t output(void)
00937         {return GetStdHandle(STD_OUTPUT_HANDLE);};
00938 
00939     static inline fd_t error(void)
00940         {return GetStdHandle(STD_ERROR_HANDLE);};
00941 
00942 #else
00943     static inline fd_t input(void)
00944         {return 0;};
00945 
00946     static inline fd_t output(void)
00947         {return 1;};
00948 
00949     static inline fd_t error(void)
00950         {return 2;};
00951 #endif
00952 };
00953 
00957 typedef shell shell_t;
00958 
00962 #undef  _TEXT
00963 #undef  _STR
00964 
00972 inline  const char *_TEXT(const char *s)
00973     {return shell::text(s);}
00974 
00975 inline const char *_STR(String& s)
00976     {return *s;}
00977 
00978 END_NAMESPACE
00979 
00980 #endif