/* bluebox distributor
 * version 0.3.2 date 2007-07-18
 * Copyright (C) 2006-2007 Stefan Schuermans <stefan@blinkenarea.org>
 * Copyleft: GNU public license V2.0 - http://www.gnu.org/copyleft/gpl.html
 * a BlinkenArea project - http://www.blinkenarea.org/
 */

#include <stdio.h>
#include <string.h>

#include "config.h"

//parse config file
void config_parse( char * filename, st_config_setting * p_settings, int settings_cnt )
{
  int i, len;
  FILE * p_file;
  char section[256], line[1024], dummy[1024], * p_lf, * p_hash, * p_line, * p_equal, * p_setting, * p_value, * p_append;

  //empty all strings in settings array
  for( i = 0; i < settings_cnt; i++ )
    if( p_settings[i].buffer != NULL && p_settings[i].buffer_len > 0 )
      p_settings[i].buffer[0] = 0;

  //check filename (fopen segaults in these cases)
  if( filename == NULL || filename[0] == 0 )
  {
    printf( "no config file was supplied\n" );
    return;
  }

  //open file
  p_file = fopen( filename, "rt" );
  if( p_file == NULL )
  {
    printf( "could not open config file \"%s\"\n", filename );
    return;
  }

  //no section yet
  section[0] = 0;

  //read file
  while( !feof( p_file ) )
  {
    //read a line
    line[0] = 0;
    fgets( line, sizeof( line ), p_file );
    //find LF in line in replace it with 0
    p_lf = strchr( line, '\n' );
    if( p_lf != NULL )
    {
      *p_lf = 0;
    }
    //no LF in line
    else
    {
      //jump over in rest of line
      dummy[0] = 0;
      while( !feof( p_file ) && strchr( dummy, '\n' ) == NULL )
        fgets( dummy, sizeof( dummy ), p_file );
    }

    //remove comment
    p_hash = strchr( line, '#' );
    if( p_hash != NULL )
      *p_hash = 0;

    //remove trailing whitespaces
    for( i = strlen( line ) - 1; i >= 0 && (line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '\n'); i-- )
      line[i] = 0;

    //remove leading whitespaces
    for( p_line = line; *p_line == ' ' || *p_line == '\t' || *p_line == '\r' || *p_line == '\n'; p_line++ );

    //find equal sign
    p_equal = strchr( p_line, '=' );
    //no equal sign found
    if( p_equal == NULL )
    {
      //line not empty
      if( p_line[0] != 0 )
      {
        //new section
        section[0] = 0;
        strncat( section, p_line, sizeof( section ) - 1 );
      }
    }
    //equal sign found
    else
    {
      //split string at equal sign
      *p_equal = 0;
      p_setting = p_line;
      p_value = p_equal + 1;

      //remove trailing whitespaces in setting name
      for( i = strlen( p_setting ) - 1; i >= 0 && (p_setting[i] == ' ' || p_setting[i] == '\t' || p_setting[i] == '\r' || p_setting[i] == '\n'); i-- )
        p_setting[i] = 0;

      //remove leading whitespaces in value
      for( ; *p_value == ' ' || *p_value == '\t' || *p_value == '\r' || *p_value == '\n'; p_value++ );

      //find where to save value
      for( i = 0; i < settings_cnt; i++ )
        if( strcasecmp( section, p_settings[i].section ) == 0 && strcasecmp( p_setting, p_settings[i].setting ) == 0 )
          break;
      //place to save value found and buffer supplied
      if( i < settings_cnt && p_settings[i].buffer != NULL && p_settings[i].buffer_len > 0 )
      {
        //save value (append value behind already saved value)
        len = strlen( p_settings[i].buffer ); //get length of current value
        if( len == 0 ) //no value saved yet
        {
          strncat( p_settings[i].buffer, p_value, p_settings[i].buffer_len - 1 ); //save value
        }
        else if( p_settings[i].separate_char != 0 ) //already saved a value and appending requested
        {
          p_append = p_settings[i].buffer + len; //get pointer to position where to append and rest length of buffer
          len = p_settings[i].buffer_len - len - 1;
          if( len > 0 ) //append separation character
          {
            p_append[0] = p_settings[i].separate_char;
            p_append[1] = 0;
            p_append++;
            len--;
          }
          strncat( p_append, p_value, len ); //append value
        }
      }
    }
  } //while( !feof( p_file ) )

  //close file
  fclose( p_file );
}

