UCommon
shell.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
29 #ifndef _UCOMMON_STRING_H_
30 #include <ucommon/string.h>
31 #endif
32 
33 #ifndef _UCOMMON_MEMORY_H_
34 #include <ucommon/memory.h>
35 #endif
36 
37 #ifndef _UCOMMON_BUFFER_H_
38 #include <ucommon/buffer.h>
39 #endif
40 
41 #ifndef _UCOMMON_SHELL_H_
42 #define _UCOMMON_SHELL_H_
43 
44 #ifdef _MSWINDOWS_
45 #define INVALID_PID_VALUE INVALID_HANDLE_VALUE
46 #else
47 #define INVALID_PID_VALUE -1
48 #endif
49 
50 #ifdef ERR
51 #undef ERR
52 #endif
53 
54 namespace ucommon {
55 
63 class __EXPORT shell : public mempager
64 {
65 private:
66  char **_argv;
67  unsigned _argc;
68  char *_argv0;
69  char *_exedir;
70  LinkedObject *_syms;
71 
72  __DELETE_COPY(shell);
73 
74  class __LOCAL args : public OrderedObject
75  {
76  public:
77  char *item;
78  };
79 
80  class __LOCAL syms : public LinkedObject
81  {
82  public:
83  const char *name;
84  const char *value;
85  };
86 
92  void collapse(LinkedObject *first);
93 
97  void set0(char *argv0);
98 
99 public:
103  typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t;
104 
108  typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
109 
113  typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
114 
118  typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t;
119 
123  typedef enum {
124  PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SERVICE_CONTROL,
125  USER_HOME = USER_DEFAULTS + 3, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE,
126  SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC,
127  SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS,
128  PROGRAM_TEMP} path_t;
129 
133  typedef bool (*logproc_t)(loglevel_t level, const char *text);
134 
138  typedef cpr_service_t mainproc_t;
139 
143  typedef void (*exitproc_t)(void);
144 
145 #ifdef _MSWINDOWS_
146  typedef HANDLE pid_t;
147 #else
148 
151  typedef int pid_t;
152 #endif
153 
160  static const char *errmsg(errmsg_t id);
161 
168  static void errmsg(errmsg_t id, const char *text);
169 
176  class __EXPORT errormap
177  {
178  public:
179  inline errormap(errmsg_t id, const char *text)
180  {shell::errmsg(id, text);}
181  };
182 
190  class __EXPORT Option : public LinkedObject
191  {
192  public:
193  char short_option;
194  const char *long_option;
195  const char *uses_option;
196  const char *help_string;
197  bool trigger_option;
198 
206  Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
207 
208  virtual ~Option();
209 
210  static LinkedObject *first(void);
211 
216  void disable(void);
217 
223  virtual const char *assign(const char *value) = 0;
224 
225  static void reset(void);
226  };
227 
235  class __EXPORT flagopt : public Option
236  {
237  private:
238  unsigned counter;
239  bool single;
240 
241  virtual const char *assign(const char *value);
242 
243  public:
244  flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
245 
246  inline operator bool() const
247  {return counter > 0;}
248 
249  inline bool operator!() const
250  {return counter == 0;}
251 
252  inline operator unsigned() const
253  {return counter;}
254 
255  inline unsigned operator*() const
256  {return counter;}
257 
258  inline void set(unsigned value = 1)
259  {counter = value;}
260  };
261 
267  class __EXPORT groupopt : public Option
268  {
269  private:
270  virtual const char *assign(const char *value);
271 
272  public:
273  groupopt(const char *help);
274  };
275 
282  class __EXPORT stringopt : public Option
283  {
284  private:
285  bool used;
286 
287  protected:
288  const char *text;
289 
290  virtual const char *assign(const char *value);
291 
292  public:
293  stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
294 
295  inline void set(const char *string)
296  {text = string;}
297 
298  inline operator bool() const
299  {return used;}
300 
301  inline bool operator!() const
302  {return !used;}
303 
304  inline operator const char *() const
305  {return text;}
306 
307  inline const char *operator*() const
308  {return text;}
309  };
310 
317  class __EXPORT charopt : public Option
318  {
319  private:
320  bool used;
321 
322  protected:
323  char code;
324 
325  virtual const char *assign(const char *value);
326 
327  public:
328  charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
329 
330  inline void set(char value)
331  {code = value;}
332 
333  inline operator bool() const
334  {return used;}
335 
336  inline bool operator!() const
337  {return !used;}
338 
339  inline operator char() const
340  {return code;}
341 
342  inline char operator*() const
343  {return code;}
344  };
345 
352  class __EXPORT numericopt : public Option
353  {
354  private:
355  bool used;
356 
357  protected:
358  long number;
359 
360  virtual const char *assign(const char *value);
361 
362  public:
363  numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
364 
365  inline void set(long value)
366  {number = value;}
367 
368  inline operator bool() const
369  {return used;}
370 
371  inline bool operator!() const
372  {return !used;}
373 
374  inline operator long() const
375  {return number;}
376 
377  inline long operator*() const
378  {return number;}
379  };
380 
389  class __EXPORT counteropt : public Option
390  {
391  private:
392  bool used;
393 
394  protected:
395  long number;
396 
397  virtual const char *assign(const char *value);
398 
399  public:
400  counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
401 
402  inline void set(long value)
403  {number = value;}
404 
405  inline operator bool() const
406  {return used;}
407 
408  inline bool operator!() const
409  {return !used;}
410 
411  inline operator long() const
412  {return number;}
413 
414  inline long operator*() const
415  {return number;}
416  };
417 
425  shell(const char *string, size_t pagesize = 0);
426 
435  shell(int argc, char **argv, size_t pagesize = 0);
436 
441  shell(size_t pagesize = 0);
442 
443  static void setNumeric(numeric_t);
444 
445  static long getNumeric(void);
446 
450  static void help(void);
451 
459  static int system(const char *command, const char **env = NULL);
460 
467  static int systemf(const char *format, ...) __PRINTF(1,2);
468 
473  static void relocate(const char *argv0);
474 
481  static String path(path_t id);
482 
487  static String userid(void);
488 
495  static String path(path_t id, const char *directory);
496 
502  static String path(String& prefix, const char *directory);
503 
515  static void bind(const char *name);
516 
526  static void rebind(const char *name = NULL);
527 
533  char **parse(const char *string);
534 
543  void parse(int argc, char **argv);
544 
552  const char *env(const char *name, const char *value = NULL);
553 
554  inline const char *getenv(const char *name, const char *value = NULL)
555  {return env(name, value);}
556 
563  const char *get(const char *name, const char *value = NULL);
564 
565  inline const char *getsym(const char *name, const char *value = NULL)
566  {return get(name, value);}
567 
573  void set(const char *name, const char *value);
574 
575  inline void setsym(const char *name, const char *value)
576  {return set(name, value);}
577 
583  bool is_sym(const char *name) const;
584 
590  char *getargv0(char **argv);
591 
599  char **getargv(char **argv);
600 
607  void restart(char *argv0, char **argv, char **list);
608 
612  inline const char *argv0() const
613  {return _argv0;}
614 
618  inline const char *execdir() const
619  {return _exedir;}
620 
625  static void error(const char *format, ...) __PRINTF(1, 2);
626 
627  static void errlog(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) const
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 #define _STR(x) (const char *)(x)
861 
869 inline const char *_TEXT(const char *s)
870  {return shell::text(s);}
871 
872 } // namespace ucommon
873 
874 #endif
A common string class and character string support functions.
unsigned argc(void) const
Get saved internal argc count for items.
Definition: shell.h:695
void release(SharedAccess &object)
Convenience function to unlock shared object through it's protocol.
Definition: access.h:280
numeric_t
Numeric mode of parser.
Definition: shell.h:118
Character option for shell parsing.
Definition: shell.h:317
const char * execdir() const
Get the exec directory.
Definition: shell.h:618
Flag option for shell parsing.
Definition: shell.h:235
int pid_t
Standard type of process id for shell class.
Definition: shell.h:151
A managed private heap for small allocations.
Definition: memory.h:192
Common base class for all objects that can be formed into a linked list.
Definition: linked.h:59
unsigned operator()(void) const
Return argc count.
Definition: shell.h:785
A linked object base class for ordered objects.
Definition: linked.h:319
A copy-on-write string class that operates by reference count.
Definition: string.h:83
Private heaps, pools, and associations.
A utility class for generic shell operations.
Definition: shell.h:63
static const char * text(const char *string)
Text translation and localization.
char ** argv(void) const
Get saved internal argv count for items in this shell object.
Definition: shell.h:704
A class to redefine error messages.
Definition: shell.h:176
errmsg_t
Error table index.
Definition: shell.h:103
Text option for shell parsing.
Definition: shell.h:282
Numeric option for shell parsing.
Definition: shell.h:352
const char * argv0() const
Get program name (argv0).
Definition: shell.h:612
Common namespace for all ucommon objects.
Definition: access.h:47
static const char * errmsg(errmsg_t id)
This can be used to get internationalized error messages.
const char * operator[](unsigned offset)
Return parser argv element.
Definition: shell.h:712
void wait(barrier_t &barrier)
Convenience function to wait on a barrier.
Definition: thread.h:1921
const char * _TEXT(const char *s)
Invoke translation lookup if available.
Definition: shell.h:869
A base class used to create parsable shell options.
Definition: shell.h:190
Grouping option.
Definition: shell.h:267
shell shell_t
Convenience type to manage and pass shell objects.
Definition: shell.h:853
Classes which use the buffer protocol to stream data.
path_t
Path types to retrieve.
Definition: shell.h:123
loglevel_t
Level of error logging.
Definition: shell.h:113
Counter option for shell parsing.
Definition: shell.h:389
Automatic integer counting class.
Definition: counter.h:43
cpr_service_t mainproc_t
Main handler.
Definition: shell.h:138