xref: /wlan-dirver/qca-wifi-host-cmn/qdf/src/qdf_parse.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "qdf_file.h"
20 #include "qdf_module.h"
21 #include "qdf_parse.h"
22 #include "qdf_status.h"
23 #include "qdf_str.h"
24 #include "qdf_trace.h"
25 #include "qdf_types.h"
26 
27 QDF_STATUS qdf_ini_parse(const char *ini_path, void *context,
28 			 qdf_ini_item_cb item_cb, qdf_ini_section_cb section_cb)
29 {
30 	QDF_STATUS status;
31 	char *fbuf;
32 	char *cursor;
33 	int ini_read_count = 0;
34 
35 	if (qdf_str_eq(QDF_WIFI_MODULE_PARAMS_FILE, ini_path))
36 		status = qdf_module_param_file_read(ini_path, &fbuf);
37 	else
38 		status = qdf_file_read(ini_path, &fbuf);
39 	if (QDF_IS_STATUS_ERROR(status)) {
40 		qdf_err("Failed to read *.ini file @ %s", ini_path);
41 		return status;
42 	}
43 
44 	/* foreach line */
45 	cursor = fbuf;
46 	while (*cursor != '\0') {
47 		char *key = cursor;
48 		char *value = NULL;
49 		bool comment = false;
50 		bool eol = false;
51 
52 		/*
53 		 * Look for the end of the line, while noting any
54 		 * value ('=') or comment ('#') indicators
55 		 */
56 		while (!eol) {
57 			switch (*cursor) {
58 			case '\r':
59 			case '\n':
60 				*cursor = '\0';
61 				cursor++;
62 				/* fall through */
63 			case '\0':
64 				eol = true;
65 				break;
66 
67 			case '=':
68 				/*
69 				 * The first '=' is the value indicator.
70 				 * Subsequent '=' are valid value characters.
71 				 */
72 				if (!value && !comment) {
73 					value = cursor + 1;
74 					*cursor = '\0';
75 				}
76 
77 				cursor++;
78 				break;
79 
80 			case '#':
81 			case '[':
82 				/*
83 				 * We don't process comments, so we can null-
84 				 * terminate unconditionally here (unlike '=').
85 				 */
86 				comment = true;
87 				*cursor = '\0';
88 				/* fall through */
89 			default:
90 				cursor++;
91 				break;
92 			}
93 		}
94 
95 		key = qdf_str_trim(key);
96 
97 		/*
98 		 * Ignoring comments, a valid ini line contains one of:
99 		 *	1) some 'key=value' config item
100 		 *	2) section header
101 		 *	3) a line containing whitespace
102 		 */
103 		if (value) {
104 			status = item_cb(context, key, value);
105 			if (QDF_IS_STATUS_ERROR(status))
106 				goto free_fbuf;
107 			else
108 				ini_read_count++;
109 		} else if (key[0] == '[') {
110 			qdf_size_t len = qdf_str_len(key);
111 
112 			if (key[len - 1] != ']') {
113 				qdf_err("Invalid *.ini syntax '%s'", key);
114 			} else {
115 				key[len - 1] = '\0';
116 				if (section_cb)
117 					status = section_cb(context, key + 1);
118 				else
119 					status = QDF_STATUS_E_NULL_VALUE;
120 
121 				if (QDF_IS_STATUS_ERROR(status))
122 					goto free_fbuf;
123 			}
124 		} else if (key[0] != '\0') {
125 			qdf_err("Invalid *.ini syntax '%s'", key);
126 		}
127 
128 		/* skip remaining EoL characters */
129 		while (*cursor == '\n' || *cursor == '\r')
130 			cursor++;
131 	}
132 
133 	qdf_info("INI values read: %d", ini_read_count);
134 	if (ini_read_count != 0) {
135 		qdf_info("INI file parse successful");
136 		status = QDF_STATUS_SUCCESS;
137 	} else {
138 		qdf_info("INI file parse fail: invalid file format");
139 		status = QDF_STATUS_E_INVAL;
140 	}
141 
142 free_fbuf:
143 	if (qdf_str_eq(QDF_WIFI_MODULE_PARAMS_FILE, ini_path))
144 		qdf_module_param_file_free(fbuf);
145 	else
146 		qdf_file_buf_free(fbuf);
147 
148 	return status;
149 }
150 qdf_export_symbol(qdf_ini_parse);
151 
152