INI 文件是一种有简单格式的文本文件(ASCII),可以用来提供一些配置信息。比如下面这个文件:
; exp ini file
[port]
Portname=COM4
Port=4
[settings]
Baud=115200 ;Speed
第一行是注释。然后 port 和 settings 都被称作 section。其中的 Portname Port 和 Baud 都是 Key,相应的,每一个 Key 都有 value 。
虽然这样的结构并不复杂,但是如果完全自己来写还是很麻烦的。经过搜索,找到了 iniparser 【参考1】这个开源项目。对应的库需要有一点修改才能编译成功, iniparser.c 中需要如下改动:
return last - s; ----> return (unsigned int) (last - s);
根据例子编写的测试代码:
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include "iniparser.h"
extern EFI_SYSTEM_TABLE *gST;
extern EFI_BOOT_SERVICES *gBS;
void create_example_ini_file(void)
{
FILE * ini ;
if ((ini=fopen("example.ini", "w"))==NULL) {
fprintf(stderr, "iniparser: cannot create example.ini\n");
return ;
}
fprintf(ini,
"#\n"
"# This is an example of ini file\n"
"#\n"
"\n"
"[Pizza]\n"
"\n"
"Ham = yes ;\n"
"Mushrooms = TRUE ;\n"
"Capres = 0 ;\n"
"Cheese = Non ;\n"
"\n"
"\n"
"[Wine]\n"
"\n"
"Grape = Cabernet Sauvignon ;\n"
"Year = 1989 ;\n"
"Country = Spain ;\n"
"Alcohol = 12.5 ;\n"
"\n");
fclose(ini);
}
int parse_ini_file(char * ini_name)
{
dictionary * ini ;
/* Some temporary variables to hold query results */
int b ;
int i ;
double d ;
const char * s ;
ini = iniparser_load(ini_name);
if (ini==NULL) {
fprintf(stderr, "cannot parse file: %s\n", ini_name);
return -1 ;
}
iniparser_dump(ini, stderr);
/* Get pizza attributes */
printf("Pizza:\n");
b = iniparser_getboolean(ini, "pizza:ham", -1);
printf("Ham: [%d]\n", b);
b = iniparser_getboolean(ini, "pizza:mushrooms", -1);
printf("Mushrooms: [%d]\n", b);
b = iniparser_getboolean(ini, "pizza:capres", -1);
printf("Capres: [%d]\n", b);
b = iniparser_getboolean(ini, "pizza:cheese", -1);
printf("Cheese: [%d]\n", b);
/* Get wine attributes */
printf("Wine:\n");
s = iniparser_getstring(ini, "wine:grape", NULL);
printf("Grape: [%s]\n", s ? s : "UNDEF");
i = iniparser_getint(ini, "wine:year", -1);
printf("Year: [%d]\n", i);
s = iniparser_getstring(ini, "wine:country", NULL);
printf("Country: [%s]\n", s ? s : "UNDEF");
d = iniparser_getdouble(ini, "wine:alcohol", -1.0);
printf("Alcohol: [%g]\n", d);
iniparser_freedict(ini);
return 0 ;
}
/***
Print a welcoming message.
Establishes the main structure of the application.
@retval 0 The application exited normally.
@retval Other An error occurred.
***/
INTN
EFIAPI
main (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
int status ;
if (Argc<2) {
create_example_ini_file();
status = parse_ini_file("example.ini");
} else {
status = parse_ini_file(Argv[1]);
}
return status ;
}
因为用到的fopen ,所以需要特别加入 DevShell 在LibraryClasses 中
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = init
FILE_GUID = a912f198-7f0e-4805-b90A-b757b806ec85
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
INITest.c
iniparser.c
iniparser.h
dictionary.h
dictionary.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
[LibraryClasses]
UefiLib
ShellCEntryLib
IoLib
LibC
LibStdio
DevShell
运行结果:
不加参数会读取example.ini
加入参数可以读取指定文件:
完整的代码下载:
参考: