diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2008-12-24 09:00:42 +0000 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2008-12-24 09:00:42 +0000 |
commit | 72b6783ebf2af43a384364e62eab71b1c5e6f9c1 (patch) | |
tree | cfa01d284089fff35faa6d8c42a8e6ec04330597 /lib/ini.c | |
parent | 54699524eda49bb287d5998e443deefd81fce8fc (diff) |
First version of new ini parser. Will just attempt to simplify code a bit.
Diffstat (limited to 'lib/ini.c')
-rw-r--r-- | lib/ini.c | 128 |
1 files changed, 91 insertions, 37 deletions
@@ -1,7 +1,7 @@ /********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * - * Copyright 2002-2005 Wilmer van der Gaast and others * + * Copyright 2002-2008 Wilmer van der Gaast and others * \********************************************************************/ /* INI file reading code */ @@ -27,64 +27,118 @@ ini_t *ini_open( char *file ) { - ini_t *ini = g_new0( ini_t, 1 ); + int fd; + ini_t *ini = NULL; + struct stat fi; - if( ( ini->fp = fopen( file, "r" ) ) == NULL ) + if( ( fd = open( file, O_RDONLY ) ) != -1 && + fstat( fd, &fi ) == 0 && + fi.st_size <= 16384 && + ( ini = g_malloc( sizeof( ini_t ) + fi.st_size + 1 ) ) && + read( fd, ini->file, fi.st_size ) == fi.st_size ) { - g_free( ini ); - return( NULL ); + memset( ini, 0, sizeof( ini_t ) ); + ini->size = fi.st_size; + ini->file[ini->size] = 0; + ini->cur = ini->file; + ini->c_section = ""; + return ini; } - return( ini ); + g_free( ini ); + if( fd >= 0 ) + close( fd ); + + return NULL; } int ini_read( ini_t *file ) { - char key[MAX_STRING], s[MAX_STRING], *t; - int i; + char *s; - while( !feof( file->fp ) ) + while( file->cur && file->cur < file->file + file->size ) { - *s = 0; - fscanf( file->fp, "%127[^\n#]s", s ); - fscanf( file->fp, "%*[^\n]s" ); - fgetc( file->fp ); /* Skip newline */ - file->line ++; - if( strchr( s, '=' ) ) + char *e, *next; + + file->line++; + + /* Leading whitespace */ + while( *file->cur == ' ' || *file->cur == '\t' ) + file->cur++; + + /* Find the end of line */ + if( ( e = strchr( file->cur, '\n' ) ) != NULL ) + { + next = e + 1; + } + else + { + /* No more lines. */ + e = file->cur + strlen( file->cur ) - 1; + next = NULL; + } + + /* Comment? */ + if( ( s = strchr( file->cur, '#' ) ) != NULL ) + e = s - 1; + + /* And kill trailing whitespace. */ + while( isspace( *e ) && e > file->cur ) + e--; + e[1] = 0; + + printf( "Stripped line: '%s'\n", file->cur ); + + if( *file->cur == '[' ) + { + file->cur++; + if( ( s = strchr( file->cur, ']' ) ) != NULL ) + { + *s = 0; + file->c_section = file->cur; + + printf( "Section started: %s\n", file->c_section ); + } + } + else if( ( s = strchr( file->cur, '=' ) ) != NULL ) { - sscanf( s, "%[^ =]s", key ); - if( ( t = strchr( key, '.' ) ) ) + *s = 0; + file->value = s + 1; + while( isspace( *file->value ) ) + file->value++; + + s--; + while( isspace( *s ) && s > file->cur ) + s--; + s[1] = 0; + file->key = file->cur; + + if( ( s = strchr( file->key, '.' ) ) != NULL ) { - *t = 0; - strcpy( file->section, key ); - t ++; + *s = 0; + file->section = file->key; + file->key = s + 1; } else { - strcpy( file->section, file->c_section ); - t = key; + file->section = file->c_section; } - sscanf( t, "%s", file->key ); - t = strchr( s, '=' ) + 1; - for( i = 0; t[i] == ' '; i ++ ); - strcpy( file->value, &t[i] ); - for( i = strlen( file->value ) - 1; file->value[i] == 32; i -- ) - file->value[i] = 0; - return( 1 ); - } - else if( ( t = strchr( s, '[' ) ) ) - { - strcpy( file->c_section, t + 1 ); - t = strchr( file->c_section, ']' ); - *t = 0; + file->cur = next; + + printf( "%s.%s = '%s'\n", file->section, file->key, file->value ); + + return 1; } + /* else: noise, but let's just ignore it. */ + + file->cur = next; } - return( 0 ); + + return 0; } void ini_close( ini_t *file ) { - fclose( file->fp ); g_free( file ); } |