summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-18 14:35:17 +0100
committerarphaman <arphaman@gmail.com>2013-09-18 14:35:17 +0100
commite183a128858719f968a20bf84c8780a362316422 (patch)
tree3bc62a789a277bd10e7c8ade44ee9ad504733dd0
parent8e83adfdc9dacf83d9bdee65bd23b9416ceededf (diff)
downloadlibflangrt-e183a128858719f968a20bf84c8780a362316422.tar.gz
added support for INDEX intrinsic
-rw-r--r--include/Strings/Character.h5
-rw-r--r--lib/Strings/Character.cpp52
-rw-r--r--test/Unit/CMakeLists.txt1
-rw-r--r--test/Unit/index.cpp49
4 files changed, 107 insertions, 0 deletions
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<T> sliceFrom(size_t Start) const {
return CharacterValue<T>(Ptr + Start, Length - Start);
}
+
+ T operator[] (size_t I) const {
+ return Ptr[I];
+ }
};
static inline
@@ -82,6 +86,47 @@ static int32_t lexcompare(const CharacterValue<T> LHS,
}
template<typename T>
+static size_t index(const CharacterValue<T> String,
+ const CharacterValue<T> 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<typename T>
+static size_t index_reverse(const CharacterValue<T> String,
+ const CharacterValue<T> 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<typename T>
static size_t lentrim(const CharacterValue<T> String) {
for(size_t I = String.Length; I > 0; I--) {
if(isWhitespace(String.Ptr[I-1])) return 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 <assert.h>
+#include <string.h>
+#include <iostream>
+#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;
+}
+