1
0

opts-parser.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <stdbool.h>
  2. #include <stddef.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <util/bmem.h>
  6. #include <util/dstr.h>
  7. #include "opts-parser.h"
  8. static bool getparam(const char *param, char **name, const char **value)
  9. {
  10. const char *assign;
  11. if (!param || !*param || (*param == '='))
  12. return false;
  13. assign = strchr(param, '=');
  14. if (!assign || !*assign || !*(assign + 1))
  15. return false;
  16. *name = bstrdup_n(param, assign - param);
  17. *value = assign + 1;
  18. return true;
  19. }
  20. struct obs_options obs_parse_options(const char *options_string)
  21. {
  22. if (!options_string || !*options_string)
  23. goto failure;
  24. char **input_words = strlist_split(options_string, ' ', false);
  25. if (!input_words)
  26. goto failure;
  27. size_t input_option_count = 0;
  28. for (char **input_word = input_words; *input_word; ++input_word)
  29. input_option_count += 1;
  30. if (!input_option_count) {
  31. strlist_free(input_words);
  32. goto failure;
  33. }
  34. char **ignored_words = bmalloc(input_option_count * sizeof(*ignored_words));
  35. char **ignored_word = ignored_words;
  36. struct obs_option *out_options = bmalloc(input_option_count * sizeof(*out_options));
  37. struct obs_option *out_option = out_options;
  38. for (char **input_word = input_words; *input_word; ++input_word) {
  39. if (getparam(*input_word, &out_option->name, (const char **)&out_option->value)) {
  40. ++out_option;
  41. } else {
  42. *ignored_word = *input_word;
  43. ++ignored_word;
  44. }
  45. }
  46. return (struct obs_options){
  47. .count = out_option - out_options,
  48. .options = out_options,
  49. .ignored_word_count = ignored_word - ignored_words,
  50. .ignored_words = ignored_words,
  51. .input_words = input_words,
  52. };
  53. failure:
  54. return (struct obs_options){
  55. .count = 0,
  56. .options = NULL,
  57. .ignored_word_count = 0,
  58. .ignored_words = NULL,
  59. .input_words = NULL,
  60. };
  61. }
  62. void obs_free_options(struct obs_options options)
  63. {
  64. for (size_t i = 0; i < options.count; ++i) {
  65. bfree(options.options[i].name);
  66. }
  67. bfree(options.options);
  68. bfree(options.ignored_words);
  69. strlist_free(options.input_words);
  70. }