UCommon
shell.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
28 #ifndef _UCOMMON_STRING_H_
29 #include <ucommon/string.h>
30 #endif
31 
32 #ifndef _UCOMMON_MEMORY_H_
33 #include <ucommon/memory.h>
34 #endif
35 
36 #ifndef _UCOMMON_BUFFER_H_
37 #include <ucommon/buffer.h>
38 #endif
39 
40 #ifndef _UCOMMON_SHELL_H_
41 #define _UCOMMON_SHELL_H_
42 
43 #ifdef _MSWINDOWS_
44 #define INVALID_PID_VALUE INVALID_HANDLE_VALUE
45 #else
46 #define INVALID_PID_VALUE -1
47 #endif
48 
49 #ifdef ERR
50 #undef ERR
51 #endif
52 
53 NAMESPACE_UCOMMON
54 
62 class __EXPORT shell : public mempager
63 {
64 private:
65  char **_argv;
66  unsigned _argc;
67  char *_argv0;
68  char *_exedir;
69  LinkedObject *_syms;
70 
71  class __LOCAL args : public OrderedObject
72  {
73  public:
74  char *item;
75  };
76 
77  class __LOCAL syms : public LinkedObject
78  {
79  public:
80  const char *name;
81  const char *value;
82  };
83 
89  void collapse(LinkedObject *first);
90 
94  void set0(char *argv0);
95 
96 public:
100  typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t;
101 
105  typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
106 
110  typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
111 
115  typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t;
116 
120  typedef enum {
121  PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SERVICE_CONTROL,
122  USER_HOME = USER_DEFAULTS + 3, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE,
123  SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC,
124  SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS,
125  PROGRAM_TEMP} path_t;
126 
130  typedef bool (*logproc_t)(loglevel_t level, const char *text);
131 
135  typedef cpr_service_t mainproc_t;
136 
140  typedef void (*exitproc_t)(void);
141 
142 #ifdef _MSWINDOWS_
143  typedef HANDLE pid_t;
144 #else
145 
148  typedef int pid_t;
149 #endif
150 
154  typedef enum {RD = BufferProtocol::BUF_RD, WR = BufferProtocol::BUF_WR, RDWR = BufferProtocol::BUF_RDWR} pmode_t;
155 
162  static const char *errmsg(errmsg_t id);
163 
170  static void errmsg(errmsg_t id, const char *text);
171 
178  class __EXPORT errormap
179  {
180  public:
181  inline errormap(errmsg_t id, const char *text)
182  {shell::errmsg(id, text);};
183  };
184 
192  class __EXPORT Option : public OrderedObject
193  {
194  public:
195  char short_option;
196  const char *long_option;
197  const char *uses_option;
198  const char *help_string;
199  bool trigger_option;
200 
208  Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
209 
210  virtual ~Option();
211 
212  static LinkedObject *first(void);
213 
218  void disable(void);
219 
225  virtual const char *assign(const char *value) = 0;
226 
227  static void reset(void);
228  };
229 
237  class __EXPORT flagopt : public Option
238  {
239  private:
240  unsigned counter;
241  bool single;
242 
243  virtual const char *assign(const char *value);
244 
245  public:
246  flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
247 
248  inline operator bool()
249  {return counter > 0;};
250 
251  inline bool operator!()
252  {return counter == 0;};
253 
254  inline operator unsigned()
255  {return counter;};
256 
257  inline unsigned operator*()
258  {return counter;};
259 
260  inline void set(unsigned value = 1)
261  {counter = value;};
262  };
263 
269  class __EXPORT groupopt : public Option
270  {
271  private:
272  virtual const char *assign(const char *value);
273 
274  public:
275  groupopt(const char *help);
276  };
277 
284  class __EXPORT stringopt : public Option
285  {
286  private:
287  bool used;
288 
289  protected:
290  const char *text;
291 
292  virtual const char *assign(const char *value);
293 
294  public:
295  stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
296 
297  inline void set(const char *string)
298  {text = string;};
299 
300  inline operator bool()
301  {return used;};
302 
303  inline bool operator!()
304  {return !used;};
305 
306  inline operator const char *()
307  {return text;};
308 
309  inline const char *operator*()
310  {return text;};
311  };
312 
319  class __EXPORT charopt : public Option
320  {
321  private:
322  bool used;
323 
324  protected:
325  char code;
326 
327  virtual const char *assign(const char *value);
328 
329  public:
330  charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
331 
332  inline void set(char value)
333  {code = value;};
334 
335  inline operator bool()
336  {return used;};
337 
338  inline bool operator!()
339  {return !used;};
340 
341  inline operator char()
342  {return code;};
343 
344  inline char operator*()
345  {return code;};
346  };
347 
354  class __EXPORT numericopt : public Option
355  {
356  private:
357  bool used;
358 
359  protected:
360  long number;
361 
362  virtual const char *assign(const char *value);
363 
364  public:
365  numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
366 
367  inline void set(long value)
368  {number = value;};
369 
370  inline operator bool()
371  {return used;};
372 
373  inline bool operator!()
374  {return !used;};
375 
376  inline operator long()
377  {return number;};
378 
379  inline long operator*()
380  {return number;};
381  };
382 
391  class __EXPORT counteropt : public Option
392  {
393  private:
394  bool used;
395 
396  protected:
397  long number;
398 
399  virtual const char *assign(const char *value);
400 
401  public:
402  counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
403 
404  inline void set(long value)
405  {number = value;};
406 
407  inline operator bool()
408  {return used;};
409 
410  inline bool operator!()
411  {return !used;};
412 
413  inline operator long()
414  {return number;};
415 
416  inline long operator*()
417  {return number;};
418  };
419 
427  shell(const char *string, size_t pagesize = 0);
428 
437  shell(int argc, char **argv, size_t pagesize = 0);
438 
443  shell(size_t pagesize = 0);
444 
445  static void setNumeric(numeric_t);
446 
447  static long getNumeric(void);
448 
452  static void help(void);
453 
461  static int system(const char *command, const char **env = NULL);
462 
469  static int systemf(const char *format, ...) __PRINTF(1,2);
470 
475  static void relocate(const char *argv0);
476 
483  static String path(path_t id);
484 
489  static String userid(void);
490 
497  static String path(path_t id, const char *directory);
498 
504  static String path(String& prefix, const char *directory);
505 
517  static void bind(const char *name);
518 
528  static void rebind(const char *name = NULL);
529 
535  char **parse(const char *string);
536 
545  void parse(int argc, char **argv);
546 
554  const char *getenv(const char *name, const char *value = NULL);
555 
562  const char *getsym(const char *name, const char *value = NULL);
563 
569  void setsym(const char *name, const char *value);
570 
576  bool issym(const char *name);
577 
583  char *getargv0(char **argv);
584 
592  char **getargv(char **argv);
593 
600  void restart(char *argv0, char **argv, char **list);
601 
608  inline static char **parse(shell &args, const char *string)
609  {return args.parse(string);}
610 
614  inline const char *argv0() const
615  {return _argv0;}
616 
620  inline const char *execdir() const
621  {return _exedir;}
622 
627  static void error(const char *format, ...) __PRINTF(1, 2);
628 
634  static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
635 
636 
642  static inline int condition(bool test, int exitcode)
643  { return (test) ? exitcode : 0;};
644 
650  static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
651 
657  static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
658 
664  static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
665 
673  static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
674 
679  static size_t printf(const char *format, ...) __PRINTF(1, 2);
680 
681  static size_t readln(char *address, size_t size);
682 
683  static size_t writes(const char *string);
684 
685  static size_t read(String& string);
686 
687  inline static size_t write(String& string)
688  {return writes(string.c_str());};
689 
695  inline unsigned argc(void) const
696  {return _argc;};
697 
704  inline char **argv(void) const
705  {return _argv;};
706 
712  inline const char *operator[](unsigned offset)
713  {return _argv[offset];};
714 
715  static void exiting(exitproc_t);
716 
720  void detach(mainproc_t mainentry = (mainproc_t)NULL);
721 
725  void restart(void);
726 
738  static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
739 
748  static void priority(int pri = 1);
749 
759  static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
760 
765  static void release(int exit_code = 0);
766 
772  static int wait(shell::pid_t pid);
773 
779  static int cancel(shell::pid_t pid);
780 
785  inline unsigned operator()(void)
786  {return _argc;};
787 
800  static const char *text(const char *string);
801 
811  static const char *texts(const char *singular, const char *plural, unsigned long count);
812 
818  static unsigned count(char **argv);
819 
820 #ifdef _MSWINDOWS_
821 
822  static inline fd_t input(void)
823  {return GetStdHandle(STD_INPUT_HANDLE);};
824 
825  static inline fd_t output(void)
826  {return GetStdHandle(STD_OUTPUT_HANDLE);};
827 
828  static inline fd_t error(void)
829  {return GetStdHandle(STD_ERROR_HANDLE);};
830 
831 #else
832  static inline fd_t input(void)
833  {return 0;};
834 
835  static inline fd_t output(void)
836  {return 1;};
837 
838  static inline fd_t error(void)
839  {return 2;};
840 #endif
841 
842  static int inkey(const char *prompt = NULL);
843 
844  static char *getpass(const char *prompt, char *buffer, size_t size);
845 
846  static char *getline(const char *prompt, char *buffer, size_t size);
847 
848 };
849 
853 typedef shell shell_t;
854 
858 #undef _TEXT
859 #undef _STR
860 
868 inline const char *_TEXT(const char *s)
869  {return shell::text(s);}
870 
871 inline const char *_STR(String& s)
872  {return *s;}
873 
874 END_NAMESPACE
875 
876 #endif