%pointer
%e 150
%p 400
%n 80
%k 80
%a 250
%o 500


%{
/*
 * Copyright 2006-2015, Thomas Maier-Komor
 * LICENSE: GPLv2, see file COPYING for details
 */

#include "log.h"
#include "tokens.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define YY_NO_UNPUT
#define YY_NO_SCAN_STRING
#define YY_NO_SCAN_BYTES

#ifdef DEBUGLEX
#define debuglex1 dbug
#define debuglex2 dbug
#else
#define debuglex1(a)
#define debuglex2(a,b)
#endif

#define YY_NO_INPUT
extern int input_data(char *,size_t);
#define YY_INPUT(buf,result,maxsize) (result = input_data(buf,maxsize))

char *Buffer;
size_t Fill;

%}

CD		^{WHITESP}?"cd"{WHITESP}([^ \t\n]+|{DQUOTED}|{SQUOTED}){WHITESP}?";"
IGNNL		"\\\n"
WHITESP		[ \t]+
COMMENT		^#[^\n]*\n
SEQUPT		^%%\n
ESQUOTE		\\['\n]
EDQUOTE		\\["\n]
DQUOTED		\"([^"\n\\]|{EDQUOTE})*\"
SQUOTED		"'"([^'\n\\]|{ESQUOTE})*"'"
ESPACE		"\\ "
UQUOTED		[^ \t\n'"<>]([^ \t\n]|{ESPACE})*
RDIN		"<"
RDOUT		">"
RDOUTF		">!"
RDAPP		">>"
RDOE		">&"
RDAOE		">>&"

%%

{WHITESP}	{
	debuglex1("W ");
	}

{CD}		{
	char *at = yytext;
	Fill = yyleng;
	Buffer = yytext;
	Buffer[Fill] = 0;
	while ((*at == ' ') || (*at == '\t'))
		++at;
	assert(memcmp(at,"cd",2) == 0);
	at += 2;
	while ((*at == ' ') || (*at == '\t'))
		++at;
	if (*at == '\'') {
		++at;
		Fill -= at - Buffer;
		Buffer = at;
		assert(Buffer[Fill-1] == ';');
		do {
			--Fill;
			Buffer[Fill] = 0;
		} while ((Buffer[Fill] == ' ') || (Buffer[Fill] == '\t'));
		assert(Buffer[Fill - 1] == '\'');
		--Fill;
		Buffer[Fill] = 0;
	} else if (*at == '"') {
		++at;
		Fill -= at - Buffer;
		Buffer = at;
		assert(Buffer[Fill-1] == ';');
		do {
			--Fill;
			Buffer[Fill] = 0;
		} while ((Buffer[Fill] == ' ') || (Buffer[Fill] == '\t'));
		assert(Buffer[Fill - 1] == '"');
		--Fill;
		Buffer[Fill] = 0;
	} else {
		Fill -= at - Buffer;
		Buffer = at;
		assert(Buffer[Fill-1] == ';');
		do {
			--Fill;
			Buffer[Fill] = 0;
		} while ((Buffer[Fill] == ' ') || (Buffer[Fill] == '\t'));
	}
	debuglex2("CD(%s) ",Buffer);
	return CD;
	}

{UQUOTED}	{
	char *at = yytext, *esc;
	Fill = yyleng;
	Buffer = yytext;
	while ((esc = strchr(at,'\\'))) {
		at = esc + 1;
		if ((*at == ' ') || (*at == '\t')) {
			size_t l = Fill - (at - Buffer) + 1;
			memmove(esc, at, l);
			--Fill;
		}
	}
	Buffer[Fill] = 0;
	debuglex2("UQ(%s) ",Buffer);
	return UQUOTED;
	}

{DQUOTED}	{
	char *at = yytext + 1, *esc;
	Fill = yyleng - 2;
	Buffer = at;
	while ((esc = strchr(at,'\\'))) {
		at = esc + 1;
		if ((*at == '"') || (*at == '\n')) {
			size_t l = Fill - (at - Buffer) + 1;
			memmove(esc, at, l);
			--Fill;
		}
	}
	Buffer[Fill] = 0;
	debuglex2("DQ(%s) ",Buffer);
	return DQUOTED;
	}

{SQUOTED}	{
	char *at = yytext + 1, *esc;
	Fill = yyleng - 2;
	Buffer = at;
	while ((esc = strchr(at,'\\'))) {
		at = esc + 1;
		if ((*at == '\'') || (*at == '\n')) {
			size_t l = Fill - (at - Buffer) + 1;
			memmove(esc, at, l);
			--Fill;
		}
	}
	Buffer[Fill] = 0;
	debuglex2("S(%s) ",Buffer);
	return SQUOTED;
	}

{RDIN}		{
	debuglex1("I ");
	return INPUT;
	}

{RDAPP}		{
	debuglex1("a ");
	return APPEND;
	}

{RDOUT}		{
	debuglex1("O ");
	return OUTPUT;
	}

{RDOUTF}	{
	debuglex1("O ");
	return OVWROUTPUT;
	}

{RDOE}		{
	debuglex1("E ");
	return ERRLOG;
	}

{RDAOE}		{
	debuglex1("A ");
	return APPERR;
	}

{SEQUPT}	{
	debuglex1("P ");
	return SEQUPT;
	}

{COMMENT}	{
	}

{IGNNL}		{
	}

\n		{
	debuglex1("E\n");
	return EOL;
	}

.		{
	warn("unexpected charakter in input: %s\n", yytext);
	return ERR;
	}

%%


