helpers.c.bak 3.7 KB

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