You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.8KB

  1. #include "osdialog.h"
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. static char *strndup_better(const char *s, int n) {
  6. char *d = malloc(n + 1);
  7. memcpy(d, s, n);
  8. d[n] = '\0';
  9. return d;
  10. }
  11. osdialog_filters *osdialog_filters_parse(const char *str) {
  12. osdialog_filters *filters_head = malloc(sizeof(osdialog_filters));
  13. filters_head->next = NULL;
  14. osdialog_filters *filters = filters_head;
  15. osdialog_filter_patterns *patterns = NULL;
  16. const char *text = str;
  17. while (1) {
  18. switch (*str) {
  19. case ':': {
  20. filters->name = strndup_better(text, str - text);
  21. filters->patterns = malloc(sizeof(osdialog_filter_patterns));
  22. patterns = filters->patterns;
  23. patterns->next = NULL;
  24. text = str + 1;
  25. } break;
  26. case ',': {
  27. assert(patterns);
  28. patterns->pattern = strndup_better(text, str - text);
  29. patterns->next = malloc(sizeof(osdialog_filter_patterns));
  30. patterns = patterns->next;
  31. patterns->next = NULL;
  32. text = str + 1;
  33. } break;
  34. case ';': {
  35. assert(patterns);
  36. patterns->pattern = strndup_better(text, str - text);
  37. filters->next = malloc(sizeof(osdialog_filters));
  38. filters = filters->next;
  39. filters->next = NULL;
  40. patterns = NULL;
  41. text = str + 1;
  42. } break;
  43. case '\0': {
  44. assert(patterns);
  45. patterns->pattern = strndup_better(text, str - text);
  46. } break;
  47. default: break;
  48. }
  49. if (!*str)
  50. break;
  51. str++;
  52. }
  53. return filters_head;
  54. }
  55. static void patterns_free(osdialog_filter_patterns *patterns) {
  56. if (!patterns)
  57. return;
  58. free(patterns->pattern);
  59. osdialog_filter_patterns *next = patterns->next;
  60. free(patterns);
  61. patterns_free(next);
  62. }
  63. void osdialog_filters_free(osdialog_filters *filters) {
  64. if (!filters)
  65. return;
  66. free(filters->name);
  67. patterns_free(filters->patterns);
  68. osdialog_filters *next = filters->next;
  69. free(filters);
  70. osdialog_filters_free(next);
  71. }