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 
157  static const char *errmsg(errmsg_t id);
158 
165  static void errmsg(errmsg_t id, const char *text);
166 
173  class __EXPORT errormap
174  {
175  public:
176  inline errormap(errmsg_t id, const char *text)
177  {shell::errmsg(id, text);};
178  };
179 
187  class __EXPORT Option : public LinkedObject
188  {
189  public:
190  char short_option;
191  const char *long_option;
192  const char *uses_option;
193  const char *help_string;
194  bool trigger_option;
195 
203  Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
204 
205  virtual ~Option();
206 
207  static LinkedObject *first(void);
208 
213  void disable(void);
214 
220  virtual const char *assign(const char *value) = 0;
221 
222  static void reset(void);
223  };
224 
232  class __EXPORT flagopt : public Option
233  {
234  private:
235  unsigned counter;
236  bool single;
237 
238  virtual const char *assign(const char *value);
239 
240  public:
241  flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
242 
243  inline operator bool()
244  {return counter > 0;};
245 
246  inline bool operator!()
247  {return counter == 0;};
248 
249  inline operator unsigned()
250  {return counter;};
251 
252  inline unsigned operator*()
253  {return counter;};
254 
255  inline void set(unsigned value = 1)
256  {counter = value;};
257  };
258 
264  class __EXPORT groupopt : public Option
265  {
266  private:
267  virtual const char *assign(const char *value);
268 
269  public:
270  groupopt(const char *help);
271  };
272 
279  class __EXPORT stringopt : public Option
280  {
281  private:
282  bool used;
283 
284  protected:
285  const char *text;
286 
287  virtual const char *assign(const char *value);
288 
289  public:
290  stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
291 
292  inline void set(const char *string)
293  {text = string;};
294 
295  inline operator bool()
296  {return used;};
297 
298  inline bool operator!()
299  {return !used;};
300 
301  inline operator const char *()
302  {return text;};
303 
304  inline const char *operator*()
305  {return text;};
306  };
307 
314  class __EXPORT charopt : public Option
315  {
316  private:
317  bool used;
318 
319  protected:
320  char code;
321 
322  virtual const char *assign(const char *value);
323 
324  public:
325  charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
326 
327  inline void set(char value)
328  {code = value;};
329 
330  inline operator bool()
331  {return used;};
332 
333  inline bool operator!()
334  {return !used;};
335 
336  inline operator char()
337  {return code;};
338 
339  inline char operator*()
340  {return code;};
341  };
342 
349  class __EXPORT numericopt : public Option
350  {
351  private:
352  bool used;
353 
354  protected:
355  long number;
356 
357  virtual const char *assign(const char *value);
358 
359  public:
360  numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
361 
362  inline void set(long value)
363  {number = value;};
364 
365  inline operator bool()
366  {return used;};
367 
368  inline bool operator!()
369  {return !used;};
370 
371  inline operator long()
372  {return number;};
373 
374  inline long operator*()
375  {return number;};
376  };
377 
386  class __EXPORT counteropt : public Option
387  {
388  private:
389  bool used;
390 
391  protected:
392  long number;
393 
394  virtual const char *assign(const char *value);
395 
396  public:
397  counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
398 
399  inline void set(long value)
400  {number = value;};
401 
402  inline operator bool()
403  {return used;};
404 
405  inline bool operator!()
406  {return !used;};
407 
408  inline operator long()
409  {return number;};
410 
411  inline long operator*()
412  {return number;};
413  };
414 
422  shell(const char *string, size_t pagesize = 0);
423 
432  shell(int argc, char **argv, size_t pagesize = 0);
433 
438  shell(size_t pagesize = 0);
439 
440  static void setNumeric(numeric_t);
441 
442  static long getNumeric(void);
443 
447  static void help(void);
448 
456  static int system(const char *command, const char **env = NULL);
457 
464  static int systemf(const char *format, ...) __PRINTF(1,2);
465 
470  static void relocate(const char *argv0);
471 
478  static String path(path_t id);
479 
484  static String userid(void);
485 
492  static String path(path_t id, const char *directory);
493 
499  static String path(String& prefix, const char *directory);
500 
512  static void bind(const char *name);
513 
523  static void rebind(const char *name = NULL);
524 
530  char **parse(const char *string);
531 
540  void parse(int argc, char **argv);
541 
549  const char *env(const char *name, const char *value = NULL);
550 
551  inline const char *getenv(const char *name, const char *value = NULL)
552  {return env(name, value);}
553 
560  const char *get(const char *name, const char *value = NULL);
561 
562  inline const char *getsym(const char *name, const char *value = NULL)
563  {return get(name, value);}
564 
570  void set(const char *name, const char *value);
571 
572  inline void setsym(const char *name, const char *value)
573  {return set(name, value);}
574 
580  bool is_sym(const char *name);
581 
587  char *getargv0(char **argv);
588 
596  char **getargv(char **argv);
597 
604  void restart(char *argv0, char **argv, char **list);
605 
609  inline const char *argv0() const
610  {return _argv0;}
611 
615  inline const char *execdir() const
616  {return _exedir;}
617 
622  static void error(const char *format, ...) __PRINTF(1, 2);
623 
629  static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
630 
631 
637  static inline int condition(bool test, int exitcode)
638  { return (test) ? exitcode : 0;};
639 
645  static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
646 
652  static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
653 
659  static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
660 
668  static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
669 
674  static size_t printf(const char *format, ...) __PRINTF(1, 2);
675 
676  static size_t readln(char *address, size_t size);
677 
678  static size_t writes(const char *string);
679 
680  static size_t read(String& string);
681 
682  inline static size_t write(String& string)
683  {return writes(string.c_str());};
684 
690  inline unsigned argc(void) const
691  {return _argc;};
692 
699  inline char **argv(void) const
700  {return _argv;};
701 
707  inline const char *operator[](unsigned offset)
708  {return _argv[offset];};
709 
710  static void exiting(exitproc_t);
711 
715  void detach(mainproc_t mainentry = (mainproc_t)NULL);
716 
720  void restart(void);
721 
733  static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
734 
743  static void priority(int pri = 1);
744 
754  static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
755 
760  static void release(int exit_code = 0);
761 
767  static int wait(shell::pid_t pid);
768 
774  static int cancel(shell::pid_t pid);
775 
780  inline unsigned operator()(void)
781  {return _argc;};
782 
795  static const char *text(const char *string);
796 
806  static const char *texts(const char *singular, const char *plural, unsigned long count);
807 
813  static unsigned count(char **argv);
814 
815 #ifdef _MSWINDOWS_
816 
817  static inline fd_t input(void)
818  {return GetStdHandle(STD_INPUT_HANDLE);};
819 
820  static inline fd_t output(void)
821  {return GetStdHandle(STD_OUTPUT_HANDLE);};
822 
823  static inline fd_t error(void)
824  {return GetStdHandle(STD_ERROR_HANDLE);};
825 
826 #else
827  static inline fd_t input(void)
828  {return 0;};
829 
830  static inline fd_t output(void)
831  {return 1;};
832 
833  static inline fd_t error(void)
834  {return 2;};
835 #endif
836 
837  static int inkey(const char *prompt = NULL);
838 
839  static char *getpass(const char *prompt, char *buffer, size_t size);
840 
841  static char *getline(const char *prompt, char *buffer, size_t size);
842 
843 };
844 
848 typedef shell shell_t;
849 
853 #undef _TEXT
854 #undef _STR
855 #define _STR(x) (const char *)(x)
856 
864 inline const char *_TEXT(const char *s)
865  {return shell::text(s);}
866 
867 END_NAMESPACE
868 
869 #endif