* String tokenizer is documented 4.x-dev

Fri, 28 Mar 2014 17:46:47 +0200

author
cemkalyoncu
date
Fri, 28 Mar 2014 17:46:47 +0200
branch
4.x-dev
changeset 431
1c4ff08ac080
parent 430
745bd00bd5bc
child 432
c370765e11e6

* String tokenizer is documented
* Fixed linux filesystem errors

.hgignore file | annotate | diff | comparison | revisions
CMakeLists.txt file | annotate | diff | comparison | revisions
Source/Filesystem.h file | annotate | diff | comparison | revisions
Source/Filesystem/Linux.cpp file | annotate | diff | comparison | revisions
Source/String/Enum.h file | annotate | diff | comparison | revisions
Source/String/Tokenizer.h file | annotate | diff | comparison | revisions
Source/String/dir.cmake file | annotate | diff | comparison | revisions
Testing/Source/Unit/Filesystem.cpp file | annotate | diff | comparison | revisions
--- a/.hgignore	Thu Mar 27 16:38:27 2014 +0200
+++ b/.hgignore	Fri Mar 28 17:46:47 2014 +0200
@@ -5,6 +5,7 @@
 Docs/Latex
 Testing/Tests
 Testing/Runtime
+Docs/HTML
 
 syntax: glob
 
--- a/CMakeLists.txt	Thu Mar 27 16:38:27 2014 +0200
+++ b/CMakeLists.txt	Fri Mar 28 17:46:47 2014 +0200
@@ -15,6 +15,10 @@
 	SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DGORGON_FAST_ANY")
 ENDIF()
 
+IF(UNIX) 
+	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} -DLINUX")
+ENDIF()
+
 INCLUDE(Scripts/Compiler.cmake)
 
 INCLUDE(Scripts/Macros.cmake)
--- a/Source/Filesystem.h	Thu Mar 27 16:38:27 2014 +0200
+++ b/Source/Filesystem.h	Fri Mar 28 17:46:47 2014 +0200
@@ -166,7 +166,7 @@
 
 		/// Returns the filename portion of a file path. This function expects the input to 
 		/// have / as directory separator.
-		/// @param  filepath path that contains the filename
+		/// @param  path path that contains the filename
 		inline std::string GetFile(std::string path) {
 			auto pos=path.find_last_of('/');
 
--- a/Source/Filesystem/Linux.cpp	Thu Mar 27 16:38:27 2014 +0200
+++ b/Source/Filesystem/Linux.cpp	Fri Mar 28 17:46:47 2014 +0200
@@ -58,11 +58,16 @@
 	}
 	
 	bool IsExists(const std::string &path) {
-		return access(path.c_str(), 0);
+		return access(path.c_str(), 0)!= -1;
 	}
 	
 	bool IsWritable(const std::string &path) {
-		return access(path.c_str(), W_OK)==-1;
+		struct stat st;
+		if(stat(path.c_str(), &st)!=0) return false;
+		
+		return (st.st_uid == getuid() && st.st_mode & 0200) || 
+				(st.st_gid == getgid() && st.st_mode & 0020) || 
+				(st.st_mode & 0002);
 	}
 	
 	bool IsHidden(const std::string &f) {
@@ -213,7 +218,7 @@
 	}
 	
 	std::string ApplicationDirectory() {
-		std::string path=Canonize("/proc/self/exe");
+		std::string path=Canonical("/proc/self/exe");
 		
 		return GetDirectory(path);
 	}
@@ -241,7 +246,7 @@
 		if(IsDirectory("/dev/disk/by-label/")) {
 			Iterator it("/dev/disk/by-label/");
 			for(;it.IsValid(); it.Next()) {
-				mapping.emplace(Canonize("/dev/disk/by-label/"+*it), *it);
+				mapping.emplace(Canonical("/dev/disk/by-label/"+*it), *it);
 			}
 		}
 		
@@ -373,7 +378,7 @@
 	}
 	
 	Iterator::Iterator(const std::string &directory, const std::string &pattern) : 
-	data(new internal::iterator_data), basedir(Canonize(directory)) {
+	data(new internal::iterator_data), basedir(Canonical(directory)) {
 		data->dir=opendir(basedir.c_str());
 		data->pattern=pattern;
 		
--- a/Source/String/Enum.h	Thu Mar 27 16:38:27 2014 +0200
+++ b/Source/String/Enum.h	Fri Mar 28 17:46:47 2014 +0200
@@ -82,8 +82,11 @@
 
 		/// Parses the given string to determine the enumeration value. Returns end
 		/// if not the same. Comparison is case sensitive
-		static typename T_::Type Parse(const std::string &e) {
-			//TODO
+		static typename T_::Type Parse(const std::string &s) {
+			for(typename T_::Type e=(typename T_::Type)0;e<T_::end;e++)
+				if(s==T_::Names[e])
+					return e;
+			
 			return T_::end;
 		}
 
@@ -94,6 +97,8 @@
 			for(e=(typename T_::Type)0;e<T_::end;e++)
 				if(s==T_::Names[e])
 					return;
+				
+			e=T_::end;
 		}
 
 		/// Adds all elements of this Enum to a given collection.
--- a/Source/String/Tokenizer.h	Thu Mar 27 16:38:27 2014 +0200
+++ b/Source/String/Tokenizer.h	Fri Mar 28 17:46:47 2014 +0200
@@ -1,104 +1,98 @@
-//DESCRIPTION
-//	This file contains string tokenizer
-
-//REQUIRES:
-//	Utils/Iterator
-
-//LICENSE
-//	This program is free software: you can redistribute it and/or modify
-//	it under the terms of the Lesser GNU General Public License as published by
-//	the Free Software Foundation, either version 3 of the License, or
-//	(at your option) 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
-//	Lesser GNU General Public License for more details.
-//
-//	You should have received a copy of the Lesser GNU General Public License
-//	along with this program. If not, see < http://www.gnu.org/licenses/ >.
-
-//COPYRIGHT
-//	Cem Kalyoncu, DarkGaze.Org (cemkalyoncu[at]gmail[dot]com)
+/// @file Tokenizer.h contains string tokenizer.
 
 #pragma once
 
 #include <string>
-#include "Iterator.h"
+#include <iterator>
 
 
-namespace gge { namespace utils {
+namespace Gorgon { namespace String {
 
-	class StringTokenizer {
+	/// Tokenizer is a forward iterator that tokenizes a given string. This class only
+	/// supports single character delimeters, however, its possible to specify more than
+	/// one delimeter. @see Extract function to tokenize a string using multicharacter
+	/// delimeters. Its also possible to change delimeters in the middle of tokenization.
+	class Tokenizer : public std::iterator<std::forward_iterator_tag, std::string> {
 	public:
-		StringTokenizer() : position(Text.npos) {}
+		
+		/// Creates an empty tokenizer. Effectively creates an end iterator.
+		Tokenizer() : position(text.npos) {}
 
-		StringTokenizer(const std::string &Text, const std::string &Delimeters) : Text(Text), Delimeters(Delimeters) {
+		/// Creates a new tokenizer.
+		/// @param  str string to be tokenized
+		/// @param  delimeters is the delimeters to use while tokenizing
+		Tokenizer(const std::string &str, const std::string &delimeters) : 
+		      text(str), Delimeters(delimeters) {
 			position=0;
 
-			auto ind=Text.find_first_of(Delimeters);
-			if(ind==Text.npos) {
-				Token=Text;
-				position=Text.length();
+			Next();
+		}
+
+		/// Move to the next token
+		void operator ++() {
+			Next();
+		}
+
+		/// Move to the next token
+		void Next() {
+			if(position==text.length())
+				position=text.npos;
+
+			if(position==text.npos)
+				return;
+
+			auto ind=text.find_first_of(Delimeters, position);
+			if(ind==text.npos) {
+				token=text.substr(position);
+				position=text.length();
 			}
 			else {
-				Token=Text.substr(position, ind);
+				token=text.substr(position, ind-position);
 				position=ind+1;
 			}
 		}
 
-		void operator ++() {
-			Next();
+		/// Return the current token
+		std::string Current() const {
+			return token;
 		}
 
-		void Next() {
-			if(position==Text.length())
-				position=Text.npos;
-
-			if(position==Text.npos)
-				return;
-
-			auto ind=Text.find_first_of(Delimeters, position);
-			if(ind==Text.npos) {
-				Token=Text.substr(position);
-				position=Text.length();
-			}
-			else {
-				Token=Text.substr(position, ind-position);
-				position=ind+1;
-			}
+		/// Return the current token
+		std::string operator *() const {
+			return token;
 		}
 
-		std::string Current() const {
-			return Token;
+		/// Return the current token
+		operator std::string() const {
+			return token;
+		}
+
+		/// Return the current token
+		const std::string *operator ->() const {
+			return &token;
 		}
 
-		std::string operator *() const {
-			return Token;
+		/// Whether the iterator is valid (i.e. dereferencable)
+		bool IsValid() const {
+			return position!=text.npos;
 		}
 
-		operator std::string() const {
-			return Token;
-		}
-
-		const std::string *operator ->() const {
-			return &Token;
+		/// Compare two iterators, does not check if two iterators are identical. Compares
+		/// only current positions and tokens
+		bool operator ==(const Tokenizer &st) const {
+			return st.position==position && st.token == token;
 		}
 
-		bool IsValid() const {
-			return position!=Text.npos;
-		}
-
-		bool operator ==(const StringTokenizer &st) const {
-			return st.position==position;
-		}
-
+		/// Delimeters to be used in tokenization. Can be changed while tokenizing.
 		std::string Delimeters;
-		std::string Text;
-		std::string Token;
 
 	protected:
-		unsigned int position;
+		/// Current text
+		std::string text;
+		/// Current token
+		std::string token;
+		/// Position of the next token. std::string::npos denotes the iterator reached the end.
+		std::string::size_t position;
 	};
 
 }}
\ No newline at end of file
--- a/Source/String/dir.cmake	Thu Mar 27 16:38:27 2014 +0200
+++ b/Source/String/dir.cmake	Fri Mar 28 17:46:47 2014 +0200
@@ -1,4 +1,5 @@
 SET(Local
 	../String.h
 	Enum.h
+	Tokenizer.h
 )
--- a/Testing/Source/Unit/Filesystem.cpp	Thu Mar 27 16:38:27 2014 +0200
+++ b/Testing/Source/Unit/Filesystem.cpp	Fri Mar 28 17:46:47 2014 +0200
@@ -122,7 +122,7 @@
 	REQUIRE( fs::IsWritable("testfile.txt") );
 
 #ifdef LINUX
-	system("chmod 000 testfile.txt");
+	system("chmod 444 testfile.txt");
 #else
 	SetFileAttributes("testfile.txt", FILE_ATTRIBUTE_READONLY);
 #endif	
@@ -130,7 +130,7 @@
 	REQUIRE_FALSE( fs::IsWritable("testfile.txt") );
 
 #ifdef LINUX
-	system("chmod 755 testfile.txt");
+	system("chmod 644 testfile.txt");
 #else
 	SetFileAttributes("testfile.txt", FILE_ATTRIBUTE_NORMAL);
 #endif
@@ -233,17 +233,17 @@
 
 
 TEST_CASE( "Current directory, depends on cmake", "[CurrentDirectory][ChangeDirectory]") {
-	REQUIRE( fs::CurrentDirectory() == TESTDIR );
+	REQUIRE( fs::Canonical(fs::CurrentDirectory()) == fs::Canonical(TESTDIR) );
 
 	REQUIRE( fs::CurrentDirectory().find_first_of('\\') == std::string::npos );
 
 	fs::CreateDirectory("testdir");
 	REQUIRE( fs::ChangeDirectory("testdir") );
 
-	REQUIRE( fs::CurrentDirectory() == TESTDIR"/testdir" );
+	REQUIRE( fs::Canonical(fs::CurrentDirectory()) == fs::Canonical(TESTDIR"/testdir") );
 
 	REQUIRE( fs::ChangeDirectory("..") );
-	REQUIRE( fs::CurrentDirectory() == TESTDIR );
+	REQUIRE( fs::Canonical(fs::CurrentDirectory()) == fs::Canonical(TESTDIR) );
 
 	fs::Delete("testdir");
 

mercurial