opts-parser.c 1.8 KB

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