From e183a128858719f968a20bf84c8780a362316422 Mon Sep 17 00:00:00 2001 From: arphaman Date: Wed, 18 Sep 2013 14:35:17 +0100 Subject: added support for INDEX intrinsic --- include/Strings/Character.h | 5 +++++ lib/Strings/Character.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++ test/Unit/CMakeLists.txt | 1 + test/Unit/index.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 test/Unit/index.cpp diff --git a/include/Strings/Character.h b/include/Strings/Character.h index 134d901..bbaf70c 100644 --- a/include/Strings/Character.h +++ b/include/Strings/Character.h @@ -26,6 +26,11 @@ LIBFLANG_ABI int32_t libflang_compare_char1(const char *LHS, size_t LHSLength, LIBFLANG_ABI int32_t libflang_lexcompare_char1(const char *LHS, size_t LHSLength, const char *RHS, size_t RHSLength); + +LIBFLANG_ABI size_t libflang_index_char1(const char *String, size_t Length, + const char *SubString, size_t SubLength, + int32_t Back); + LIBFLANG_ABI size_t libflang_lentrim_char1(const char *String, size_t Length); #endif diff --git a/lib/Strings/Character.cpp b/lib/Strings/Character.cpp index e5274bf..823f8e3 100644 --- a/lib/Strings/Character.cpp +++ b/lib/Strings/Character.cpp @@ -14,6 +14,10 @@ struct CharacterValue { CharacterValue sliceFrom(size_t Start) const { return CharacterValue(Ptr + Start, Length - Start); } + + T operator[] (size_t I) const { + return Ptr[I]; + } }; static inline @@ -81,6 +85,47 @@ static int32_t lexcompare(const CharacterValue LHS, return 0;//FIXME } +template +static size_t index(const CharacterValue String, + const CharacterValue SubString) { + if(String.Length < SubString.Length) + return 0; + if(!SubString.Length) return 1; + + auto Range = String.Length - SubString.Length; + for(size_t I = 0; I <= Range; ++I) { + bool Match = true; + for(size_t J = 0; J < SubString.Length; ++J) { + if(String[I+J] != SubString[J]) { + Match = false; + break; + } + } + if(Match) return I+1; + } + return 0; +} + +template +static size_t index_reverse(const CharacterValue String, + const CharacterValue SubString) { + if(String.Length < SubString.Length) + return 0; + if(!SubString.Length) return String.Length + 1; + + for(size_t I = String.Length - SubString.Length + 1; I != 0; --I) { + bool Match = true; + for(size_t J = 0; J < SubString.Length; ++J) { + if(String[I-1+J] != SubString[J]) { + Match = false; + break; + } + } + if(Match) return I; + } + return 0; +} + template static size_t lentrim(const CharacterValue String) { for(size_t I = String.Length; I > 0; I--) { @@ -115,6 +160,13 @@ LIBFLANG_ABI int32_t libflang_lexcompare_char1(const char *LHS, size_t LHSLength return lexcompare(generic(LHS, LHSLength), generic(RHS, RHSLength)); } +LIBFLANG_ABI size_t libflang_index_char1(const char *String, size_t Length, + const char *SubString, size_t SubLength, + int32_t Back) { + return Back == 0? index(generic(String, Length), generic(SubString, SubLength)) : + index_reverse(generic(String, Length), generic(SubString, SubLength)); +} + LIBFLANG_ABI size_t libflang_lentrim_char1(const char *String, size_t Length) { return lentrim(generic(String, Length)); } diff --git a/test/Unit/CMakeLists.txt b/test/Unit/CMakeLists.txt index 0b648ef..af1eaa6 100644 --- a/test/Unit/CMakeLists.txt +++ b/test/Unit/CMakeLists.txt @@ -1,2 +1,3 @@ add_libflang_test(ipow ipow.cpp) add_libflang_test(selected_int_kind selected_int_kind.cpp) +add_libflang_test(index index.cpp) diff --git a/test/Unit/index.cpp b/test/Unit/index.cpp new file mode 100644 index 0000000..ed5107b --- /dev/null +++ b/test/Unit/index.cpp @@ -0,0 +1,49 @@ +//===-- index.cpp - Test libflang_index_char* -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include "Strings/Character.h" + +static bool testIndex(const char *str, const char *substr, size_t expected, bool back = false) { + auto x = libflang_index_char1(str, strlen(str), substr, strlen(substr), + back? 1:0); + if(x != expected) + std::cout << "Error in libflang_index - expected " << expected + << ", got " << x << std::endl; + return x != expected; +} + +int main() { + if(testIndex("FORTRAN","R",3)) + return 1; + if(testIndex("FORTRAN","R",5,true)) + return 1; + if(testIndex("hello","ell",2)) + return 1; + if(testIndex("hello","ell",2,true)) + return 1; + if(testIndex("hello","world",0)) + return 1; + if(testIndex("hello","world",0,true)) + return 1; + if(testIndex("A","a",0)) + return 1; + if(testIndex("hell","hello",0)) + return 1; + if(testIndex("hell","hello",0,true)) + return 1; + if(testIndex("hello","",1)) + return 1; + if(testIndex("hello","",6,true)) + return 1; + return 0; +} + -- cgit v1.2.1