mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	bootconfig: Support mixing a value and subkeys under a key
Support mixing a value and subkeys under a key. Since kernel cmdline
options will support "aaa.bbb=value1 aaa.bbb.ccc=value2", it is
better that the bootconfig supports such configuration too.
Note that this does not change syntax itself but just accepts
mixed value and subkeys e.g.
key = value1
key.subkey = value2
But this is not accepted;
key {
 value1
 subkey = value2
}
That will make value1 as a subkey.
Also, the order of the value node under a key is fixed. If there
are a value and subkeys, the value is always the first child node
of the key. Thus if user specifies subkeys first, e.g.
key.subkey = value1
key = value2
In the program (and /proc/bootconfig), it will be shown as below
key = value2
key.subkey = value1
Link: https://lkml.kernel.org/r/162262194685.264090.7738574774030567419.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
			
			
This commit is contained in:
		
							parent
							
								
									ca24306d83
								
							
						
					
					
						commit
						e5efaeb8a8
					
				
					 3 changed files with 115 additions and 29 deletions
				
			
		| 
						 | 
					@ -80,6 +80,8 @@ static inline __init bool xbc_node_is_array(struct xbc_node *node)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Test the @node is a leaf key node which is a key node and has a value node
 | 
					 * Test the @node is a leaf key node which is a key node and has a value node
 | 
				
			||||||
 * or no child. Returns true if it is a leaf node, or false if not.
 | 
					 * or no child. Returns true if it is a leaf node, or false if not.
 | 
				
			||||||
 | 
					 * Note that the leaf node can have subkey nodes in addition to the
 | 
				
			||||||
 | 
					 * value node.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline __init bool xbc_node_is_leaf(struct xbc_node *node)
 | 
					static inline __init bool xbc_node_is_leaf(struct xbc_node *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -129,6 +131,23 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
 | 
				
			||||||
	return xbc_node_find_child(NULL, key);
 | 
						return xbc_node_find_child(NULL, key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * xbc_node_get_subkey() - Return the first subkey node if exists
 | 
				
			||||||
 | 
					 * @node: Parent node
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return the first subkey node of the @node. If the @node has no child
 | 
				
			||||||
 | 
					 * or only value node, this will return NULL.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline struct xbc_node * __init xbc_node_get_subkey(struct xbc_node *node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct xbc_node *child = xbc_node_get_child(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (child && xbc_node_is_value(child))
 | 
				
			||||||
 | 
							return xbc_node_get_next(child);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return child;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * xbc_array_for_each_value() - Iterate value nodes on an array
 | 
					 * xbc_array_for_each_value() - Iterate value nodes on an array
 | 
				
			||||||
 * @anode: An XBC arraied value node
 | 
					 * @anode: An XBC arraied value node
 | 
				
			||||||
| 
						 | 
					@ -149,11 +168,24 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
 | 
				
			||||||
 * @child: Iterated XBC node.
 | 
					 * @child: Iterated XBC node.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Iterate child nodes of @parent. Each child nodes are stored to @child.
 | 
					 * Iterate child nodes of @parent. Each child nodes are stored to @child.
 | 
				
			||||||
 | 
					 * The @child can be mixture of a value node and subkey nodes.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define xbc_node_for_each_child(parent, child)				\
 | 
					#define xbc_node_for_each_child(parent, child)				\
 | 
				
			||||||
	for (child = xbc_node_get_child(parent); child != NULL ;	\
 | 
						for (child = xbc_node_get_child(parent); child != NULL ;	\
 | 
				
			||||||
	     child = xbc_node_get_next(child))
 | 
						     child = xbc_node_get_next(child))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * xbc_node_for_each_subkey() - Iterate child subkey nodes
 | 
				
			||||||
 | 
					 * @parent: An XBC node.
 | 
				
			||||||
 | 
					 * @child: Iterated XBC node.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Iterate subkey nodes of @parent. Each child nodes are stored to @child.
 | 
				
			||||||
 | 
					 * The @child is only the subkey node.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define xbc_node_for_each_subkey(parent, child)				\
 | 
				
			||||||
 | 
						for (child = xbc_node_get_subkey(parent); child != NULL ;	\
 | 
				
			||||||
 | 
						     child = xbc_node_get_next(child))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * xbc_node_for_each_array_value() - Iterate array entries of geven key
 | 
					 * xbc_node_for_each_array_value() - Iterate array entries of geven key
 | 
				
			||||||
 * @node: An XBC node.
 | 
					 * @node: An XBC node.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,7 +156,7 @@ xbc_node_find_child(struct xbc_node *parent, const char *key)
 | 
				
			||||||
	struct xbc_node *node;
 | 
						struct xbc_node *node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (parent)
 | 
						if (parent)
 | 
				
			||||||
		node = xbc_node_get_child(parent);
 | 
							node = xbc_node_get_subkey(parent);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		node = xbc_root_node();
 | 
							node = xbc_root_node();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,7 +164,7 @@ xbc_node_find_child(struct xbc_node *parent, const char *key)
 | 
				
			||||||
		if (!xbc_node_match_prefix(node, &key))
 | 
							if (!xbc_node_match_prefix(node, &key))
 | 
				
			||||||
			node = xbc_node_get_next(node);
 | 
								node = xbc_node_get_next(node);
 | 
				
			||||||
		else if (*key != '\0')
 | 
							else if (*key != '\0')
 | 
				
			||||||
			node = xbc_node_get_child(node);
 | 
								node = xbc_node_get_subkey(node);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -274,6 +274,8 @@ int __init xbc_node_compose_key_after(struct xbc_node *root,
 | 
				
			||||||
struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
 | 
					struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
 | 
				
			||||||
						 struct xbc_node *node)
 | 
											 struct xbc_node *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct xbc_node *next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(!xbc_data))
 | 
						if (unlikely(!xbc_data))
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -282,6 +284,13 @@ struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
 | 
				
			||||||
		if (!node)
 | 
							if (!node)
 | 
				
			||||||
			node = xbc_nodes;
 | 
								node = xbc_nodes;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
							/* Leaf node may have a subkey */
 | 
				
			||||||
 | 
							next = xbc_node_get_subkey(node);
 | 
				
			||||||
 | 
							if (next) {
 | 
				
			||||||
 | 
								node = next;
 | 
				
			||||||
 | 
								goto found;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (node == root)	/* @root was a leaf, no child node. */
 | 
							if (node == root)	/* @root was a leaf, no child node. */
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,6 +305,7 @@ struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
 | 
				
			||||||
		node = xbc_node_get_next(node);
 | 
							node = xbc_node_get_next(node);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					found:
 | 
				
			||||||
	while (node && !xbc_node_is_leaf(node))
 | 
						while (node && !xbc_node_is_leaf(node))
 | 
				
			||||||
		node = xbc_node_get_child(node);
 | 
							node = xbc_node_get_child(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -375,18 +385,20 @@ static inline __init struct xbc_node *xbc_last_child(struct xbc_node *node)
 | 
				
			||||||
	return node;
 | 
						return node;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
 | 
					static struct xbc_node * __init __xbc_add_sibling(char *data, u32 flag, bool head)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct xbc_node *sib, *node = xbc_add_node(data, flag);
 | 
						struct xbc_node *sib, *node = xbc_add_node(data, flag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (node) {
 | 
						if (node) {
 | 
				
			||||||
		if (!last_parent) {
 | 
							if (!last_parent) {
 | 
				
			||||||
 | 
								/* Ignore @head in this case */
 | 
				
			||||||
			node->parent = XBC_NODE_MAX;
 | 
								node->parent = XBC_NODE_MAX;
 | 
				
			||||||
			sib = xbc_last_sibling(xbc_nodes);
 | 
								sib = xbc_last_sibling(xbc_nodes);
 | 
				
			||||||
			sib->next = xbc_node_index(node);
 | 
								sib->next = xbc_node_index(node);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			node->parent = xbc_node_index(last_parent);
 | 
								node->parent = xbc_node_index(last_parent);
 | 
				
			||||||
			if (!last_parent->child) {
 | 
								if (!last_parent->child || head) {
 | 
				
			||||||
 | 
									node->next = last_parent->child;
 | 
				
			||||||
				last_parent->child = xbc_node_index(node);
 | 
									last_parent->child = xbc_node_index(node);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				sib = xbc_node_get_child(last_parent);
 | 
									sib = xbc_node_get_child(last_parent);
 | 
				
			||||||
| 
						 | 
					@ -400,6 +412,16 @@ static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
 | 
				
			||||||
	return node;
 | 
						return node;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return __xbc_add_sibling(data, flag, false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct xbc_node * __init xbc_add_head_sibling(char *data, u32 flag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return __xbc_add_sibling(data, flag, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline __init struct xbc_node *xbc_add_child(char *data, u32 flag)
 | 
					static inline __init struct xbc_node *xbc_add_child(char *data, u32 flag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct xbc_node *node = xbc_add_sibling(data, flag);
 | 
						struct xbc_node *node = xbc_add_sibling(data, flag);
 | 
				
			||||||
| 
						 | 
					@ -568,8 +590,9 @@ static int __init __xbc_add_key(char *k)
 | 
				
			||||||
		node = find_match_node(xbc_nodes, k);
 | 
							node = find_match_node(xbc_nodes, k);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		child = xbc_node_get_child(last_parent);
 | 
							child = xbc_node_get_child(last_parent);
 | 
				
			||||||
 | 
							/* Since the value node is the first child, skip it. */
 | 
				
			||||||
		if (child && xbc_node_is_value(child))
 | 
							if (child && xbc_node_is_value(child))
 | 
				
			||||||
			return xbc_parse_error("Subkey is mixed with value", k);
 | 
								child = xbc_node_get_next(child);
 | 
				
			||||||
		node = find_match_node(child, k);
 | 
							node = find_match_node(child, k);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -612,27 +635,29 @@ static int __init xbc_parse_kv(char **k, char *v, int op)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	child = xbc_node_get_child(last_parent);
 | 
					 | 
				
			||||||
	if (child) {
 | 
					 | 
				
			||||||
		if (xbc_node_is_key(child))
 | 
					 | 
				
			||||||
			return xbc_parse_error("Value is mixed with subkey", v);
 | 
					 | 
				
			||||||
		else if (op == '=')
 | 
					 | 
				
			||||||
			return xbc_parse_error("Value is redefined", v);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c = __xbc_parse_value(&v, &next);
 | 
						c = __xbc_parse_value(&v, &next);
 | 
				
			||||||
	if (c < 0)
 | 
						if (c < 0)
 | 
				
			||||||
		return c;
 | 
							return c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (op == ':' && child) {
 | 
						child = xbc_node_get_child(last_parent);
 | 
				
			||||||
		xbc_init_node(child, v, XBC_VALUE);
 | 
						if (child && xbc_node_is_value(child)) {
 | 
				
			||||||
	} else {
 | 
							if (op == '=')
 | 
				
			||||||
		if (op == '+' && child)
 | 
								return xbc_parse_error("Value is redefined", v);
 | 
				
			||||||
			last_parent = xbc_last_child(child);
 | 
							if (op == ':') {
 | 
				
			||||||
		if (!xbc_add_sibling(v, XBC_VALUE))
 | 
								unsigned short nidx = child->next;
 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								xbc_init_node(child, v, XBC_VALUE);
 | 
				
			||||||
 | 
								child->next = nidx;	/* keep subkeys */
 | 
				
			||||||
 | 
								goto array;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* op must be '+' */
 | 
				
			||||||
 | 
							last_parent = xbc_last_child(child);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/* The value node should always be the first child */
 | 
				
			||||||
 | 
						if (!xbc_add_head_sibling(v, XBC_VALUE))
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array:
 | 
				
			||||||
	if (c == ',') {	/* Array */
 | 
						if (c == ',') {	/* Array */
 | 
				
			||||||
		c = xbc_parse_array(&next);
 | 
							c = xbc_parse_array(&next);
 | 
				
			||||||
		if (c < 0)
 | 
							if (c < 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,30 +35,55 @@ static int xbc_show_value(struct xbc_node *node, bool semicolon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xbc_show_compact_tree(void)
 | 
					static void xbc_show_compact_tree(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct xbc_node *node, *cnode;
 | 
						struct xbc_node *node, *cnode = NULL, *vnode;
 | 
				
			||||||
	int depth = 0, i;
 | 
						int depth = 0, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node = xbc_root_node();
 | 
						node = xbc_root_node();
 | 
				
			||||||
	while (node && xbc_node_is_key(node)) {
 | 
						while (node && xbc_node_is_key(node)) {
 | 
				
			||||||
		for (i = 0; i < depth; i++)
 | 
							for (i = 0; i < depth; i++)
 | 
				
			||||||
			printf("\t");
 | 
								printf("\t");
 | 
				
			||||||
 | 
							if (!cnode)
 | 
				
			||||||
			cnode = xbc_node_get_child(node);
 | 
								cnode = xbc_node_get_child(node);
 | 
				
			||||||
		while (cnode && xbc_node_is_key(cnode) && !cnode->next) {
 | 
							while (cnode && xbc_node_is_key(cnode) && !cnode->next) {
 | 
				
			||||||
 | 
								vnode = xbc_node_get_child(cnode);
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * If @cnode has value and subkeys, this
 | 
				
			||||||
 | 
								 * should show it as below.
 | 
				
			||||||
 | 
								 *
 | 
				
			||||||
 | 
								 * key(@node) {
 | 
				
			||||||
 | 
								 *      key(@cnode) = value;
 | 
				
			||||||
 | 
								 *      key(@cnode) {
 | 
				
			||||||
 | 
								 *          subkeys;
 | 
				
			||||||
 | 
								 *      }
 | 
				
			||||||
 | 
								 * }
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (vnode && xbc_node_is_value(vnode) && vnode->next)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
			printf("%s.", xbc_node_get_data(node));
 | 
								printf("%s.", xbc_node_get_data(node));
 | 
				
			||||||
			node = cnode;
 | 
								node = cnode;
 | 
				
			||||||
			cnode = xbc_node_get_child(node);
 | 
								cnode = vnode;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (cnode && xbc_node_is_key(cnode)) {
 | 
							if (cnode && xbc_node_is_key(cnode)) {
 | 
				
			||||||
			printf("%s {\n", xbc_node_get_data(node));
 | 
								printf("%s {\n", xbc_node_get_data(node));
 | 
				
			||||||
			depth++;
 | 
								depth++;
 | 
				
			||||||
			node = cnode;
 | 
								node = cnode;
 | 
				
			||||||
 | 
								cnode = NULL;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		} else if (cnode && xbc_node_is_value(cnode)) {
 | 
							} else if (cnode && xbc_node_is_value(cnode)) {
 | 
				
			||||||
			printf("%s = ", xbc_node_get_data(node));
 | 
								printf("%s = ", xbc_node_get_data(node));
 | 
				
			||||||
			xbc_show_value(cnode, true);
 | 
								xbc_show_value(cnode, true);
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * If @node has value and subkeys, continue
 | 
				
			||||||
 | 
								 * looping on subkeys with same node.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (cnode->next) {
 | 
				
			||||||
 | 
									cnode = xbc_node_get_next(cnode);
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			printf("%s;\n", xbc_node_get_data(node));
 | 
								printf("%s;\n", xbc_node_get_data(node));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							cnode = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (node->next) {
 | 
							if (node->next) {
 | 
				
			||||||
			node = xbc_node_get_next(node);
 | 
								node = xbc_node_get_next(node);
 | 
				
			||||||
| 
						 | 
					@ -70,11 +95,13 @@ static void xbc_show_compact_tree(void)
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			if (!xbc_node_get_child(node)->next)
 | 
								if (!xbc_node_get_child(node)->next)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
								if (depth) {
 | 
				
			||||||
				depth--;
 | 
									depth--;
 | 
				
			||||||
				for (i = 0; i < depth; i++)
 | 
									for (i = 0; i < depth; i++)
 | 
				
			||||||
					printf("\t");
 | 
										printf("\t");
 | 
				
			||||||
				printf("}\n");
 | 
									printf("}\n");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		node = xbc_node_get_next(node);
 | 
							node = xbc_node_get_next(node);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -86,8 +113,10 @@ static void xbc_show_list(void)
 | 
				
			||||||
	const char *val;
 | 
						const char *val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xbc_for_each_key_value(leaf, val) {
 | 
						xbc_for_each_key_value(leaf, val) {
 | 
				
			||||||
		if (xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX) < 0)
 | 
							if (xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX) < 0) {
 | 
				
			||||||
 | 
								fprintf(stderr, "Failed to compose key %d\n", ret);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		printf("%s = ", key);
 | 
							printf("%s = ", key);
 | 
				
			||||||
		if (!val || val[0] == '\0') {
 | 
							if (!val || val[0] == '\0') {
 | 
				
			||||||
			printf("\"\"\n");
 | 
								printf("\"\"\n");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue