Xeon-SP boards: Factor out OCP VPD `get_cxl_mode()` impl
[coreboot2.git] / util / cbfstool / flashmap / kv_pair.c
blob5d033b3be19bb8e07a535891ac4de2fa778b851f
1 /* SPDX-License-Identifier: BSD-3-Clause or GPL-2.0-only */
3 #include <stdlib.h>
4 #include <stdarg.h>
6 #include "kv_pair.h"
8 /* Internal variable for output style. Use accessors to get/set style. */
9 static enum kv_pair_style _style;
11 void kv_pair_set_style(enum kv_pair_style style)
13 _style = style;
16 enum kv_pair_style kv_pair_get_style(void)
18 return _style;
21 struct kv_pair *kv_pair_new(void)
23 struct kv_pair *kv;
25 kv = calloc(1, sizeof(*kv));
26 if (!kv)
27 return NULL;
29 return kv;
32 struct kv_pair *kv_pair_add(struct kv_pair *kv_list,
33 const char *key, const char *value)
35 struct kv_pair *kv_new;
36 struct kv_pair *kv_ptr;
38 kv_new = kv_pair_new();
39 if (!kv_new)
40 return NULL;
42 /* save key=value strings if provided */
43 if (key) {
44 kv_new->key = strdup(key);
45 if (!kv_new->key)
46 goto kv_pair_add_failed;
48 if (value) {
49 kv_new->value = strdup(value);
50 if (!kv_new->value)
51 goto kv_pair_add_failed;
54 /* first in the list if no list provided */
55 if (kv_list) {
56 /* find the end of list */
57 for (kv_ptr = kv_list; kv_ptr->next != NULL;
58 kv_ptr = kv_ptr->next)
61 /* link in the new pair at the end */
62 kv_ptr->next = kv_new;
65 /* return pointer to the new pair */
66 return kv_new;
68 kv_pair_add_failed:
69 kv_pair_free(kv_new);
70 return NULL;
73 struct kv_pair *kv_pair_add_bool(struct kv_pair *kv_list,
74 const char *key, int value)
76 const char *str;
78 if (value) {
79 str = "yes";
80 } else {
81 str = "no";
83 return kv_pair_add(kv_list, key, str);
86 struct kv_pair *kv_pair_fmt(struct kv_pair *kv_list,
87 const char *kv_key, const char *format, ...)
89 char kv_value[KV_PAIR_MAX_VALUE_LEN];
90 va_list vptr;
92 memset(kv_value, 0, sizeof(kv_value));
94 va_start(vptr, format);
95 vsnprintf(kv_value, sizeof(kv_value), format, vptr);
96 va_end(vptr);
98 return kv_pair_add(kv_list, kv_key, kv_value);
101 void kv_pair_free(struct kv_pair *kv_list)
103 struct kv_pair *kv_ptr = kv_list;
104 struct kv_pair *kv_next;
106 while (kv_ptr != NULL) {
107 /* free key/value strings */
108 if (kv_ptr->key)
109 free(kv_ptr->key);
110 if (kv_ptr->value)
111 free(kv_ptr->value);
113 /* free current pair move to next */
114 kv_next = kv_ptr->next;
115 free(kv_ptr);
116 kv_ptr = kv_next;
120 void kv_pair_print_to_file(FILE* fp, struct kv_pair *kv_list,
121 enum kv_pair_style style)
123 struct kv_pair *kv_ptr;
125 switch (style) {
126 case KV_STYLE_PAIR:
127 for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) {
128 if (kv_ptr->key && kv_ptr->value) {
129 fprintf(fp, "%s=\"%s\" ",
130 kv_ptr->key, kv_ptr->value);
133 break;
135 case KV_STYLE_VALUE:
136 for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) {
137 if (kv_ptr->value) {
138 fprintf(fp, "%s", kv_ptr->value);
139 if (kv_ptr->next)
140 fprintf(fp, " | ");
143 break;
145 case KV_STYLE_LONG:
146 for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) {
147 if (kv_ptr->key && kv_ptr->value)
148 fprintf(fp, "%-20s | %s\n",
149 kv_ptr->key, kv_ptr->value);
151 break;
154 fprintf(fp, "\n");
157 void kv_pair_print(struct kv_pair *kv_list)
159 kv_pair_print_to_file(stdout, kv_list, kv_pair_get_style());
162 const char *kv_pair_get_value(struct kv_pair *kv_list, const char *kv_key)
164 const char *kv_value = NULL;
165 struct kv_pair *kv_ptr;
167 for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) {
168 if (kv_ptr->key && strcmp(kv_ptr->key, kv_key) == 0) {
169 kv_value = kv_ptr->value;
170 break;
173 return kv_value;
176 int kv_pair_size(struct kv_pair *kv_list) {
177 struct kv_pair *kv_ptr;
178 int count;
180 count = 0;
181 for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) {
182 if (kv_ptr->key) {
183 count++;
186 return count;