📄 cfg.cpp
字号:
////// File: cfg.c// Desc: Configuration file parser//// Changelog: 04/08/2002 - Magicdude - Created basic parser, not very robust, no memory leaks// 05/08/2002 - Magicdude - Renamed cfgPrivateFindEntry to _cfgFindEntry
// 06/08/2002 - Magicdude - Added default parameters to cfgGet*
// 06/08/2002 - Magicdude - Fixed it so it doesnt append the EOF character to the final value.//////Copyright (C) Chris Barnaby 2002
//This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
//warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//You should have received a copy of the GNU General Public License along with this program; if not, write to the
//Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cfg.h"void cfgRelease( cfg_ptr cfg ){ if( !cfg ){ return; } cfgcategory_ptr curr_category; cfgentry_ptr curr_entry; curr_category = cfg->categories; while ( curr_category != NULL ) { curr_entry = curr_category->entries; while ( curr_entry != NULL ) { if ( curr_entry->next != NULL ) { curr_entry = curr_entry->next; free( curr_entry->prev ); } else { free( curr_entry ); curr_entry = NULL; } } if ( curr_category->next != NULL ) { curr_category = curr_category->next; free( curr_category->prev ); } else { free( curr_category ); curr_category = NULL; } } free( cfg );}cfg_ptr cfgParse( const char *filename ){ FILE *fp; char c; cfg_ptr cfg; cfgcategory_ptr curr_category; cfgentry_ptr curr_entry; int state; fp = fopen( filename, "rt" ); if ( fp == NULL ) { return NULL; } cfg = (cfg_ptr)malloc( sizeof( cfg_t ) ); memset( cfg, 0, sizeof( cfg_t ) ); strncpy( cfg->filename, filename, 29 ); curr_category = NULL; curr_entry = NULL; while ( feof( fp ) == 0 ) { c = fgetc( fp );
if ( c == EOF )
break;
switch ( c ) { case '[': { if ( cfg->categories == NULL ) { cfg->categories = (cfgcategory_ptr)malloc( sizeof( cfgcategory_t ) ); memset( cfg->categories, 0, sizeof( cfgcategory_t ) ); curr_category = cfg->categories; } else { if ( curr_category->next == NULL ) { curr_category->next = (cfgcategory_ptr)malloc( sizeof( cfgcategory_t ) ); memset( curr_category->next, 0, sizeof( cfgcategory_t ) ); curr_category->next->prev = curr_category; curr_category = curr_category->next; } } state = STATE_CATEGORY; }break; case ']': { state = STATE_GLOBAL; }break; case '=': { state = STATE_VALUE; }break; case '\n': { if ( curr_category->entries == NULL ) { curr_category->entries = (cfgentry_ptr)malloc( sizeof( cfgentry_t ) ); memset( curr_category->entries, 0, sizeof( cfgentry_t ) ); curr_entry = curr_category->entries; } else { if ( curr_entry->next == NULL ) { curr_entry->next = (cfgentry_ptr)malloc( sizeof( cfgentry_t ) ); memset( curr_entry->next, 0, sizeof( cfgentry_t ) ); curr_entry->next->prev = curr_entry; curr_entry = curr_entry->next; } } state = STATE_ENTRY; }break; default: { if ( state == STATE_CATEGORY ) curr_category->name[ strlen( curr_category->name ) ] = c; if ( state == STATE_ENTRY ) curr_entry->name[ strlen( curr_entry->name ) ] = c; if ( state == STATE_VALUE ) curr_entry->val[ strlen( curr_entry->val ) ] = c; } } } fclose( fp ); return cfg;}cfgentry_ptr _cfgFindEntry( cfg_ptr cfg, const char *category, const char *variable ){ if( !cfg ){ return NULL; } cfgcategory_ptr curr_category; cfgentry_ptr curr_entry; // First locate the category curr_category = cfg->categories; while ( curr_category != NULL ) { if ( strcasecmp( curr_category->name, category ) == 0 ) break; else curr_category = curr_category->next; } if ( curr_category == NULL ) return NULL; // Next locate the entry and return the integer result curr_entry = curr_category->entries; while ( curr_entry != NULL ) { if ( strcasecmp( curr_entry->name, variable ) == 0 ) break; else curr_entry = curr_entry->next; } return curr_entry;}int cfgGetInt( cfg_ptr cfg, const char *category, const char *variable, int def ){ cfgentry_ptr entry; entry = _cfgFindEntry( cfg, category, variable ); if ( entry == NULL ) return def; return atoi( entry->val );}
void cfgSetInt( cfg_ptr cfg, const char *category, const char *variable, int def )
{
char str[255];
memset( str, 0, sizeof( str )); sprintf( str, "%d", def );
cfgSetString( cfg, category, variable, str );
}const char *cfgGetString( cfg_ptr cfg, const char *category, const char *variable, const char *def ){ cfgentry_ptr entry; entry = _cfgFindEntry( cfg, category, variable ); if ( entry == NULL ) return def; return entry->val;}
void cfgSetString( cfg_ptr cfg, const char *category, const char *variable, const char *val )
{
cfgentry_ptr entry;
cfgcategory_ptr curr_category;
curr_category = cfg->categories;
while ( curr_category->next != NULL )
{
if ( strcasecmp( curr_category->name, category ) == 0 )
break;
curr_category = curr_category->next;
}
if ( curr_category->next != NULL )
{
entry = curr_category->entries;
while ( entry->next != NULL )
{
if ( strcasecmp( entry->name, variable ) == 0 )
break;
entry = entry->next;
}
}
else
{
curr_category->next = (cfgcategory_ptr)malloc( sizeof( cfgcategory_t ) );
memset( curr_category->next, 0, sizeof( cfgcategory_t ) );
curr_category->next->prev = curr_category;
memset( curr_category->next->name, 0, strlen( category ) + 1 );
strcpy( curr_category->next->name, category );
entry = (cfgentry_ptr)malloc( sizeof( cfgentry_t ) );
memset( entry, 0, sizeof( cfgentry_t ) );
memset( entry->name, 0, strlen( variable ) + 1 );
strcpy( entry->name, variable );
memset( entry->val, 0, strlen( val ) + 1 );
strcpy( entry->val, val );
curr_category->next->entries = entry;
}
if ( entry->next != NULL )
{
memset( entry->val, 0, strlen( val ) + 1 );
strcpy( entry->val, val );
}
else
{
entry->next = (cfgentry_ptr)malloc( sizeof( cfgentry_t ) );
memset( entry->next, 0, sizeof( cfgentry_t ) );
entry->next->prev = entry;
memset( entry->next->name, 0, strlen( variable ) + 1 );
strcpy( entry->next->name, variable );
memset( entry->next->val, 0, strlen( val ) + 1 );
strcpy( entry->next->val, val );
}
}
int cfgGetBoolean( cfg_ptr cfg, const char *category, const char *variable, int def ){ cfgentry_ptr entry; entry = _cfgFindEntry( cfg, category, variable ); if ( entry == NULL ) return def; if ( strcasecmp( entry->val, "true" ) == 0 ) return 1; else return 0;}
void cfgSetBoolean( cfg_ptr cfg, const char *category, const char *variable, int def )
{
if ( def == 1 )
{
cfgSetString( cfg, category, variable, "true" );
}
else
{
cfgSetString( cfg, category, variable, "false" );
}
}
void cfgWrite( cfg_ptr cfg )
{
cfgentry_ptr entry;
cfgcategory_ptr category;
FILE *fp;
category = cfg->categories;
fp = fopen( cfg->filename, "wt" );
while ( category != NULL )
{
fprintf( fp, "[%s]\n", category->name );
entry = category->entries;
while ( entry != NULL )
{
if ( strcmp( entry->name, "" ) != 0 )
fprintf( fp, "%s=%s\n", entry->name, entry->val );
entry = entry->next;
}
fprintf( fp, "\n" );
category = category->next;
}
fclose( fp );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -