helpers.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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_uintval(const char *arg, unsigned int *ui)
  61. {
  62. int i;
  63. char *err = opt_set_intval(arg, &i);
  64. if (err)
  65. return err;
  66. if (i < 0)
  67. return arg_bad("'%s' is negative", arg);
  68. *ui = i;
  69. return NULL;
  70. }
  71. char *opt_set_longval(const char *arg, long *l)
  72. {
  73. char *endp;
  74. /* This is how the manpage says to do it. Yech. */
  75. errno = 0;
  76. *l = strtol(arg, &endp, 0);
  77. if (*endp || !arg[0])
  78. return arg_bad("'%s' is not a number", arg);
  79. if (errno)
  80. return arg_bad("'%s' is out of range", arg);
  81. return NULL;
  82. }
  83. char *opt_set_ulongval(const char *arg, unsigned long *ul)
  84. {
  85. long int l;
  86. char *err;
  87. err = opt_set_longval(arg, &l);
  88. if (err)
  89. return err;
  90. *ul = l;
  91. if (l < 0)
  92. return arg_bad("'%s' is negative", arg);
  93. return NULL;
  94. }
  95. char *opt_inc_intval(int *i)
  96. {
  97. (*i)++;
  98. return NULL;
  99. }
  100. /* Display version string. */
  101. char *opt_version_and_exit(const char *version)
  102. {
  103. printf("%s\n", version);
  104. exit(0);
  105. }
  106. char *opt_usage_and_exit(const char *extra)
  107. {
  108. printf("%s", opt_usage(opt_argv0, extra));
  109. exit(0);
  110. }
  111. void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
  112. {
  113. strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
  114. }
  115. void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
  116. {
  117. strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
  118. }
  119. void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
  120. {
  121. size_t len = strlen(*p);
  122. buf[0] = '"';
  123. if (len > OPT_SHOW_LEN - 2)
  124. len = OPT_SHOW_LEN - 2;
  125. strncpy(buf+1, *p, len);
  126. buf[1+len] = '"';
  127. if (len < OPT_SHOW_LEN - 2)
  128. buf[2+len] = '\0';
  129. }
  130. /* Set an integer value, various forms. Sets to 1 on arg == NULL. */
  131. void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
  132. {
  133. snprintf(buf, OPT_SHOW_LEN, "%i", *i);
  134. }
  135. void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
  136. {
  137. snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
  138. }
  139. void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
  140. {
  141. snprintf(buf, OPT_SHOW_LEN, "%li", *l);
  142. }
  143. void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
  144. {
  145. snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
  146. }