From 7b4b5764899c1d0b6b9eb02becfa4ccc4271e73e Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 21 Jan 2016 18:49:42 +0000 Subject: [PATCH] added: MainSpaceParser - starting writing a parser for main(argc, argv) arguments (a Space object is returned) git-svn-id: svn://ttmath.org/publicrep/pikotools/trunk@1019 e52654a7-88a9-db11-a3e9-0013d4bc506e --- Makefile | 7 +- mainspaceparser/Makefile | 27 ++++ mainspaceparser/Makefile.dep | 3 + mainspaceparser/Makefile.o.dep | 1 + mainspaceparser/mainspaceparser.cpp | 242 ++++++++++++++++++++++++++++ mainspaceparser/mainspaceparser.h | 99 ++++++++++++ 6 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 mainspaceparser/Makefile create mode 100644 mainspaceparser/Makefile.dep create mode 100644 mainspaceparser/Makefile.o.dep create mode 100644 mainspaceparser/mainspaceparser.cpp create mode 100644 mainspaceparser/mainspaceparser.h diff --git a/Makefile b/Makefile index 3167163..ba2bb74 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ export LDFLAGS export AR -all: space mainparser utf8 date +all: space mainparser mainspaceparser utf8 date @@ -33,6 +33,9 @@ space: FORCE mainparser: FORCE @cd mainparser ; $(MAKE) -e +mainspaceparser: FORCE + @cd mainspaceparser ; $(MAKE) -e + utf8: FORCE @cd utf8 ; $(MAKE) -e @@ -49,11 +52,13 @@ FORCE: clean: @cd space ; $(MAKE) -e clean @cd mainparser ; $(MAKE) -e clean + @cd mainspaceparser ; $(MAKE) -e clean @cd utf8 ; $(MAKE) -e clean @cd date ; $(MAKE) -e clean depend: @cd space ; $(MAKE) -e depend @cd mainparser ; $(MAKE) -e depend + @cd mainspaceparser ; $(MAKE) -e depend @cd utf8 ; $(MAKE) -e depend @cd date ; $(MAKE) -e depend diff --git a/mainspaceparser/Makefile b/mainspaceparser/Makefile new file mode 100644 index 0000000..5e52fc0 --- /dev/null +++ b/mainspaceparser/Makefile @@ -0,0 +1,27 @@ +include Makefile.o.dep + +libname=mainspaceparser.a + +all: $(libname) + +$(libname): $(o) + $(AR) rcs $(libname) $(o) + + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) -I.. $< + + + +depend: + makedepend -Y. -I.. -f- *.cpp > Makefile.dep + echo -n "o = " > Makefile.o.dep + ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep + + +clean: + rm -f *.o + rm -f $(libname) + + +include Makefile.dep diff --git a/mainspaceparser/Makefile.dep b/mainspaceparser/Makefile.dep new file mode 100644 index 0000000..4579292 --- /dev/null +++ b/mainspaceparser/Makefile.dep @@ -0,0 +1,3 @@ +# DO NOT DELETE + +mainspaceparser.o: mainspaceparser.h ../space/space.h ../textstream/types.h diff --git a/mainspaceparser/Makefile.o.dep b/mainspaceparser/Makefile.o.dep new file mode 100644 index 0000000..cda6e8b --- /dev/null +++ b/mainspaceparser/Makefile.o.dep @@ -0,0 +1 @@ +o = mainspaceparser.o diff --git a/mainspaceparser/mainspaceparser.cpp b/mainspaceparser/mainspaceparser.cpp new file mode 100644 index 0000000..78ea1ae --- /dev/null +++ b/mainspaceparser/mainspaceparser.cpp @@ -0,0 +1,242 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2016, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "mainspaceparser.h" +#include "utf8/utf8.h" +#include + +// REMOVE ME +#include + + +namespace PT +{ + + +MainSpaceParser::MainSpaceParser() +{ + space = 0; + options_space = 0; + use_utf8 = true; + last_status = status_ok; +} + + + +MainSpaceParser::~MainSpaceParser() +{ + + +} + + +void MainSpaceParser::UTF8(bool utf8) +{ + use_utf8 = utf8; +} + + +void MainSpaceParser::SetSpace(Space & space_ref) +{ + space = &space_ref; + options_space = 0; +} + + +std::wstring & MainSpaceParser::GetErrorToken() +{ + return last_error_token; +} + + +MainSpaceParser::Status MainSpaceParser::Parse(int argc, const char ** argv) +{ + if( !space ) + { + return status_space_not_assigned; + } + + options_space = space->FindSpace(L"options"); + last_status = status_ok; + last_error_token.clear(); + + for(size_t i=1 ; i < (size_t)argc && last_status == status_ok ; ) + { + Parse((size_t)argc, argv, i); + } + + return last_status; +} + + +void MainSpaceParser::Parse(size_t argc, const char ** argv, size_t & argv_index) +{ + const char * pchar = argv[argv_index]; + + if( *pchar == '-' ) + { + if( *(pchar+1) == '-' ) + { + ParseMultiArgument(argc, argv, argv_index); + } + else + { + ParseSingleArgument(argc, argv, argv_index); + } + } + else + { + last_status = status_syntax_error; + ConvertStr(pchar, last_error_token); + } +} + + +void MainSpaceParser::ConvertStr(const char * src, std::wstring & dst) +{ + if( use_utf8 ) + { + PT::UTF8ToWide(src,dst); + } + else + { + dst.clear(); + + for( ; *src ; ++src ) + dst += (wchar_t)(unsigned char)*src; + } +} + + +void MainSpaceParser::ParseSingleArgument(size_t argc, const char ** argv, size_t & argv_index) +{ + ConvertStr(argv[argv_index] + 1, wide_arg); + const wchar_t * wide_pchar = wide_arg.c_str(); + + temp_list_val.clear(); + bool was_option = false; + argv_index += 1; + + for( ; *wide_pchar && !was_option ; ++wide_pchar ) + { + temp_arg = *wide_pchar; + size_t opt_size = RequireOption(temp_arg); + + if( opt_size > 0 ) + { + was_option = true; + + if( *(wide_pchar+1) ) + { + temp_val = wide_pchar + 1; + temp_list_val.push_back(temp_val); + opt_size -= 1; + } + + for( ; opt_size > 0 && argv_index < argc ; --opt_size, ++argv_index) + { + ConvertStr(argv[argv_index], temp_val); + temp_list_val.push_back(temp_val); + } + } + + temp_val.clear(); + + if( temp_list_val.empty() ) + space->Add(temp_arg, temp_val); + else + if( temp_list_val.size() == 1 ) + space->Add(temp_arg, temp_list_val[0] ); + else + space->table[temp_arg] = temp_list_val; // !! IMPROVE ME + } +} + + +void MainSpaceParser::ParseMultiArgument(size_t argc, const char ** argv, size_t & argv_index) +{ + ConvertStr(argv[argv_index] + 2, wide_arg); + temp_val.clear(); + + /* + * IMPLEMENT ME + * add checking for files here + * + */ + + space->Add(wide_arg, temp_val); + + argv_index += 1; +} + + +size_t MainSpaceParser::RequireOption(const std::wstring & arg) +{ + size_t res = 0; + + if( options_space ) + { + std::wstring * val = options_space->GetValue(arg); + + if( val ) + { + /* + * IMPLEMENT ME + * add a converter to convert/inttostr.h + * + */ + + long res_long = wcstol(val->c_str(), 0, 10); + + if( res_long < 0 ) + res_long = 0; + + res = (size_t)res_long; + + //std::wcout << L"argument " << arg << L" needs " << res << L" options" << std::endl; + } + } + + return res; +} + + + +} // namespace + + diff --git a/mainspaceparser/mainspaceparser.h b/mainspaceparser/mainspaceparser.h new file mode 100644 index 0000000..db4547b --- /dev/null +++ b/mainspaceparser/mainspaceparser.h @@ -0,0 +1,99 @@ +/* + * This file is a part of PikoTools + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2016, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_picotools_mainspaceparser_mainparser +#define headerfile_picotools_mainspaceparser_mainparser + +#include "space/space.h" +#include +#include + + +namespace PT +{ + + +/* + a very little parser for main(int argc, char ** argv) parameters + look in sample/sample.cpp how to use the parser +*/ +class MainSpaceParser +{ +public: + + MainSpaceParser(); + ~MainSpaceParser(); + + enum Status + { + status_ok = 0, + status_space_not_assigned = 1, + status_syntax_error = 2, + }; + + void SetSpace(Space & space); + Status Parse(int argc, const char ** argv); + + void UTF8(bool utf8); + + std::wstring & GetErrorToken(); + +private: + + Space * space; + Space * options_space; + std::wstring wide_arg, temp_arg, temp_val; + std::vector temp_list_val; + bool use_utf8; + Status last_status; + std::wstring last_error_token; + + + void ConvertStr(const char * src, std::wstring & dst); + void Parse(size_t argc, const char ** argv, size_t & argv_index); + void ParseSingleArgument(size_t argc, const char ** argv, size_t & argv_index); + void ParseMultiArgument(size_t argc, const char ** argv, size_t & argv_index); + size_t RequireOption(const std::wstring & arg); + + +}; + + +} // namespace + + +#endif