dclib-option.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #ifndef DCLIB_OPTION_H
  34. #define DCLIB_OPTION_H 1
  35. #include "dclib-basics.h"
  36. struct TCPStream_t;
  37. //
  38. ///////////////////////////////////////////////////////////////////////////////
  39. /////////////// GenericOpt_t ///////////////
  40. ///////////////////////////////////////////////////////////////////////////////
  41. // [[GenericOptParm_t]]
  42. typedef struct GenericOptParm_t
  43. {
  44. u32 id; // id of the option
  45. u8 arg; // 0: no arguments
  46. // 1: always argument,
  47. // 2: optional argument
  48. // 3: short-opt: no arg / long-opt: optional arg
  49. ccp name; // pipe separated option names
  50. }
  51. GenericOptParm_t;
  52. //-----------------------------------------------------------------------------
  53. // [[GenericOpt_t]]
  54. struct option;
  55. typedef struct GenericOpt_t
  56. {
  57. //--- short options
  58. char sopt[0x100]; // short options string
  59. u32 sopt_id[0x80];
  60. //--- long options
  61. struct option *lopt; // long options list
  62. uint lopt_used; // number of used 'lopt' elements
  63. uint lopt_size; // number of alloced 'lopt' elements
  64. //--- string pool
  65. MemPool_t str_pool; // pool for option names
  66. }
  67. GenericOpt_t;
  68. //-----------------------------------------------------------------------------
  69. void InitializeGenericOpt ( GenericOpt_t *go, char first_char );
  70. void ResetGenericOpt ( GenericOpt_t *go );
  71. void AddGenericOpt
  72. (
  73. GenericOpt_t *go, // data structure
  74. const GenericOptParm_t *gp, // list to add, list end on name==NULL
  75. bool rm_minus // remove '-' of options for alternatives
  76. );
  77. //
  78. ///////////////////////////////////////////////////////////////////////////////
  79. /////////////// GOPT_t ///////////////
  80. ///////////////////////////////////////////////////////////////////////////////
  81. // [[GOPT_t]]
  82. typedef enum GOPT_t
  83. {
  84. GOPT_RESERVED_BEG = 0x01000000, // begin of reserved range
  85. GOPT_RESERVED_END = 0x02000000, // end of reserved range
  86. GOPT_M_INDEX = 0x000000ff, // mask to get the index
  87. GOPT_N_PARAM = 60, // max used index+1 = num of params
  88. GOPT_M_VALUE = 0x0003ff00, // mask for GOPT_T_PLUS|GOPT_T_MINUS
  89. GOPT_S_VALUE = 8, // value is shifted by this num
  90. GOPT_M_TYPE = 0x00fc0000, // mask to isolate option type
  91. GOPT_I_TYPE = 0x00040000, // increment between types
  92. GOPT_S_TYPE = 18, // type is shifted by this num
  93. //--- parameters by index (sn=signed num, un=unsigned num)
  94. GOPT_IDX_NULL = 0, // type undefined
  95. GOPT_IDX_INC, // increment 'sn', ptype := GOPT_T_INC
  96. GOPT_IDX_INC0, // increment 'sn', ptype := GOPT_T_INC
  97. GOPT_IDX_DEC, // decrement 'sn', ptype := GOPT_T_INC
  98. GOPT_IDX_DEC0, // decrement 'sn', ptype := GOPT_T_INC
  99. GOPT_IDX_SETP, // set 'sn' to value 0..0x3ff, ptype := GOPT_IDX_SINT
  100. GOPT_IDX_SETM, // set 'sn' to value -0..-0x3ff, ptype := GOPT_IDX_SINT
  101. GOPT_IDX_SETP64, // set 'sn64' to value 0..0x3ff, ptype := GOPT_IDX_S64
  102. GOPT_IDX_SETM64, // set 'sn64' to value -0..-0x3ff, ptype := GOPT_IDX_S64
  103. GOPT_IDX_OR, // set 'un' |= value 0..0x3ff, ptype := GOPT_IDX_UINT
  104. GOPT_IDX_SETBIT, // set bit VALUE in 'un', ptype := GOPT_IDX_UINT
  105. GOPT_IDX_BIT, // ana param and set/clear bit VALUE in 'un', ptype := GOPT_IDX_UINT
  106. GOPT_IDX_OR64, // set 'un64' |= value 0..0x3ff, ptype := GOPT_IDX_U64
  107. GOPT_IDX_SETBIT64, // set bit VALUE in 'un64', ptype := GOPT_IDX_UINT64
  108. GOPT_IDX_SINT, // scan signed integer
  109. GOPT_IDX_UINT, // scan unsigned integer
  110. GOPT_IDX_OFF_ON, // scan 'off|onn|0|1' and otional a number, ptype := GOPT_IDX_UINT
  111. GOPT_IDX_S64, // scan signed 64-bit integer
  112. GOPT_IDX_U64, // scan unsigned 64-bit integer
  113. GOPT_IDX_HEX, // scan unsigned 64-bit integer, assume hex
  114. GOPT_IDX_SIZE, // scan size (double with optional SI) and store as 'un64'
  115. GOPT_IDX_DOUBLE, // scan double float
  116. GOPT_IDX_DURATION, // scan duration (double with optional SI) and store as 'd'
  117. GOPT_IDX_STRING, // store ccp pointer to text
  118. GOPT_IDX_END, // end of parameters
  119. //--- parameters types
  120. GOPT_T_NULL = 0, // type undefined
  121. GOPT_T_INC = GOPT_RESERVED_BEG | ( GOPT_IDX_INC << GOPT_S_TYPE ),
  122. GOPT_T_INC0 = GOPT_RESERVED_BEG | ( GOPT_IDX_INC0 << GOPT_S_TYPE ),
  123. GOPT_T_DEC = GOPT_RESERVED_BEG | ( GOPT_IDX_DEC << GOPT_S_TYPE ),
  124. GOPT_T_DEC0 = GOPT_RESERVED_BEG | ( GOPT_IDX_DEC0 << GOPT_S_TYPE ),
  125. GOPT_T_SETP = GOPT_RESERVED_BEG | ( GOPT_IDX_SETP << GOPT_S_TYPE ),
  126. GOPT_T_SETM = GOPT_RESERVED_BEG | ( GOPT_IDX_SETM << GOPT_S_TYPE ),
  127. GOPT_T_SETP64 = GOPT_RESERVED_BEG | ( GOPT_IDX_SETP64 << GOPT_S_TYPE ),
  128. GOPT_T_SETM64 = GOPT_RESERVED_BEG | ( GOPT_IDX_SETM64 << GOPT_S_TYPE ),
  129. GOPT_T_OR = GOPT_RESERVED_BEG | ( GOPT_IDX_OR << GOPT_S_TYPE ),
  130. GOPT_T_SETBIT = GOPT_RESERVED_BEG | ( GOPT_IDX_SETBIT << GOPT_S_TYPE ),
  131. GOPT_T_BIT = GOPT_RESERVED_BEG | ( GOPT_IDX_BIT << GOPT_S_TYPE ),
  132. GOPT_T_OR64 = GOPT_RESERVED_BEG | ( GOPT_IDX_OR64 << GOPT_S_TYPE ),
  133. GOPT_T_SETBIT64 = GOPT_RESERVED_BEG | ( GOPT_IDX_SETBIT64 << GOPT_S_TYPE ),
  134. GOPT_T_SINT = GOPT_RESERVED_BEG | ( GOPT_IDX_SINT << GOPT_S_TYPE ),
  135. GOPT_T_UINT = GOPT_RESERVED_BEG | ( GOPT_IDX_UINT << GOPT_S_TYPE ),
  136. GOPT_T_OFF_ON = GOPT_RESERVED_BEG | ( GOPT_IDX_OFF_ON << GOPT_S_TYPE ),
  137. GOPT_T_S64 = GOPT_RESERVED_BEG | ( GOPT_IDX_S64 << GOPT_S_TYPE ),
  138. GOPT_T_U64 = GOPT_RESERVED_BEG | ( GOPT_IDX_U64 << GOPT_S_TYPE ),
  139. GOPT_T_HEX = GOPT_RESERVED_BEG | ( GOPT_IDX_HEX << GOPT_S_TYPE ),
  140. GOPT_T_SIZE = GOPT_RESERVED_BEG | ( GOPT_IDX_SIZE << GOPT_S_TYPE ),
  141. GOPT_T_DOUBLE = GOPT_RESERVED_BEG | ( GOPT_IDX_DOUBLE << GOPT_S_TYPE ),
  142. GOPT_T_DURATION = GOPT_RESERVED_BEG | ( GOPT_IDX_DURATION << GOPT_S_TYPE ),
  143. GOPT_T_STRING = GOPT_RESERVED_BEG | ( GOPT_IDX_STRING << GOPT_S_TYPE ),
  144. GOPT_T_END = GOPT_RESERVED_BEG | ( GOPT_IDX_END << GOPT_S_TYPE ),
  145. //--- named options
  146. GOPT_O__BEGIN = 0x100,
  147. GOPT_O_TEST_OPT, // test: print all defined options: --@opt
  148. GOPT_O_HELP, // force help
  149. GOPT_O_CLEAR, // clear screen -> ScanGOptionsHelperTN()
  150. GOPT_O_PAGER, // activate pager -> ScanGOptionsHelperTN()
  151. GOPT_O_WIDTH, // limit terminal width -> ScanGOptionsHelperTN()
  152. GOPT_O_QUIT, // quit if command done -> ScanGOptionsHelperTN()
  153. GOPT_O_QUIET, // be quiet
  154. GOPT_O_VERBOSE, // be verbose, or set by --verbose=#
  155. GOPT_O_DEBUG, // increment debug level, or set by --debug=#
  156. GOPT_O__CONTINUE // continue with this value on more options
  157. }
  158. GOPT_t;
  159. static inline GOPT_t GetGOPType ( GOPT_t gt )
  160. { return ( gt & GOPT_M_TYPE ) >> GOPT_S_TYPE; }
  161. //
  162. ///////////////////////////////////////////////////////////////////////////////
  163. /////////////// global options: parameters ///////////////
  164. ///////////////////////////////////////////////////////////////////////////////
  165. // [[GParamValueType_t]]
  166. typedef enum GParamValueType_t
  167. {
  168. GPT_NONE, // no param set
  169. GPT_SN, // value stored as 'sn'
  170. GPT_UN, // value stored as 'un'
  171. GPT_SN64, // value stored as 'sn64'
  172. GPT_UN64, // value stored as 'un64'
  173. GPT_D, // value stored as 'd'
  174. GPT_STR, // value stored as 'str'
  175. GPT_BIT, // value stored as 'bit.val' & 'bit.mask'
  176. }
  177. GParamValueType_t;
  178. GParamValueType_t GetGParamValueType ( GOPT_t gt );
  179. ///////////////////////////////////////////////////////////////////////////////
  180. // [[GParam_t]]
  181. typedef struct GParam_t
  182. {
  183. u16 ptype; // GOPT_IDX_*
  184. u16 vtype; // GParamValueType_t
  185. union
  186. {
  187. int sn; // used by GOPT_T_INC*, GOPT_T_DEC*, GOPT_T_SINT
  188. uint un; // used by GOPT_T_UINT
  189. s64 sn64; // used by GOPT_T_S64, GOPT_T_SETM
  190. u64 un64; // used by GOPT_T_U64, GOPT_T_HEX, GOPT_T_SIZE, GOPT_T_SETP
  191. double d; // used by GOPT_T_DOUBLE, GOPT_T_DURATION
  192. ccp str; // used by GOPT_T_STRING
  193. struct { u32 val; u32 mask; } bit;
  194. // used by GOPT_T_BIT
  195. };
  196. }
  197. GParam_t;
  198. ///////////////////////////////////////////////////////////////////////////////
  199. // [[GetGParam_t]]
  200. typedef enum GetGParam_t
  201. {
  202. GGP_NONE = 0, // no param set or param unusable, 'return_val' is untouched
  203. GGP_CONVERT, // param set, but converted (different numeric type)
  204. GGP_SIGN, // param returned, but sign maybe converted
  205. GGP_OK // original or extended param returned
  206. }
  207. GetGParam_t;
  208. // If gp==NULL: return GGP_NONE
  209. // If return_val==NULL: analyse only
  210. GetGParam_t GetGParamINT ( const GParam_t *par, int *return_val );
  211. GetGParam_t GetGParamUINT ( const GParam_t *par, uint *return_val );
  212. GetGParam_t GetGParamS64 ( const GParam_t *par, s64 *return_val );
  213. GetGParam_t GetGParamU64 ( const GParam_t *par, u64 *return_val );
  214. GetGParam_t GetGParamDBL ( const GParam_t *par, double *return_val );
  215. GetGParam_t GetGParamCCP ( const GParam_t *par, ccp *return_val );
  216. GetGParam_t GetGParamBIT ( const GParam_t *par, u32 *return_val, u32 *return_mask );
  217. ccp PrintGParam ( const GParam_t *par );
  218. //
  219. ///////////////////////////////////////////////////////////////////////////////
  220. /////////////// global options ///////////////
  221. ///////////////////////////////////////////////////////////////////////////////
  222. // [[GOptions_t]]
  223. typedef struct GOptions_t
  224. {
  225. //--- parameters
  226. int argc; // number of parameters
  227. char **argv; // parameters without options
  228. //--- named options
  229. int help; // number of GOPT_O_HELP
  230. int clear; // number of GOPT_O_CLEAR
  231. int pager; // number of GOPT_O_PAGER
  232. int quit; // number of GOPT_O_QUIT
  233. int debug; // number of GOPT_O_DEBUG
  234. int verbose; // combi of GOPT_O_QUIET & GOPT_O_VERBOSE
  235. int max_width; // max terminal width
  236. int width; // terminal width
  237. //--- generic parameter support
  238. GParam_t param[GOPT_N_PARAM];
  239. }
  240. GOptions_t;
  241. //-----------------------------------------------------------------------------
  242. #define GOOD_INFO_MAX_WIDTH 120
  243. static inline void InitializeGOptions ( GOptions_t *go, int max_width )
  244. {
  245. DASSERT(go);
  246. memset(go,0,sizeof(*go));
  247. go->max_width = max_width;
  248. go->width = max_width < GOOD_INFO_MAX_WIDTH ? max_width : GOOD_INFO_MAX_WIDTH;
  249. }
  250. static inline const GParam_t * GetGParam ( const GOptions_t *go, uint par_index )
  251. { return go && par_index < GOPT_N_PARAM ? go->param+par_index : 0; }
  252. ///////////////////////////////////////////////////////////////////////////////
  253. extern const GenericOptParm_t StandardGOptions[];
  254. ///////////////////////////////////////////////////////////////////////////////
  255. ///////////////////////////////////////////////////////////////////////////////
  256. typedef int (*ScanOptionFunc)
  257. (
  258. // returns: 0 on not procecced / <0 on error / >0 on success
  259. GenericOpt_t *go, // valid pointer to generic options
  260. GOptions_t *gopt, // valid pointer to options data
  261. void *any_ptr, // user specific pointer
  262. int num, // numeric param:
  263. // OnAddOptions(): 'scan_opt'
  264. // OnOption(): option id
  265. // OnArgument(): argument index
  266. ccp arg // NULL or text argument
  267. );
  268. ///////////////////////////////////////////////////////////////////////////////
  269. // [[ScanGOpt_t]]
  270. typedef enum ScanGOpt_t
  271. {
  272. SGO_KNOWN = 0x0001, // scan only until first unknown parameter
  273. SGO_PAGER = 0x0002, // auto enable pager
  274. SGO__CONTINUE = 0x0004 // define more flags based on this value
  275. }
  276. ScanGOpt_t;
  277. ///////////////////////////////////////////////////////////////////////////////
  278. enumError ScanGOptionsHelper
  279. (
  280. GOptions_t *gopt, // valid pointer
  281. GenericOpt_t *go, // NULL or list with options
  282. // => ResetGenericOpt() is called at finish
  283. int argc, // argument counter
  284. char **argv, // list of arguments
  285. int max_param, // >=0: max allowed parameters
  286. ScanGOpt_t scan_opt, // scan options
  287. //--- call back functions
  288. ScanOptionFunc OnAddOptions, // not NULL: called once to add options
  289. ScanOptionFunc OnOption, // not NULL: called for each option
  290. ScanOptionFunc OnArgument, // not NULL: called for each argument
  291. void *any_ptr // NULL or user specific pointer for call back
  292. );
  293. //-----------------------------------------------------------------------------
  294. enumError ScanGOptionsHelperTN
  295. (
  296. // like ScanGOptionsHelper(), but with TELNET support
  297. // for 'gopt->clear', 'gopt->pager' and 'gopt->quit',
  298. // if 'ts' is not NULL and telnet is active.
  299. GOptions_t *gopt, // valid pointer
  300. GenericOpt_t *go, // NULL or list with options
  301. // => ResetGenericOpt() is called at finish
  302. int argc, // argument counter
  303. char **argv, // list of arguments
  304. int max_param, // >=0: max allowed parameters
  305. ScanGOpt_t scan_opt, // scan options
  306. struct TCPStream_t *ts, // NULL or current stream with TELNET support
  307. //--- call back functions
  308. ScanOptionFunc OnAddOptions, // not NULL: called once to add options
  309. ScanOptionFunc OnOption, // not NULL: called for each option
  310. ScanOptionFunc OnArgument, // not NULL: called for each argument
  311. void *any_ptr // NULL or user specific pointer for call back
  312. );
  313. //
  314. ///////////////////////////////////////////////////////////////////////////////
  315. /////////////// E N D ///////////////
  316. ///////////////////////////////////////////////////////////////////////////////
  317. #endif // DCLIB_OPTION_H