#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "misc/parser.h"
#include "system/xstdlib.h"

/******************************************************************
 * Function  : parse_init                                         *
 * Input     : char *s                                            *
 * Return    : A pointer to the parser struct                     *
 * Effect    : Initializes the parser                             *
 * Comments  : -                                                  *
 ******************************************************************/

PARSE *parse_init(char *s)
{
	PARSE *p;

	p=xsafe_malloc(sizeof(PARSE));
	p->text=s;

	return p;
}

/******************************************************************
 * Function  : parse_exit                                         *
 * Input     : PARSE *p                                           *
 * Return    : -                                                  *
 * Effect    : Cleans up a parser session                         *
 * Comments  : -                                                  *
 ******************************************************************/

void parse_exit(PARSE *p)
{
  xfree(p);
}

/******************************************************************
 * Function  : parse_get                                          *
 * Input     : char *p                                            *
 *             char *s                                            *
 * Return    : A pointer to the token if aviable, otherwise NULL. *
 * Effect    : Gets a token                                       *
 * Comments  : -                                                  *
 ******************************************************************/

char *parse_get(PARSE *p, char *s)
{
	char *t=s;
	static char separators[]="[](){}<>=\"";

	while (isspace(*p->text)) p->text++;
	if (!*p->text)
	{
		*s='\0';
		return NULL;
	}

	if (strchr(separators,*p->text)) *(s++)=*(p->text++);

	else
		while (!strchr(separators,*p->text) && !isspace(*p->text) && *p->text)
			*(s++)=*(p->text++);

	*s='\0';
	return t;
}

/******************************************************************
 * Function  : parse_peek                                         *
 * Input     : char *p                                            *
 *             char *s                                            *
 * Return    : A pointer to the token if aviable, otherwise NULL.	*
 * Effect    : Gets a token, but does not advance the pointer     *
 * Comments  : -                                                  *
 ******************************************************************/

char *parse_peek(PARSE *p, char *s)
{
	char *t=p->text,*r;

	r=parse_get(p,s);
	p->text=t;

	return r;
}

/******************************************************************
 * Function  : parse_safeget                                      *
 * Input     : char *p                                            *
 *             char *s                                            *
 * Return    : A pointer to the token                             *
 * Effect    : Gets a token                                       *
 * Comments  : If no token is aviable this function types an      *
 *             error message, then exits.                         *
 ******************************************************************/

char *parse_safeget(PARSE *p, char *s)
{
	char *t;

	t=parse_get(p,s);
	if (!t)
	{
		fprintf(stderr, "Parse error: Unexpected end of file.\n");
		exit(-1);
	}
	return t;
}

/******************************************************************
 * Function  : parse_safepeek                                     *
 * Input     : char *p                                            *
 *             char *s                                            *
 * Return    : A pointer to the token                             *
 * Effect    : Gets a token, but does not advance the pointer			*
 * Comments  : If no token is aviable this function types an      *
 *             error message, then exits.                         *
 ******************************************************************/

char *parse_safepeek(PARSE *p, char *s)
{
	char *t;

	t=parse_peek(p,s);
	if (!t)
	{
		fprintf(stderr, "Parse error: Unexpected end of file.\n");
		exit(-1);
	}

	return t;
}

int parse_geti(PARSE *p)
{
	char tok[256];
	DWORD i;

	parse_safeget(p,tok);
	for (i=0; i<strlen(tok); i++)
		if (!isdigit(tok[i]) && !strchr("-+",tok[i]))
		{
			fprintf(stderr, "Parse error: Malformed integer.\n");
			exit( -1);
		}

	return atoi(tok);
}

float parse_getf(PARSE *p)
{
	char tok[256];
  float f;
	int i;

	parse_safeget(p,tok);

  // exchange , to standard dot....

  for (i=0;i<strlen (tok);i++)
		if (tok[i]==',') tok[i]='.';

	if( sscanf( tok, "%f", &f) != 1)
	{
		fprintf(stderr, "Parse error: Malformed float.\n");
		exit(-1);
	}

	return( f);
}

void parse_this(PARSE *p, char *s)
{
	char tok[256];

	parse_get(p,tok);
	if (stricmp(s,tok))
	{
		fprintf(stderr, "Parse error: Expected '%s', but found '%s'.\n",s,tok);
		exit( -1);
	}
}

int parse_case(char *tok, char *s)
{
	char l[256];
	int n=0,i;
	PARSE *q;

	if (!tok) return 0;
	q=parse_init(s);
	for (i=1; parse_get(q,l); i++)
		if (!stricmp(l,tok)) n=i;
	parse_exit(q);
	return n;
}

/*int main(void)
{
	char *s="asdf hej hopp(\nasf ) 124\n1asf    \n",t[256];
	PARSE *p;

	printf("---\n");
	p=parse_init(s);
	printf("%d\n",parse_case(p,"a b c d e f"));
	printf("%s\n",parse_peek(p,t));
	while (parse_get(p,t)) printf("%s\n",t);
	parse_exit(p);

	return 0;
}*/
