blob: ae22e65ed33efca977ff10ef892d26542445b793 [file] [log] [blame]
Googlerfc3e29a2022-11-22 14:17:45 +08001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include "ini_config.h"
7
8#define LOG_TAG "ini_handler"
9#define LOG_NDEBUG 0
10
11#include "ini_log.h"
12
13#include "ini_core.h"
14#include "ini_handler.h"
15#include "ini_platform.h"
16
17static void trim(char *str, char ch);
18static void trim_all(char *str);
19static INI_SECTION* getSection(const char* section, INI_HANDLER_DATA *pHandlerData);
20static INI_LINE* getKeyLineAtSec(INI_SECTION* pSec, const char* key);
21static int setKeyValue(void* user, const char* section, const char* name, const char* value, int set_mode);
22static int handler(void* user, const char* section, const char* name, const char* value);
23static INI_LINE* newLine(const char* name, const char* value);
24static INI_SECTION* newSection(const char* section, INI_LINE* pLINE);
25
26#if CC_MEMORY_ALLOC_FREE_TRACE == 1
27static void alloc_mem(const char *fun_name, const char *var_name, void *ptr);
28static void free_mem(const char *fun_name, const char *var_name, void *ptr);
29static void printAllocMemND(const char *fun_name);
30static void printFreeMemND(const char *fun_name);
31static void clearMemND(void);
32#endif
33
34int bin_file_read(const char* filename, unsigned char *file_buf) {
35 int tmp_ret = -1, rd_cnt = 0, file_size = 0;
36 unsigned char *tmp_buf = NULL;
37
38 if (!iniIsFileExist(filename)) {
39 ALOGE("%s, file \"%s\" is not exist!\n", __FUNCTION__, filename);
40 return -1;
41 }
42
43 file_size = iniGetFileSize(filename);
44 if (file_size <= 0) {
45 ALOGE("%s, file \"%s\" size error!\n", __FUNCTION__, filename);
46 return -1;
47 }
48
49 tmp_buf = (unsigned char *) malloc(file_size * 2);
50 if (tmp_buf != NULL) {
51 rd_cnt = iniReadFileToBuffer(filename, 0, file_size, tmp_buf);
52 if (rd_cnt > 0) {
53 if (file_size > CC_MAX_INI_FILE_SIZE) {
54 ALOGE("%s: file \"%s\" size out of support!\n", __FUNCTION__, filename);
55 tmp_ret = -1;
56 } else {
57 memcpy(file_buf, tmp_buf, file_size);
58 tmp_ret = file_size;
59 }
60 }
61
62 free(tmp_buf);
63 tmp_buf = NULL;
64 }
65
66 return tmp_ret;
67}
68
69int ini_file_parse(const char* filename, INI_HANDLER_DATA *pHandlerData) {
70 int tmp_ret = -1, rd_cnt = 0, file_size = 0;
71 unsigned char *tmp_buf = NULL;
72
73 if (!iniIsFileExist(filename)) {
74 ALOGE("%s, file \"%s\" is not exist!\n", __FUNCTION__, filename);
75 return -1;
76 }
77
78 file_size = iniGetFileSize(filename);
79 if (file_size <= 0) {
80 ALOGE("%s, file \"%s\" size error!\n", __FUNCTION__, filename);
81 return -1;
82 }
83
84 tmp_buf = (unsigned char *) malloc(file_size * 2);
85 if (tmp_buf != NULL) {
86 strncpy(pHandlerData->mpFileName, filename, CC_MAX_INI_FILE_NAME_LEN - 1);
87
88 memset((void *)tmp_buf, '\0', (file_size * 2) * sizeof(char));
89 rd_cnt = iniReadFileToBuffer(filename, 0, file_size, tmp_buf);
90 if (rd_cnt > 0) {
91 tmp_ret = ini_mem_parse(tmp_buf, pHandlerData);
92 }
93
94 free(tmp_buf);
95 tmp_buf = NULL;
96 }
97
98 return tmp_ret;
99}
100
101int ini_mem_parse(unsigned char* file_buf, INI_HANDLER_DATA *pHandlerData) {
102 //ALOGD("%s, entering...\n", __FUNCTION__);
103 return ini_parse_mem((char *)file_buf, handler, (void *)pHandlerData);
104}
105
106int ini_set_save_file_name(const char* filename, INI_HANDLER_DATA *pHandlerData) {
107 //ALOGD("%s, entering...\n", __FUNCTION__);
108
109 strncpy(pHandlerData->mpFileName, filename, CC_MAX_INI_FILE_NAME_LEN - 1);
110 return 0;
111}
112
113void ini_free_mem(INI_HANDLER_DATA *pHandlerData) {
114 //ALOGD("%s, entering...\n", __FUNCTION__);
115
116 INI_SECTION* pNextSec = NULL;
117 INI_SECTION* pSec = NULL;
118 for (pSec = pHandlerData->mpFirstSection; pSec != NULL;) {
119 pNextSec = pSec->pNext;
120
121 INI_LINE* pNextLine = NULL;
122 INI_LINE* pLine = NULL;
123 for (pLine = pSec->pLine; pLine != NULL;) {
124 pNextLine = pLine->pNext;
125
126 if (pLine != NULL) {
127#if CC_MEMORY_ALLOC_FREE_TRACE == 1
128 free_mem(__FUNCTION__, "pLine", pLine);
129#endif
130
131 free(pLine);
132 pLine = NULL;
133 }
134
135 pLine = pNextLine;
136 }
137
138 if (pSec != NULL) {
139#if CC_MEMORY_ALLOC_FREE_TRACE == 1
140 free_mem(__FUNCTION__, "pSec", pSec);
141#endif
142
143 free(pSec);
144 pSec = NULL;
145 }
146
147 pSec = pNextSec;
148 }
149
150 pHandlerData->mpFirstSection = NULL;
151 pHandlerData->mpCurSection = NULL;
152
153#if CC_MEMORY_ALLOC_FREE_TRACE == 1
154 printAllocMemND(__FUNCTION__);
155 printFreeMemND(__FUNCTION__);
156 clearMemND();
157#endif
158}
159
160static void trim(char *str, char ch) {
161 char* pStr;
162
163 pStr = str;
164 while (*pStr != '\0') {
165 if (*pStr == ch) {
166 char* pTmp = pStr;
167 while (*pTmp != '\0') {
168 *pTmp = *(pTmp + 1);
169 pTmp++;
170 }
171 } else {
172 pStr++;
173 }
174 }
175}
176
177static void trim_all(char *str) {
178 char* pStr = NULL;
179
180 pStr = strchr(str, '\n');
181 if (pStr != NULL) {
182 *pStr = 0;
183 }
184
185 int Len = strlen(str);
186 if (Len > 0) {
187 if (str[Len - 1] == '\r') {
188 str[Len - 1] = '\0';
189 }
190 }
191
192 pStr = strchr(str, '#');
193 if (pStr != NULL) {
194 *pStr = 0;
195 }
196
197 pStr = strchr(str, ';');
198 if (pStr != NULL) {
199 *pStr = 0;
200 }
201
202 trim(str, ' ');
203 trim(str, '{');
204 trim(str, '\\');
205 trim(str, '}');
206 trim(str, '\"');
207 return;
208}
209
210void ini_print_all(INI_HANDLER_DATA *pHandlerData) {
211 INI_SECTION* pSec = NULL;
212 for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
213 ALOGD("[%s]\n", pSec->Name);
214 INI_LINE* pLine = NULL;
215 for (pLine = pSec->pLine; pLine != NULL; pLine = pLine->pNext) {
216 ALOGD("%s = %s\n", pLine->Name, pLine->Value);
217 }
218 ALOGD("\n\n\n");
219 }
220}
221
222void ini_list_section(INI_HANDLER_DATA *pHandlerData) {
223 INI_SECTION* pSec = NULL;
224 for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
225 printf(" %s\n", pSec->Name);
226 }
227}
228
229static INI_SECTION* getSection(const char* section, INI_HANDLER_DATA *pHandlerData) {
230 INI_SECTION* pSec = NULL;
231 for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
232 if (strncmp(pSec->Name, section, strlen(section)) == 0) {
233 return pSec;
234 }
235 }
236
237 return NULL;
238}
239
240static INI_LINE* getKeyLineAtSec(INI_SECTION* pSec, const char* key) {
241 INI_LINE* pLine = NULL;
242 for (pLine = pSec->pLine; pLine != NULL; pLine = pLine->pNext) {
243 if (strncmp(pLine->Name, key, strlen(key)) == 0) {
244 return pLine;
245 }
246 }
247 return NULL;
248}
249
250const char* ini_get_string(const char* section, const char* key,
251 const char* def_value, INI_HANDLER_DATA *pHandlerData) {
252 INI_SECTION* pSec = getSection(section, pHandlerData);
253 if (pSec == NULL) {
254 //ALOGD("%s, section %s is NULL\n", __FUNCTION__, section);
255 return def_value;
256 }
257
258 INI_LINE* pLine = getKeyLineAtSec(pSec, key);
259 if (pLine == NULL) {
260 //ALOGD("%s, key \"%s\" is NULL\n", __FUNCTION__, key);
261 return def_value;
262 }
263
264 return pLine->Value;
265}
266
267int ini_set_string(const char *section, const char *key, const char *value, INI_HANDLER_DATA *pHandlerData) {
268 setKeyValue(pHandlerData, section, key, value, 1);
269 return 0;
270}
271
272int ini_save_to_file(const char *filename, INI_HANDLER_DATA *pHandlerData) {
273#if (defined CC_COMPILE_IN_PC || defined CC_COMPILE_IN_ANDROID)
274 const char *fname = NULL;
275 FILE *fp = NULL;
276
277 if (filename == NULL) {
278 if (strlen(pHandlerData->mpFileName) == 0) {
279 ALOGE("%s, save file name is NULL!!!\n", __FUNCTION__);
280 return -1;
281 } else {
282 fname = pHandlerData->mpFileName;
283 }
284 } else {
285 fname = filename;
286 }
287
288 if ((fp = fopen (fname, "wb")) == NULL) {
289 ALOGE("%s, Open file \"%s\" ERROR (%s)!!!\n", __FUNCTION__, fname, strerror(errno));
290 return -1;
291 }
292
293 INI_SECTION* pSec = NULL;
294 for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
295 fprintf(fp, "[%s]\r\n", pSec->Name);
296 INI_LINE* pLine = NULL;
297 for (pLine = pSec->pLine; pLine != NULL; pLine = pLine->pNext) {
298 fprintf(fp, "%s = %s\r\n", pLine->Name, pLine->Value);
299 }
300 }
301
302 fflush(fp);
303 fsync(fileno(fp));
304
305 fclose(fp);
306 fp = NULL;
307
308 return 0;
309#elif (defined CC_COMPILE_IN_UBOOT)
310 return 0;
311#endif
312}
313
314static INI_LINE* newLine(const char* name, const char* value) {
315 INI_LINE* pLine = NULL;
316
317 pLine = (INI_LINE*) malloc(sizeof(INI_LINE));
318 if (pLine != NULL) {
319 pLine->pNext = NULL;
320 strncpy(pLine->Name, name, sizeof(pLine->Name) - 1);
321 pLine->Name[sizeof(pLine->Name) - 1] = '\0';
322 strncpy(pLine->Value, value, sizeof(pLine->Value) - 1);
323 pLine->Value[sizeof(pLine->Value) - 1] = '\0';
324
325#if CC_MEMORY_ALLOC_FREE_TRACE == 1
326 alloc_mem(__FUNCTION__, "pLine", pLine);
327#endif
328 }
329
330 return pLine;
331}
332
333static INI_SECTION* newSection(const char* section, INI_LINE* pLine) {
334 INI_SECTION* pSec = NULL;
335
336 pSec = (INI_SECTION*) malloc(sizeof(INI_SECTION));
337 if (pSec != NULL) {
338 pSec->pLine = pLine;
339 pSec->pNext = NULL;
340 strncpy(pSec->Name, section, sizeof(pSec->Name) - 1);
341 pSec->Name[sizeof(pSec->Name) - 1] = '\0';
342
343#if CC_MEMORY_ALLOC_FREE_TRACE == 1
344 alloc_mem(__FUNCTION__, "pSec", pSec);
345#endif
346 }
347
348 return pSec;
349}
350
351static int setKeyValue(void* user, const char* section, const char* key, const char* value, int set_mode) {
352 INI_LINE* pLine = NULL;
353 INI_SECTION *pSec = NULL;
354 INI_HANDLER_DATA *pHandlerData = (INI_HANDLER_DATA *) user;
355
356 if (section == NULL || key == NULL || value == NULL) {
357 return 1;
358 }
359
360 trim_all((char *) value);
361 if (value[0] == '\0') {
362 return 1;
363 }
364
365 if (strlen(key) > CC_MAX_INI_LINE_NAME_LEN) {
366 ALOGE("key name is too long, limit %d.\n", CC_MAX_INI_LINE_NAME_LEN);
367 return 1;
368 }
369 if (strlen(value) > CC_MAX_INI_FILE_LINE_LEN) {
370 ALOGE("key name is too long, limit %d.\n", CC_MAX_INI_FILE_LINE_LEN);
371 return 1;
372 }
373
374 if (pHandlerData->mpFirstSection == NULL) {
375 pLine = newLine(key, value);
376 pSec = newSection(section, pLine);
377
378 pHandlerData->mpFirstSection = pSec;
379 pHandlerData->mpCurSection = pSec;
380 pSec->pCurLine = pLine;
381 } else {
382 pSec = getSection(section, pHandlerData);
383 if (pSec == NULL) {
384 pLine = newLine(key, value);
385 pSec = newSection(section, pLine);
386
387 pHandlerData->mpCurSection->pNext = pSec;
388 pHandlerData->mpCurSection = pSec;
389 pSec->pCurLine = pLine;
390
391 pSec->pCurLine = pLine;
392 } else {
393 pLine = getKeyLineAtSec(pSec, key);
394 if (pLine == NULL) {
395 pLine = newLine(key, value);
396
397 pSec->pCurLine->pNext = pLine;
398 pSec->pCurLine = pLine;
399 } else {
400 if (set_mode == 1) {
401 strcpy(pLine->Value, value);
402 } else {
403 strcat(pLine->Value, value);
404 }
405 }
406 }
407 }
408
409 return 0;
410}
411
412static int handler(void* user, const char* section, const char* name,
413 const char* value) {
414 //ALOGD("%s, section = %s, name = %s, value = %s\n", __FUNCTION__, section, name, value);
415 setKeyValue(user, section, name, value, 0);
416 return 1;
417}
418
419#if CC_MEMORY_ALLOC_FREE_TRACE == 1
420
421#define CC_MEM_RECORD_CNT (1024)
422
423typedef struct tag_memnd {
424 char fun_name[50];
425 char var_name[50];
426 void *ptr;
427} memnd;
428
429static memnd gMemAllocItems[CC_MEM_RECORD_CNT];
430static int gMemAllocInd = 0;
431
432static memnd gMemFreeItems[CC_MEM_RECORD_CNT];
433static int gMemFreeInd = 0;
434
435static void alloc_mem(const char *fun_name, const char *var_name, void *ptr) {
436 strncpy(gMemAllocItems[gMemAllocInd].fun_name, fun_name,
437 sizeof(gMemAllocItems[gMemAllocInd].fun_name) - 1);
438 gMemAllocItems[gMemAllocInd].fun_name[sizeof(gMemAllocItems[gMemAllocInd].fun_name) - 1]
439 = '\0';
440 strncpy(gMemAllocItems[gMemAllocInd].var_name, var_name,
441 sizeof(gMemAllocItems[gMemAllocInd].var_name) - 1);
442 gMemAllocItems[gMemAllocInd].var_name[sizeof(gMemAllocItems[gMemAllocInd].var_name) - 1]
443 = '\0';
444 gMemAllocItems[gMemAllocInd].ptr = ptr;
445
446 gMemAllocInd += 1;
447}
448
449static void free_mem(const char *fun_name, const char *var_name, void *ptr) {
450 strncpy(gMemFreeItems[gMemFreeInd].fun_name, fun_name,
451 sizeof(gMemFreeItems[gMemFreeInd].fun_name) - 1);
452 gMemFreeItems[gMemFreeInd].fun_name[sizeof(gMemFreeItems[gMemFreeInd].fun_name) - 1]
453 = '\0';
454 strncpy(gMemFreeItems[gMemFreeInd].var_name, var_name,
455 sizeof(gMemFreeItems[gMemFreeInd].var_name) - 1);
456 gMemFreeItems[gMemFreeInd].var_name[sizeof(gMemFreeItems[gMemFreeInd].var_name) - 1]
457 = '\0';
458
459 gMemFreeItems[gMemFreeInd].ptr = ptr;
460
461 gMemFreeInd += 1;
462}
463
464static void printMemND(const char *fun_name, memnd *tmp_nd, int tmp_cnt) {
465#if CC_MEMORY_ALLOC_FREE_TRACE_PRINT_ALL == 1
466 int i = 0;
467
468 ALOGD("fun_name = %s, total_cnt = %d\n", fun_name, tmp_cnt);
469
470 for (i = 0; i < tmp_cnt; i++) {
471 ALOGD("fun_name = %s, var_name = %s, ptr = %p\n", tmp_nd[i].fun_name, tmp_nd[i].var_name, tmp_nd[i].ptr);
472 }
473#endif
474}
475
476static void printFreeMemND(const char *fun_name) {
477 printMemND(__FUNCTION__, gMemFreeItems, gMemFreeInd);
478}
479
480static void printAllocMemND(const char *fun_name) {
481 printMemND(__FUNCTION__, gMemAllocItems, gMemAllocInd);
482}
483
484static void clearMemND(void) {
485 gMemAllocInd = 0;
486 gMemFreeInd = 0;
487 memset((void *)gMemAllocItems, 0, sizeof(memnd) * CC_MEM_RECORD_CNT);
488 memset((void *)gMemFreeItems, 0, sizeof(memnd) * CC_MEM_RECORD_CNT);
489}
490#endif