#include <stdio.h>
#include <stdlib.h>
#include "inifile.h"

void ini_init()
{
}

void ini_dump(inifile *i)
{
element *e=head(i->data);

while (e->next!=NULL)
 {
  e=e->next;
  printf("%04d [%2d] : %s\n", E2I(e)->line_nr , E2I(e)->class, E2I(e)->buf);
 }
}

int ini_goto_grp(inifile *i, char *name)
{
 int r=0;
  
 ini_rewind(i);
 while ((strcasecmp(i->sts.cur_grp, name)!=0) && (r!=-255))
  {
   r=ini_nextgrp(i);
  }
 
 if ((strcasecmp(i->sts.cur_grp, name)!=0))
  r=-1;
 else
  r=0;
 
 return(r);
}

inifile *ini_open(char *name)
{
inifile *r=(inifile *)malloc(sizeof(inifile));
ini_line curbuf;
char readbuf[1023];

 curbuf.line_nr=0;
 r->name=(char *)strdup(name);
 r->f=fopen(name, "r");
 r->data=newchain();

 strcpy(r->sts.cur_grp,"");

 if (r->f==NULL)
  {
   free(r->name);
   free(r);
  }
 
 
 while (!feof(r->f))
  {
   fgets(readbuf, 1023, r->f);
   curbuf.line_nr++;
   curbuf.class=ini_classify(readbuf);
   if ((curbuf.class!=INI_CLS_CMNT) && (curbuf.class!=INI_CLS_NULL))
   {
    curbuf.buf=(char *)strdup(readbuf);
    r->data=addelement(&curbuf, sizeof(curbuf), r->data);
   } 
  }
 
 r->data=head(r->data);
return(r);
}

int ini_nextgrp(inifile *i)
{
int r=-1; // Fail by default!
char *tmp=(char *)malloc(1024);
char *tmp2;

if (i->data->next!=NULL)
{
 strcpy(tmp, "#");
 if (i->data->cur==NULL) i->data=i->data->next;
 while ((E2I(i->data)->class!=INI_CLS_GRP) && (i->data->next!=NULL))
  {
   i->data=i->data->next;
  }
 
 if (E2I(i->data)->class==INI_CLS_GRP)
  {
   tmp2=ini_grp2s(E2I(i->data)->buf);
   if (tmp2!=NULL)
   {
    strncpy(i->sts.cur_grp, tmp2, 511); 
    r=0;
   }
  }
} else
{
 return(-255);
} 

free(tmp);
return(r);
}

void ini_rewind(inifile *i)
{
 
 strcpy(i->sts.cur_grp, "");
 i->data=head(i->data)->next;

}

void ini_close(inifile *i)
{
 fclose(i->f);
 free(i->name);
 free(i);
}

char *ini_nextline(inifile *i)
{
char buffer[1024];
char *r=buffer;
element *e=i->data;

 if (e->next!=NULL)
 {
  e=e->next;
  if (E2I(e)->class==INI_CLS_DATA)
   {
    return((char *)strdup(E2I(e)->buf));
   }
   else
   {
    return(NULL);
   }
 }  
}

char *ini_grp2s(char *s)
{
 char *r=(char *)strdup(s);
 char *tmp;
 
 if (strlen(r)>0)
  {
   if (r[0]=='[')
    {
     r++;
     if (strrchr(r,']')!=NULL)
      {
       tmp=(char *)strrchr(r,']');
       tmp[0]=0x00;
      } else
      {
       free(r);
       return(NULL);
      }
    }
  }
 return(r); 
}

char *ini_trim(char *s)
{
 if (strlen(s)>0)
  {
   while ((s[0]==' ')&&(strlen(s)>0))
    {
     s++;
    }
  }
 return(s); 
}

int ini_classify(char *s)
{
char *w=ini_trim(s); //working string
int r=INI_CLS_DATA;

 if (strlen(s)>0)
  {
   switch (w[0])
    {
     case '[':
      r=INI_CLS_GRP;
      break;

     case '#':
      r=INI_CLS_CMNT;
      break;

     case ';':
      r=INI_CLS_CMNT;
      break;
    }
  } else
  {
   r=INI_CLS_NULL;
  }
  
return(r);
}


syntax highlighted by Code2HTML, v. 0.9.1