helpers.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <ccan/opt/opt.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include "private.h"
  7. /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
  8. #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
  9. /* FIXME: asprintf module? */
  10. static char *arg_bad(const char *fmt, const char *arg)
  11. {
  12. char *str = malloc(strlen(fmt) + strlen(arg));
  13. sprintf(str, fmt, arg);
  14. return str;
  15. }
  16. char *opt_set_bool(bool *b)
  17. {
  18. *b = true;
  19. return NULL;
  20. }
  21. char *opt_set_false(bool *b)
  22. {
  23. *b = false;
  24. return NULL;
  25. }
  26. char *opt_set_invbool(bool *b)
  27. {
  28. *b = false;
  29. return NULL;
  30. }
  31. char *opt_set_bool_arg(const char *arg, bool *b)
  32. {
  33. if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
  34. return opt_set_bool(b);
  35. if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
  36. return opt_set_invbool(b);
  37. return opt_invalid_argument(arg);
  38. }
  39. char *opt_set_invbool_arg(const char *arg, bool *b)
  40. {
  41. char *err = opt_set_bool_arg(arg, b);
  42. if (!err)
  43. *b = !*b;
  44. return err;
  45. }
  46. /* Set a char *. */
  47. char *opt_set_charp(const char *arg, char **p)
  48. {
  49. *p = (char *)arg;
  50. return NULL;
  51. }
  52. /* Set an integer value, various forms. Sets to 1 on arg == NULL. */
  53. char *opt_set_intval(const char *arg, int *i)
  54. {
  55. long l;
  56. char *err = opt_set_longval(arg, &l);
  57. if (err)
  58. return err;
  59. *i = l;
  60. /* Beware truncation... */
  61. if (*i != l)
  62. return arg_bad("value '%s' does not fit into an integer", arg);
  63. return err;
  64. }
  65. char *opt_set_floatval(const char *arg, float *f)
  66. {
  67. char *endp;
  68. errno = 0;
  69. *f = strtof(arg, &endp);
  70. if (*endp || !arg[0])
  71. return arg_bad("'%s' is not a number", arg);
  72. if (errno)
  73. return arg_bad("'%s' is out of range", arg);
  74. return NULL;
  75. }
  76. char *opt_set_uintval(const char *arg, unsigned int *ui)
  77. {
  78. int i;
  79. char *err = opt_set_intval(arg, &i);
  80. if (err)
  81. return err;
  82. if (i < 0)
  83. return arg_bad("'%s' is negative", arg);
  84. *ui = i;
  85. return NULL;
  86. }
  87. char *opt_set_longval(const char *arg, long *l)
  88. {
  89. char *endp;
  90. /* This is how the manpage says to do it. Yech. */
  91. errno = 0;
  92. *l = strtol(arg, &endp, 0);
  93. if (*endp || !arg[0])
  94. return arg_bad("'%s' is not a number", arg);
  95. if (errno)
  96. return arg_bad("'%s' is out of range", arg);
  97. return NULL;
  98. }
  99. char *opt_set_ulongval(const char *arg, unsigned long *ul)
  100. {
  101. long int l;
  102. char *err;
  103. err = opt_set_longval(arg, &l);
  104. if (err)
  105. return err;
  106. *ul = l;
  107. if (l < 0)
  108. return arg_bad("'%s' is negative", arg);
  109. return NULL;
  110. }
  111. char *opt_inc_intval(int *i)
  112. {
  113. (*i)++;
  114. return NULL;
  115. }
  116. /* Display version string. */
  117. char *opt_version_and_exit(const char *version)
  118. {
  119. printf("%s\n", version);
  120. fflush(stdout);
  121. exit(0);
  122. }
  123. char *opt_usage_and_exit(const char *extra)
  124. {
  125. printf("%s", opt_usage(opt_argv0, extra));
  126. fflush(stdout);
  127. exit(0);
  128. }
  129. void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
  130. {
  131. strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
  132. }
  133. void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
  134. {
  135. strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
  136. }
  137. void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
  138. {
  139. size_t len = strlen(*p);
  140. buf[0] = '"';
  141. if (len > OPT_SHOW_LEN - 2)
  142. len = OPT_SHOW_LEN - 2;
  143. strncpy(buf+1, *p, len);
  144. buf[1+len] = '"';
  145. if (len < OPT_SHOW_LEN - 2)
  146. buf[2+len] = '\0';
  147. }
  148. /* Set an integer value, various forms. Sets to 1 on arg == NULL. */
  149. void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
  150. {
  151. snprintf(buf, OPT_SHOW_LEN, "%i", *i);
  152. }
  153. void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
  154. {
  155. snprintf(buf, OPT_SHOW_LEN, "%.1f", *f);
  156. }
  157. void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
  158. {
  159. snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
  160. }
  161. void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
  162. {
  163. snprintf(buf, OPT_SHOW_LEN, "%li", *l);
  164. }
  165. void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
  166. {
  167. snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
  168. }