From 401122a2457a293510e9bef33d98ae244b3fab23 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 22 Jan 2019 15:50:01 +0100
Subject: [PATCH] allow escape in identifiers and strings as file args

---
 alib2cli/src/lexer/Lexer.cpp   | 22 ++++++++++++++++++++++
 alib2cli/src/parser/Parser.cpp | 14 ++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/alib2cli/src/lexer/Lexer.cpp b/alib2cli/src/lexer/Lexer.cpp
index f9a332702f..12731fa3f0 100644
--- a/alib2cli/src/lexer/Lexer.cpp
+++ b/alib2cli/src/lexer/Lexer.cpp
@@ -126,6 +126,11 @@ q0:	if ( m_source->isEndOfTransmition ( ) ) {
 		goto q3;
 	}
 
+	if ( m_source->getCharacter ( ) == '\\' ) {
+		m_source->advance ( true );
+		goto q3Escape;
+	}
+
 	res.m_type = TokenType::ERROR;
 	return res;
 
@@ -160,6 +165,9 @@ q2:	if ( m_source->isEndOfSequence ( ) ) {
 		res.m_value += m_source->getCharacter ( );
 		m_source->advance ( readNextLine );
 		goto q3;
+	} else if ( m_source->getCharacter ( ) == '\\' ) {
+		m_source->advance ( true );
+		goto q3Escape;
 	}
 
 	res.m_value = "";
@@ -178,11 +186,25 @@ q3:	if ( m_source->isEndOfSequence ( ) ) {
 		res.m_value += m_source->getCharacter ( );
 		m_source->advance ( readNextLine );
 		goto q3;
+	} else if ( m_source->getCharacter ( ) == '\\' ) {
+		m_source->advance ( true );
+		goto q3Escape;
 	} else {
 		res.m_type = is_kw ( res.m_value );
 		return res;
 	}
 
+q3Escape:
+	if ( m_source->isEndOfSequence ( ) ) {
+		res.m_type = TokenType::ERROR;
+		return res;
+	}
+
+	res.m_value += m_source->getCharacter ( );
+
+	m_source->advance ( readNextLine );
+	goto q3;
+
 q4:	if ( m_source->isEndOfSequence ( ) ) {
 		res.m_type = TokenType::ERROR;
 		return res;
diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp
index 104cf25f94..e17125823a 100644
--- a/alib2cli/src/parser/Parser.cpp
+++ b/alib2cli/src/parser/Parser.cpp
@@ -98,7 +98,12 @@ std::shared_ptr < Statement > Parser::in_redirect_file ( ) {
 		templateArgs.emplace_back ( template_arg ( ) );
 	}
 
-	std::unique_ptr < Arg > file = arg ( );
+	std::unique_ptr < Arg > file;
+	if ( check ( cli::Lexer::TokenType::STRING ) )
+		file = std::make_unique < ImmediateArg > ( matchString ( ) );
+	else {
+		file = arg ( );
+	}
 	return std::make_shared < FileStatement > ( std::move ( file ), std::move ( fileType ), std::move ( type ), std::move ( templateArgs ) );
 }
 
@@ -223,7 +228,12 @@ void Parser::out_redirect_file ( std::shared_ptr < StatementList > & list ) {
 		match ( cli::Lexer::TokenType::RIGHT_BRACKET );
 	}
 
-	std::unique_ptr < Arg > file = arg ( );
+	std::unique_ptr < Arg > file;
+	if ( check ( cli::Lexer::TokenType::STRING ) )
+		file = std::make_unique < ImmediateArg > ( matchString ( ) );
+	else {
+		file = arg ( );
+	}
 	list->append ( std::make_unique < ResultFileStatement > ( std::move ( file ), std::move ( fileType ) ) );
 }
 
-- 
GitLab