opts-parser.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. char **ignored_words =
  31. bmalloc(input_option_count * sizeof(*ignored_words));
  32. char **ignored_word = ignored_words;
  33. struct obs_option *out_options =
  34. bmalloc(input_option_count * sizeof(*out_options));
  35. struct obs_option *out_option = out_options;
  36. for (char **input_word = input_words; *input_word; ++input_word) {
  37. if (getparam(*input_word, &out_option->name,
  38. (const char **)&out_option->value)) {
  39. ++out_option;
  40. } else {
  41. *ignored_word = *input_word;
  42. ++ignored_word;
  43. }
  44. }
  45. return (struct obs_options){
  46. .count = out_option - out_options,
  47. .options = out_options,
  48. .ignored_word_count = ignored_word - ignored_words,
  49. .ignored_words = ignored_words,
  50. .input_words = input_words,
  51. };
  52. failure:
  53. return (struct obs_options){
  54. .count = 0,
  55. .options = NULL,
  56. .ignored_word_count = 0,
  57. .ignored_words = NULL,
  58. .input_words = NULL,
  59. };
  60. }
  61. void obs_free_options(struct obs_options options)
  62. {
  63. for (size_t i = 0; i < options.count; ++i) {
  64. bfree(options.options[i].name);
  65. }
  66. bfree(options.options);
  67. bfree(options.ignored_words);
  68. strlist_free(options.input_words);
  69. }