Commit 18bd7a9df23f7e8388fb8747efeca1fe47bc88ce

Thomas de Grivel 2024-08-07T11:22:13

add Str.starts_with? and Str.ends_with? to fix bug in HTTPd

diff --git a/.ikc3_history b/.ikc3_history
index 28a7516..eca2693 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,8 +1,3 @@
-op.sym
-op = %{id: 1, sym: :-}
-op.id
-type(op.id)
-type(op.sym)
 (Str) op.sym
 [fd: (S32) -1]
 load("https://git.kmx.io/kc3-lang/kc3/
@@ -97,4 +92,8 @@ File.list(lib)
 File.list("lib")
 File.list("lib/kc3")
 File.list("lib/kc3/0.1")
-
+Str.starts_with?("abc", "a")
+Str.starts_with?("abc", "b")
+Str.ends_with?("abc", "b")
+Str.ends_with?("abc", "c")
+Str.ends_with?("abc/", "/")
diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 9e58885..f07b2c6 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -80,7 +80,7 @@ defmodule HTTPd do
   def directory_page = fn (request) {
     files = File.list(root_dir + request.url)
     file_li = fn (file) {
-      slash = if request.url == "/" do "" else "/" end
+      slash = if Str.ends_with?(request.url, "/") do "" else "/" end
       "<li><a href=\"#{request.url}#{slash}#{file}\">#{request.url}#{slash}#{file}</a></li>"
     }
     body = "<html>
diff --git a/lib/kc3/0.1/str.facts b/lib/kc3/0.1/str.facts
index b25372e..197b062 100644
--- a/lib/kc3/0.1/str.facts
+++ b/lib/kc3/0.1/str.facts
@@ -3,3 +3,7 @@
 replace {Str, :is_a, :module}
 replace {Str, :symbol, Str.cast}
 replace {Str.cast, :symbol_value, cfn Str "str_init_cast" (Result, Sym, Tag)}
+add {Str, :symbol, Str.starts_with?}
+replace {Str.starts_with?, :symbol_value, cfn Bool "str_starts_with" (Str, Str)}
+add {Str, :symbol, Str.ends_with?}
+replace {Str.ends_with?, :symbol_value, cfn Bool "str_ends_with" (Str, Str)}
diff --git a/libkc3/str.c b/libkc3/str.c
index aa4a64a..6c6f1a1 100644
--- a/libkc3/str.c
+++ b/libkc3/str.c
@@ -160,6 +160,19 @@ void str_delete (s_str *str)
   free(str);
 }
 
+bool str_ends_with (const s_str *str, const s_str *end)
+{
+  uw i;
+  assert(str);
+  assert(end);
+  if (! end->size)
+    return true;
+  if (str->size < end->size)
+    return false;
+  i = str->size - end->size;
+  return ! memcmp(str->ptr.pchar + i, end->ptr.p, end->size);
+}
+
 bool * str_has_reserved_characters (const s_str *src, bool *dest)
 {
   character c;
@@ -829,6 +842,17 @@ uw * str_rindex_character (const s_str *str, character c, uw *dest)
   return NULL;
 }
 
+bool str_starts_with (const s_str *str, const s_str *start)
+{
+  assert(str);
+  assert(start);
+  if (! start->size)
+    return true;
+  if (str->size < start->size)
+    return false;
+  return ! memcmp(str->ptr.p, start->ptr.p, start->size);
+}
+
 uw * str_sw_pos_to_uw (sw pos, uw max_pos, uw *dest)
 {
   assert(dest);
diff --git a/libkc3/str.h b/libkc3/str.h
index c203cda..f1d5054 100644
--- a/libkc3/str.h
+++ b/libkc3/str.h
@@ -92,6 +92,7 @@ sw            str_character (const s_str *str, uw position,
 character     str_character_escape (character c);
 bool          str_character_is_reserved (character c);
 sw            str_character_position (const s_str *str, character c);
+bool          str_ends_with (const s_str *str, const s_str *end);
 bool *        str_has_reserved_characters (const s_str *src,
                                            bool *dest);
 s_str *       str_inspect (const s_str *str, s_str *dest);
@@ -114,6 +115,7 @@ sw            str_peek_u64 (const s_str *str, u64 *dest);
 sw            str_position_1 (const s_str *str, const char *token);
 uw *          str_rindex_character (const s_str *str, character c,
                                     uw *dest);
+bool          str_starts_with (const s_str *str, const s_str *start);
 uw *          str_sw_pos_to_uw (sw pos, uw max_pos, uw *dest);
 s_str *       str_to_hex (const s_str *str, s_str *dest);
 s_ident *     str_to_ident (const s_str *str, s_ident *dest);