1d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#define LOG_TAG "bt_osi_config"
2d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
3d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include <assert.h>
4d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include <ctype.h>
5d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include <stdio.h>
6d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include <stdlib.h>
7d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include <string.h>
8d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include <utils/Log.h>
9d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
10d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include "config.h"
11d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati#include "list.h"
12d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
13d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatitypedef struct {
14d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char *key;
15d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char *value;
16d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati} entry_t;
17d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
18d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatitypedef struct {
19d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char *name;
20d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  list_t *entries;
21d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati} section_t;
22d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
23d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistruct config_t {
24d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  list_t *sections;
25d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati};
26d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
27d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic void config_parse(FILE *fp, config_t *config);
28d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
29d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic section_t *section_new(const char *name);
30d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic void section_free(void *ptr);
31d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic section_t *section_find(const config_t *config, const char *section);
32d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
33d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic entry_t *entry_new(const char *key, const char *value);
34d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic void entry_free(void *ptr);
35d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic entry_t *entry_find(const config_t *config, const char *section, const char *key);
36d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
37d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavaticonfig_t *config_new(const char *filename) {
38d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(filename != NULL);
39d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
40d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  FILE *fp = fopen(filename, "rt");
41d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!fp) {
42d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    ALOGE("%s unable to open file '%s': %s", __func__, filename, strerror(errno));
43d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return NULL;
44d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
45d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
46d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  config_t *config = calloc(1, sizeof(config_t));
47d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!config) {
48d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    ALOGE("%s unable to allocate memory for config_t.", __func__);
49d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    fclose(fp);
50d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return NULL;
51d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
52d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
53d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  config->sections = list_new(section_free);
54d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  config_parse(fp, config);
55d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
56d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  fclose(fp);
57d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
58d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return config;
59d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
60d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
61d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavativoid config_free(config_t *config) {
62d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!config)
63d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return;
64d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
65d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  list_free(config->sections);
66d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  free(config);
67d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
68d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
69d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatibool config_has_section(const config_t *config, const char *section) {
70d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
71d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
72d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
73d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return (section_find(config, section) != NULL);
74d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
75d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
76d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatibool config_has_key(const config_t *config, const char *section, const char *key) {
77d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
78d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
79d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(key != NULL);
80d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
81d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return (entry_find(config, section, key) != NULL);
82d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
83d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
84d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatiint config_get_int(const config_t *config, const char *section, const char *key, int def_value) {
85d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
86d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
87d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(key != NULL);
88d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
89d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry_t *entry = entry_find(config, section, key);
90d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!entry)
91d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return def_value;
92d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
93d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char *endptr;
94d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  int ret = strtol(entry->value, &endptr, 0);
95d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return (*endptr == '\0') ? ret : def_value;
96d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
97d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
98d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatibool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value) {
99d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
100d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
101d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(key != NULL);
102d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
103d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry_t *entry = entry_find(config, section, key);
104d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!entry)
105d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return def_value;
106d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
107d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!strcmp(entry->value, "true"))
108d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return true;
109d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!strcmp(entry->value, "false"))
110d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return false;
111d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
112d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return def_value;
113d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
114d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
115d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavaticonst char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value) {
116d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
117d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
118d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(key != NULL);
119d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
120d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry_t *entry = entry_find(config, section, key);
121d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!entry)
122d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return def_value;
123d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
124d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return entry->value;
125d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
126d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
127d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavativoid config_set_int(config_t *config, const char *section, const char *key, int value) {
128d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
129d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
130d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(key != NULL);
131d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
132d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char value_str[32] = { 0 };
133d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  sprintf(value_str, "%d", value);
134d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  config_set_string(config, section, key, value_str);
135d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
136d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
137d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavativoid config_set_bool(config_t *config, const char *section, const char *key, bool value) {
138d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
139d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(section != NULL);
140d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(key != NULL);
141d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
142d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  config_set_string(config, section, key, value ? "true" : "false");
143d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
144d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
145d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavativoid config_set_string(config_t *config, const char *section, const char *key, const char *value) {
146d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  section_t *sec = section_find(config, section);
147d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!sec) {
148d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    sec = section_new(section);
149d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    list_append(config->sections, sec);
150d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
151d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
152d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) {
153d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    entry_t *entry = list_node(node);
154d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    if (!strcmp(entry->key, key)) {
155d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      free(entry->value);
156d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      entry->value = strdup(value);
157d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      return;
158d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    }
159d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
160d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
161d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry_t *entry = entry_new(key, value);
162d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  list_append(sec->entries, entry);
163d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
164d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
165d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic char *trim(char *str) {
166d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  while (isspace(*str))
167d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    ++str;
168d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
169d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!*str)
170d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return str;
171d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
172d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char *end_str = str + strlen(str) - 1;
173d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  while (end_str > str && isspace(*end_str))
174d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    --end_str;
175d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
176d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  end_str[1] = '\0';
177d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return str;
178d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
179d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
180d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic void config_parse(FILE *fp, config_t *config) {
181d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(fp != NULL);
182d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  assert(config != NULL);
183d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
184d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  int line_num = 0;
185d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char line[1024];
186d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  char section[1024];
187d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  strcpy(section, CONFIG_DEFAULT_SECTION);
188d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
189d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  while (fgets(line, sizeof(line), fp)) {
190d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    char *line_ptr = trim(line);
191d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    ++line_num;
192d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
193d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    // Skip blank and comment lines.
194d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    if (*line_ptr == '\0' || *line_ptr == '#')
195d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      continue;
196d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
197d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    if (*line_ptr == '[') {
198d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      size_t len = strlen(line_ptr);
199d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      if (line_ptr[len - 1] != ']') {
200d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati        ALOGD("%s unterminated section name on line %d.", __func__, line_num);
201d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati        continue;
202d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      }
203d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      strncpy(section, line_ptr + 1, len - 2);
204d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      section[len - 2] = '\0';
205d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    } else {
206d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      char *split = strchr(line_ptr, '=');
207d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      if (!split) {
208d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati        ALOGD("%s no key/value separator found on line %d.", __func__, line_num);
209d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati        continue;
210d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      }
211d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
212d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      *split = '\0';
213d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      config_set_string(config, section, trim(line_ptr), trim(split + 1));
214d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    }
215d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
216d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
217d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
218d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic section_t *section_new(const char *name) {
219d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  section_t *section = calloc(1, sizeof(section_t));
220d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!section)
221d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return NULL;
222d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
223d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  section->name = strdup(name);
224d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  section->entries = list_new(entry_free);
225d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return section;
226d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
227d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
228d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic void section_free(void *ptr) {
229d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!ptr)
230d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return;
231d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
232d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  section_t *section = ptr;
233d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  free(section->name);
234d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  list_free(section->entries);
235d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
236d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
237d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic section_t *section_find(const config_t *config, const char *section) {
238d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
239d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    section_t *sec = list_node(node);
240d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    if (!strcmp(sec->name, section))
241d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      return sec;
242d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
243d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
244d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return NULL;
245d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
246d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
247d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic entry_t *entry_new(const char *key, const char *value) {
248d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry_t *entry = calloc(1, sizeof(entry_t));
249d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!entry)
250d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return NULL;
251d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
252d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry->key = strdup(key);
253d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry->value = strdup(value);
254d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return entry;
255d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
256d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
257d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic void entry_free(void *ptr) {
258d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!ptr)
259d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return;
260d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
261d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  entry_t *entry = ptr;
262d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  free(entry->key);
263d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  free(entry->value);
264d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
265d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
266d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavatistatic entry_t *entry_find(const config_t *config, const char *section, const char *key) {
267d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  section_t *sec = section_find(config, section);
268d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  if (!sec)
269d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    return NULL;
270d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
271d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) {
272d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    entry_t *entry = list_node(node);
273d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati    if (!strcmp(entry->key, key))
274d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati      return entry;
275d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  }
276d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati
277d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati  return NULL;
278d1c453f4f9648bb5eef80df106e79e3f916f301cSharvil Nanavati}
279