www.pudn.com > rDUNclientBeta1.zip > 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#include #include #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 ( stricmp( 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 ( stricmp( 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]; itoa( def, str, 10 ); 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 ( stricmp( 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 ( stricmp( 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 ( stricmp( 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 ); }