读取yaml文件数组内容到glist链表
config.yaml内容:
servers:
- name: server1
ip: 192.168 .1.1
roles:
- web
- database
- name: server2
ip: 192.168 .1.2
roles:
- web
- name: server3
ip: 192.168 .1.3
roles:
- database
测试代码:
typedef struct {
char name[ MAX_NAME_LEN] ;
char ip[ MAX_IP_LEN] ;
char roles[ MAX_ROLES] [ MAX_NAME_LEN] ;
int role_count;
} server_t;
void print_event( yaml_event_t *event) {
switch ( event-> type) {
case YAML_NO_EVENT: puts( "No event!" ) ; break ;
case YAML_STREAM_START_EVENT: puts( "STREAM START" ) ; break ;
case YAML_STREAM_END_EVENT: puts( "STREAM END" ) ; break ;
case YAML_DOCUMENT_START_EVENT: puts( "Start Document" ) ; break ;
case YAML_DOCUMENT_END_EVENT: puts( "End Document" ) ; break ;
case YAML_SEQUENCE_START_EVENT: puts( "Start Sequence" ) ; break ;
case YAML_SEQUENCE_END_EVENT: puts( "End Sequence" ) ; break ;
case YAML_MAPPING_START_EVENT: puts( "Start Mapping" ) ; break ;
case YAML_MAPPING_END_EVENT: puts( "End Mapping" ) ; break ;
case YAML_ALIAS_EVENT: printf( "Alias: %s\n " , event-> data.alias.anchor) ; break ;
case YAML_SCALAR_EVENT: printf( "Scalar: %s\n " , event-> data.scalar.value) ; break ;
}
}
GList* get_array_config_yaml( const char *file_path) {
FILE *fh = fopen( file_path, "r" ) ;
if ( ! fh) {
perror( "Failed to open file" ) ;
return NULL;
}
yaml_parser_t parser;
yaml_event_t event;
if ( ! yaml_parser_initialize( & parser)) {
fputs( "Failed to initialize parser\n " , stderr) ;
fclose( fh) ;
return NULL;
}
yaml_parser_set_input_file( & parser, fh) ;
GList *server_list = NULL;
server_t *current_server = NULL;
int in_servers = 0 ; // Are we parsing the 'servers' section?
int in_roles = 0 ; // Are we parsing the 'roles' section of a server?
char current_key[ MAX_NAME_LEN] = "" ; // Current key being parsed
while ( 1 ) {
if ( ! yaml_parser_parse( & parser, & event)) {
fprintf( stderr, "Parser error %d\n " , parser.error) ;
goto cleanup;
}
print_event( & event) ;
if ( event.type == YAML_STREAM_END_EVENT) {
yaml_event_delete( & event) ;
break ;
}
switch ( event.type) {
case YAML_MAPPING_START_EVENT:
if ( in_servers && ! current_server) {
// Starting a new server object
current_server = g_new0( server_t, 1 ) ;
}
break ;
case YAML_MAPPING_END_EVENT:
if ( current_server) {
// Finished parsing a server object
server_list = g_list_append( server_list, current_server) ;
current_server = NULL;
}
break ;
case YAML_SCALAR_EVENT:
if ( ! in_servers) {
// We are at the root level expecting the 'servers' key
if ( strcmp(( char * ) event.data.scalar.value, "servers") == 0 ) {
in_servers = 1 ;
}
} else if ( current_server && ! in_roles) {
/ / Not in roles, this must be a key or value for the server
if ( strlen( current_key) == 0 ) {
/ / This is a key
strncpy( current_key, ( char * ) event.data.scalar.value, MAX_NAME_LEN) ;
} else {
/ / This is a value
if ( strcmp( current_key, "name") == 0 ) {
strncpy( current_server- > name, ( char * ) event.data.scalar.value, MAX_NAME_LEN) ;
} else if ( strcmp( current_key, "ip") == 0 ) {
strncpy( current_server- > ip, ( char * ) event.data.scalar.value, MAX_IP_LEN) ;
}
current_key[0 ] = '\0 '; / / Reset current_key after usage
}
} else if ( current_server && in_roles) {
/ / In roles sequence, add this role to the current server
if ( current_server- > role_count < MAX_ROLES) {
strncpy( current_server- > roles[current_server- > role_count], ( char * ) event.data.scalar.value, MAX_NAME_LEN) ;
current_server- > role_count++ ;
}
}
break;
case YAML_SEQUENCE_START_EVENT:
if ( current_server && strcmp( current_key, "roles") == 0 ) {
in_roles = 1 ; / / Start of roles sequence
current_key[0 ] = '\0 '; / / Reset current_key after usage
}
break;
case YAML_SEQUENCE_END_EVENT:
if ( in_roles) {
in_roles = 0 ; / / End of roles sequence
}
break;
default:
break;
}
yaml_event_delete( & event) ;
}
cleanup:
yaml_parser_delete( & parser) ;
fclose( fh) ;
return server_list;
}
int main( void) {
GList * server_list = get_array_config_yaml( "config.yaml") ;
/ / Print the parsed data
for ( GList * iter = server_list; iter != NULL; iter = g_list_next( iter)) {
server_t *server = ( server_t *) iter-> data;
printf( "Server Name: %s\n " , server-> name) ;
printf( "IP Address: %s\n " , server-> ip) ;
printf( "Roles: " ) ;
for ( int j = 0 ; j < server-> role_count; ++j) {
printf( "%s " , server-> roles[ j] ) ;
}
printf( "\n " ) ;
}
// Free the server list memory
for ( GList *iter = server_list; iter != NULL; iter = g_list_next( iter)) {
server_t *server = ( server_t *) iter-> data;
g_free( server) ;
}
g_list_free( server_list) ;
return 0 ;
}
编译:
gcc -o parse_yaml main.c -I/usr/local/eyou/gateway/ebaselib/include/ -L/usr/local/eyou/gateway/ebaselib/lib/ -lyaml $( pkg-config --cflags --libs glib-2.0)
执行
./parse_yaml
结果:
STREAM START
Start Document
Start Mapping
Scalar: servers
Start Sequence
Start Mapping
Scalar: name
Scalar: server1
Scalar: ip
Scalar: 192.168 .1.1
Scalar: roles
Start Sequence
Scalar: web
Scalar: database
End Sequence
End Mapping
Start Mapping
Scalar: name
Scalar: server2
Scalar: ip
Scalar: 192.168 .1.2
Scalar: roles
Start Sequence
Scalar: web
End Sequence
End Mapping
Start Mapping
Scalar: name
Scalar: server3
Scalar: ip
Scalar: 192.168 .1.3
Scalar: roles
Start Sequence
Scalar: database
End Sequence
End Mapping
End Sequence
End Mapping
End Document
STREAM END
Server Name: server1
IP Address: 192.168 .1.1
Roles: web database
Server Name: server2
IP Address: 192.168 .1.2
Roles: web
Server Name: server3
IP Address: 192.168 .1.3
Roles: database