/*
  (c) 1998 netEstate (http://www.netestate.de/, info@netestate.de),
Michael Brunnbauer & Markus Hendel, Gesellschaft fuer Netzwerkkommunikation bR
Am Bluetenanger 8, 80995 Muenchen, Germany

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
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 "parselib.h"

long tonumber(char* buf)
{
  char* endptr;
  long rueck;

  rueck=strtol(buf,&endptr,10);
  if (endptr[0])
    {
      log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
          "tonumber(), string '%s' is not a valid number",buf);
    };
  return rueck;
}

double todouble(char* buf)
{
  char* endptr;
  double rueck;

  rueck=strtod(buf,&endptr);
  if (endptr[0])
    {
      log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
          "todouble(), string '%s' is not a valid number",buf);
    };
  return rueck;
}

int parse_seps(char* output,size_t size,FILE* fh,char* sep)
{
  size_t pointer=0;
  size_t len_sep=strlen(sep);
  
  if (size<=1)
    {
      log(LOG_WARN,__FILE__,__LINE__,0,
          "Argument size to parse_seps(FILE*) <= 1");
      return -1;
    };

  while ((output[pointer++]=fgetc(fh))!=EOF)
    {
      output[pointer]=0;

      /* wenn der string schon gross genug ist, suchen wir nach needle */
      if (pointer>=len_sep)
        {
          if (!strcmp(output+pointer-len_sep,sep))
            {
              output[pointer-len_sep]=0;
	      log(LOG_DEBUG,__FILE__,__LINE__,0,
		  "parse_seps(FILE*): string '%s' returned",output);
              return 1;
            };
        };

      /* ist output gross genug fuer den naechsten durchlauf ? */
      if (pointer+1>size)
        {
          log(LOG_WARN,__FILE__,__LINE__,0,
              "Argument 'size' for parse_seps(FILE*) was too little: %lu",size);
          return -1;
        };
    };

  output[pointer-1]=0;
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "parse_seps(FILE*): string '%s' returned (EOF)",output);
  return 0;
}

int parse_seps(char* output,size_t size,char** src,char* sep)
{
  size_t pointer=0;
  size_t len_sep=strlen(sep);
  
  if (size<=1)
    {
      log(LOG_WARN,__FILE__,__LINE__,0,
          "Argument size to parse_seps(char**) <= 1");
      return -1;
    };

  while ((output[pointer++]=*((*src)++))!=0)
    {
      output[pointer]=0;

      /* wenn der string schon gross genug ist, suchen wir nach needle */
      if (pointer>=len_sep)
        {
          if (!strcmp(output+pointer-len_sep,sep))
            {
              output[pointer-len_sep]=0;
	      log(LOG_DEBUG,__FILE__,__LINE__,0,
		  "parse_seps(char**): string '%s' returned",output);
              return 1;
            };
        };

      /* ist output gross genug fuer den naechsten durchlauf ? */
      if (pointer+1>size)
        {
          log(LOG_WARN,__FILE__,__LINE__,0,
              "Argument 'size' for parse_seps(char**) was too little: %lu",size);
          return -1;
        };
    };

  output[pointer-1]=0;
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "parse_seps(char**): string '%s' returned (EOF)",output);
  return 0;
}

int parse_sepc(char* output,size_t size,FILE* fh,char* sep)
{
  size_t pointer=0;
  size_t len_sep=strlen(sep);
  size_t i;

  if (size<=1)
    {
      log(LOG_WARN,__FILE__,__LINE__,0,
          "Argument size to parse_sepc(FILE*) <= 1");
      return -1;
    };

  while ((output[pointer++]=fgetc(fh))!=EOF)
    {
      output[pointer]=0;

      for (i=0;i!=len_sep;i++)
        {
          if (output[pointer-1]==sep[i])
            {
              output[pointer-1]=0;
	      log(LOG_DEBUG,__FILE__,__LINE__,0,
		  "parse_sepc(FILE*): string '%s' returned",output);
              return 1;
            };
        };

      /* ist output gross genug fuer den naechsten durchlauf ? */
      if (pointer+1>size)
        {
          log(LOG_WARN,__FILE__,__LINE__,0,
              "Argument 'size' for parse_sepc(FILE*) was too little: %lu",size);
          return -1;
        };
    };

  output[pointer-1]=0;
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "parse_sepc(FILE*): string '%s' returned (EOF)",output);
  return 0;
}

int parse_sepc(char* output,size_t size,char** src,char* sep)
{
  size_t pointer=0;
  size_t len_sep=strlen(sep);
  size_t i;

  if (size<=1)
    {
      log(LOG_WARN,__FILE__,__LINE__,0,
          "Argument size to parse_sepc(char**) <= 1");
      return -1;
    };

  while ((output[pointer++]=*((*src)++))!=0)
    {
      output[pointer]=0;

      for (i=0;i!=len_sep;i++)
        {
          if (output[pointer-1]==sep[i])
            {
              output[pointer-1]=0;
	      log(LOG_DEBUG,__FILE__,__LINE__,0,
		  "parse_sepc(char**): string '%s' returned",output);
              return 1;
            };
        };

      /* ist output gross genug fuer den naechsten durchlauf ? */
      if (pointer+1>size)
        {
          log(LOG_WARN,__FILE__,__LINE__,0,
              "Argument 'size' for parse_sepc(char**) was too little: %lu",size);
          return -1;
        };
    };

  output[pointer-1]=0;
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "parse_sepc(char**): string '%s' returned (EOF)",output);
  return 0;
}

int parse_string(string& rueck,FILE* fh,char* separator,int flags=0)
{
  char buf[MAX_LINE_SIZE];
  int status;
  
  buf[0]=0;
  do
    {
      status=parse_seps(buf,MAX_LINE_SIZE,fh,separator);
      if (status==-1)
	{
	  if (flags & PARSE_NOFATAL)
	    {
              log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
	      return -1;
	    }
	  else
	    {
	      log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
		  "separator '%s' not found: %s",separator,buf);
	    };
	};
    } while (!buf[0] && (flags & PARSE_REPEATE) && status);

  /* eine leere zeichenkette bedeutet einen undefinierten string ! */
  if (buf[0]) { rueck=buf; } else { rueck=0; };

  return status;
}

int parse_string(string& rueck,char** src,char* separator,int flags=0)
{
  char buf[MAX_LINE_SIZE];
  int status;

  buf[0]=0;
  do
    {
      status=parse_seps(buf,MAX_LINE_SIZE,src,separator);
      if (status==-1)
	{
          if (flags & PARSE_NOFATAL)
            {
              log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
              return -1;
            }
          else
            {
              log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
            };
	};
    } while (!buf[0] && (flags & PARSE_REPEATE) && status);

  /* eine leere zeichenkette bedeutet einen undefinierten string ! */
  if (buf[0]) { rueck=buf; } else { rueck=0; };

  return status;
}

int parse_number(long& rueck,FILE*fh,char* separator,int flags=0)
{
  return parse_scanf(fh,separator,flags,"%li",&rueck);
}

int parse_number(long& rueck,char** src,char* separator,int flags=0)
{
  return parse_scanf(src,separator,flags,"%li",&rueck);
}

int parse_double(double& rueck,FILE* fh,char* separator,int flags=0)
{
  return parse_scanf(fh,separator,flags,"%f",&rueck);
}

int parse_double(double& rueck,char** src,char* separator,int flags=0)
{
  return parse_scanf(src,separator,flags,"%f",&rueck);
}

int parse_stringc(string& rueck,FILE* fh,char* separator,int flags=0)
{
  char buf[MAX_LINE_SIZE];
  int status;

  buf[0]=0;
  do
    {
      status=parse_sepc(buf,MAX_LINE_SIZE,fh,separator);
      if (status==-1)
	{
          if (flags & PARSE_NOFATAL)
            {
              log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
              return -1;
            }
          else
            {
              log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
            };
	};
    } while (!buf[0] && (flags & PARSE_REPEATE) && status);

  /* eine leere zeichenkette bedeutet einen undefinierten string ! */
  if (buf[0]) { rueck=buf; } else { rueck=0; };

  return status;
}

int parse_stringc(string& rueck,char** src,char* separator,int flags=0)
{
  char buf[MAX_LINE_SIZE];
  int status;

  buf[0]=0;
  do
    {
      status=parse_sepc(buf,MAX_LINE_SIZE,src,separator);
      if (status==-1)
	{
          if (flags & PARSE_NOFATAL)
            {
              log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
              return -1;
            }
          else
            {
              log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                  "separator '%s' not found: %s",separator,buf);
            };
	};
    } while (!buf[0] && (flags & PARSE_REPEATE) && status);

  /* eine leere zeichenkette bedeutet einen undefinierten string ! */
  if (buf[0]) { rueck=buf; } else { rueck=0; };

  return status;
}

int parse_numberc(long& rueck,FILE*fh,char* separator,int flags=0)
{
  return parse_scanfc(fh,separator,flags,"%li",&rueck);
}

int parse_numberc(long& rueck,char** src,char* separator,int flags=0)
{
  return parse_scanfc(src,separator,flags,"%li",&rueck);
}

int parse_doublec(double& rueck,FILE* fh,char* separator,int flags=0)
{
  return parse_scanfc(fh,separator,flags,"%f",&rueck);
}

int parse_doublec(double& rueck,char** src,char* separator,int flags=0)
{
  return parse_scanfc(src,separator,flags,"%f",&rueck);
}

char* parse_date_months[]=
{
  "Jan",
  "Feb",
  "Mar",
  "Apr",
  "May",
  "Jun",
  "Jul",
  "Aug",
  "Sep",
  "Oct",
  "Nov",
  "Dec",
  ""
};

int parse_test_month(tm* t,char* buf,int flags)
{
  t->tm_mon=12;
  int i;

  for (i=0;parse_date_months[i][0];i++)
    {
      if (!strcmp(parse_date_months[i],buf))
        {
          t->tm_mon=i;break;
        };
    };

  if (t->tm_mon==12)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%s is not a valid month: ",(char*) buf);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%s is not a valid month: ",(char*) buf);
        };
    };

  return 1;
}

int parse_test_month(tm* t,int month,int flags)
{
  month--;

  if (month<0 || month>11)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid month: ",month);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid month: ",month);
        };
    };
  
  t->tm_mon=month;

  return 1;
}

int parse_test_day(tm* t,int day,int flags)
{
  if (day<1 || day >31)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid day: ",day);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid day: ",day);
        };
    };

  t->tm_mday=day;

  return 1;
}

int parse_test_hour(tm* t,int hour,int flags)
{
  if (hour<0 || hour >23)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid hour: ",hour);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid hour: ",hour);
        };
    };

  t->tm_hour=hour;
  
  return 1;
}

int parse_test_minute(tm* t,int minute,int flags)
{
  if (minute<0 || minute >59)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid minute: ",minute);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid minute: ",minute);
        };
    };
  t->tm_min=minute;

  return 1;
}

int parse_test_second(tm* t,int second,int flags)
{
  if (second<0 || second >61)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid second: ",second);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid second: ",second);
        };
    };
  t->tm_sec=second;

  return 1;
}

int parse_test_year(tm* t,int year,int flags)
{
  if (year<1970)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid year: ",year);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "%i is not a valid year: ",year);
        };
    };

  t->tm_year=year-1900;

  return 1;
}


/* '[15/Apr/1997:21:55:00 +0200] ' */
int parse_date1(time_t& rueck,char** src,int flags=0)
{
  tm t;
  int status;

  int day,year,hour,minute,second;
  char month[4];
  string dummy;

  month[3]=0;
  status=parse_scanfc(src," \n",flags,"[%d/%c%c%c/%d:%d:%d:%d",
		      &day,&month[0],&month[1],&month[2],
		      &year,&hour,&minute,&second);
  if (status==-1 || !status)
    {
      return status;
    };

  /* timezone (garbage) */
  status=parse_stringc(dummy,src," \n",flags);
  if (status==-1 || !status)
    {
      return status;
    };

  if (parse_test_day(&t,day,flags)==-1) { return -1; };
  if (parse_test_month(&t,month,flags)==-1) { return -1; };
  if (parse_test_year(&t,year,flags)==-1) { return -1; };
  if (parse_test_hour(&t,hour,flags)==-1) { return -1; };
  if (parse_test_minute(&t,minute,flags)==-1) { return -1; };
  if (parse_test_second(&t,second,flags)==-1) { return -1; };

  t.tm_isdst=-1;
  rueck=mktime(&t);
  if (rueck == -1)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
        };
    };

  return 1;
}

/* '01/16/1997:11:17:08:' */
int parse_date2(time_t& rueck,char** src,int flags=0)
{
  tm t;
  int status;

  int day,year,hour,minute,second,month;
  string dummy;

  status=parse_scanfc(src," \n",flags,"%d/%d/%d:%d:%d:%d:",
                      &month,&day,&year,&hour,&minute,&second);
  if (status==-1 || !status)
    {
      return status;
    };

  if (parse_test_day(&t,day,flags)==-1) { return -1; };
  if (parse_test_month(&t,month,flags)==-1) { return -1; };
  if (parse_test_year(&t,year,flags)==-1) { return -1; };
  if (parse_test_hour(&t,hour,flags)==-1) { return -1; };
  if (parse_test_minute(&t,minute,flags)==-1) { return -1; };
  if (parse_test_second(&t,second,flags)==-1) { return -1; };

  t.tm_isdst=-1;
  rueck=mktime(&t);
  if (rueck == -1)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
        };
    };

  return 1;
}

/* 'Jun 29 21:00:02 ' (syslog format, year = actual year) */
int parse_date_syslog(time_t& rueck,char** src,int flags=0)
{
  tm t;
  time_t now;
  int status;

  int day,year,hour,minute,second;
  char month[4];
  string dummy;

  month[3]=0;
  status=parse_scanfc(src," \n",flags,"%c%c%c",&month[0],&month[1],&month[2]);
  if (status==-1 || !status)
    {
      return status;
    };
  status=parse_scanfc(src," \n",flags,"%d",&day);
  if (status==-1 || !status)
    {
      return status;
    };
  status=parse_scanfc(src," \n",flags,"%d:%d:%d",&hour,&minute,&second);
  if (status==-1 || !status)
    {
      return status;
    };

  time(&now);
  year=1900+localtime(&now)->tm_year;

  if (parse_test_day(&t,day,flags)==-1) { return -1; };
  if (parse_test_month(&t,month,flags)==-1) { return -1; };
  if (parse_test_year(&t,year,flags)==-1) { return -1; };
  if (parse_test_hour(&t,hour,flags)==-1) { return -1; };
  if (parse_test_minute(&t,minute,flags)==-1) { return -1; };
  if (parse_test_second(&t,second,flags)==-1) { return -1; };

  t.tm_isdst=-1;
  rueck=mktime(&t);
  if (rueck == -1)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
        };
    };

  return 1;
}

/* 30.8.1997 11:17:08 */
int parse_date_brick(time_t& rueck,char** src,int flags=0)
{
  tm t;
  int status;

  int day,year,hour,minute,second,month;
  string dummy;

  status=parse_scanfc(src,". \n",flags,"%d",&day);
  if (status==-1 || !status) { return status; };

  status=parse_scanfc(src,". \n",flags,"%d",&month);
  if (status==-1 || !status) { return status; };

  status=parse_scanfc(src,". \n",flags,"%d",&year);
  if (status==-1 || !status) { return status; };

  status=parse_scanfc(src," \n",flags,"%d:%d:%d",
		      &hour,&minute,&second);
  if (status==-1 || !status)
    {
      return status;
    };

  if (parse_test_day(&t,day,flags)==-1) { return -1; };
  if (parse_test_month(&t,month,flags)==-1) { return -1; };
  if (parse_test_year(&t,year,flags)==-1) { return -1; };
  if (parse_test_hour(&t,hour,flags)==-1) { return -1; };
  if (parse_test_minute(&t,minute,flags)==-1) { return -1; };
  if (parse_test_second(&t,second,flags)==-1) { return -1; };

  t.tm_isdst=-1;
  rueck=mktime(&t);
  if (rueck == -1)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "error with mktime()");
        };
    };

  return 1;
}

int parse_scanf(FILE* fh,char* separator,int flags,char* fmt,...)
{
  va_list arg;
  string buf;
  int status;
  int anzarg=0;
  size_t i;

  status=parse_string(buf,fh,separator,flags);
  if (status==-1 || !status) { return status ; };

  if (!defined(buf))
    {
      if (flags & PARSE_NOFATAL)
        {
	  log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
	      "empty string for scanf");
	  return -1;
	}
      else
	{
	  log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "empty string for scanf");
	};
    };

  /* zu scannende elemente fuer scanf zaehlen */
  for (i=0;i!=strlen(fmt);i++)
    {
      if (fmt[i]=='%')
	{
	  if (fmt[i+1]=='%')
	    {
	      i++;
	    }
	  else
	    {
	      anzarg++;
	    };
	};
    };

  va_start(arg,fmt);
  status=vsscanf(buf,fmt,arg);
  if (status!=anzarg)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
        };
    };
  return 1;
}

int parse_scanf(char** src,char* separator,int flags,char* fmt,...)
{
  va_list arg;
  string buf;
  int status;
  int anzarg=0;
  size_t i;

  status=parse_string(buf,src,separator,flags);
  if (status==-1 || !status) { return status ; };

  if (!defined(buf))
    {
      if (flags & PARSE_NOFATAL)
        {
	  log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
	      "empty string for scanf");
	  return -1;
	}
      else
	{
	  log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "empty string for scanf");
	};
    };

  /* zu scannende elemente fuer scanf zaehlen */
  for (i=0;i!=strlen(fmt);i++)
    {
      if (fmt[i]=='%')
	{
	  if (fmt[i+1]=='%')
	    {
	      i++;
	    }
	  else
	    {
	      anzarg++;
	    };
	};
    };

  va_start(arg,fmt);
  status=vsscanf(buf,fmt,arg);
  if (status!=anzarg)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
        };
    };
  return 1;
}

int parse_scanfc(FILE* fh,char* separator,int flags,char* fmt,...)
{
  va_list arg;
  string buf;
  int status;
  int anzarg=0;
  size_t i;

  status=parse_stringc(buf,fh,separator,flags);
  if (status==-1 || !status) { return status ; };

  if (!defined(buf))
    {
      if (flags & PARSE_NOFATAL)
        {
	  log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
	      "empty string for scanf");
	  return -1;
	}
      else
	{
	  log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "empty string for scanf");
	};
    };

  /* zu scannende elemente fuer scanf zaehlen */
  for (i=0;i!=strlen(fmt);i++)
    {
      if (fmt[i]=='%')
	{
	  if (fmt[i+1]=='%')
	    {
	      i++;
	    }
	  else
	    {
	      anzarg++;
	    };
	};
    };

  va_start(arg,fmt);
  status=vsscanf(buf,fmt,arg);
  if (status!=anzarg)
     {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
          return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
        };
    };
  return 1;
}

int parse_scanfc(char** src,char* separator,int flags,char* fmt,...)
{
  va_list arg;
  string buf;
  int status;
  int anzarg=0;
  size_t i;

  status=parse_stringc(buf,src,separator,flags);
  if (status==-1 || !status) { return status ; };

  if (!defined(buf))
    {
      if (flags & PARSE_NOFATAL)
        {
	  log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
	      "empty string for scanf");
	  return -1;
	}
      else
	{
	  log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "empty string for scanf");
	};
    };

  /* zu scannende elemente fuer scanf zaehlen */
  for (i=0;i!=strlen(fmt);i++)
    {
      if (fmt[i]=='%')
	{
	  if (fmt[i+1]=='%')
	    {
	      i++;
	    }
	  else
	    {
	      anzarg++;
	    };
	};
    };

  va_start(arg,fmt);
  status=vsscanf(buf,fmt,arg);
  if (status!=anzarg)
    {
      if (flags & PARSE_NOFATAL)
        {
          log(LOG_WARN,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
	      (char*) buf,fmt,status);
	  return -1;
        }
      else
        {
          log(LOG_FATAL,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
              "vsscanf() failed: buf: %s fmt: %s status: %i",
              (char*) buf,fmt,status);
        };
    };
  return 1;
}



