You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2013/09/01 22:17:01 UTC
[lucy-commits] [13/24] Rename CharBuf to String (cnick Str)
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Err.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Err.c b/clownfish/runtime/core/Clownfish/Err.c
index 68bc66f..46f0027 100644
--- a/clownfish/runtime/core/Clownfish/Err.c
+++ b/clownfish/runtime/core/Clownfish/Err.c
@@ -27,18 +27,18 @@
#include <ctype.h>
#include "Clownfish/Err.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/VTable.h"
#include "Clownfish/Util/Memory.h"
Err*
-Err_new(CharBuf *mess) {
+Err_new(String *mess) {
Err *self = (Err*)VTable_Make_Obj(ERR);
return Err_init(self, mess);
}
Err*
-Err_init(Err *self, CharBuf *mess) {
+Err_init(Err *self, String *mess) {
self->mess = mess;
return self;
}
@@ -49,14 +49,14 @@ Err_Destroy_IMP(Err *self) {
SUPER_DESTROY(self, ERR);
}
-CharBuf*
+String*
Err_To_String_IMP(Err *self) {
- return (CharBuf*)INCREF(self->mess);
+ return (String*)INCREF(self->mess);
}
void
-Err_Cat_Mess_IMP(Err *self, const CharBuf *mess) {
- CB_Cat(self->mess, mess);
+Err_Cat_Mess_IMP(Err *self, const String *mess) {
+ Str_Cat(self->mess, mess);
}
// Fallbacks in case variadic macros aren't available.
@@ -65,10 +65,10 @@ void
THROW(VTable *vtable, char *pattern, ...) {
va_list args;
Err *err = (Err*)VTable_Make_Obj(vtable);
- err = Err_init(err, CB_new(0));
+ err = Err_init(err, Str_new(0));
va_start(args, pattern);
- CB_VCatF(err->mess, pattern, args);
+ Str_VCatF(err->mess, pattern, args);
va_end(args);
Err_do_throw(err);
@@ -76,21 +76,21 @@ THROW(VTable *vtable, char *pattern, ...) {
void
CFISH_WARN(char *pattern, ...) {
va_list args;
- CharBuf *const message = CB_new(strlen(pattern) + 10);
+ String *const message = Str_new(strlen(pattern) + 10);
va_start(args, pattern);
- CB_VCatF(message, pattern, args);
+ Str_VCatF(message, pattern, args);
va_end(args);
Err_warn_mess(message);
}
-CharBuf*
+String*
CFISH_MAKE_MESS(char *pattern, ...) {
va_list args;
- CharBuf *const message = CB_new(strlen(pattern) + 10);
+ String *const message = Str_new(strlen(pattern) + 10);
va_start(args, pattern);
- CB_VCatF(message, pattern, args);
+ Str_VCatF(message, pattern, args);
va_end(args);
return message;
@@ -99,28 +99,28 @@ CFISH_MAKE_MESS(char *pattern, ...) {
static void
-S_vcat_mess(CharBuf *message, const char *file, int line, const char *func,
+S_vcat_mess(String *message, const char *file, int line, const char *func,
const char *pattern, va_list args) {
size_t guess_len = strlen(file)
+ func ? strlen(func) : 0
+ strlen(pattern)
+ 30;
- CB_Grow(message, guess_len);
- CB_VCatF(message, pattern, args);
+ Str_Grow(message, guess_len);
+ Str_VCatF(message, pattern, args);
if (func != NULL) {
- CB_catf(message, "\n\t%s at %s line %i32\n", func, file, (int32_t)line);
+ Str_catf(message, "\n\t%s at %s line %i32\n", func, file, (int32_t)line);
}
else {
- CB_catf(message, "\n\t%s line %i32\n", file, (int32_t)line);
+ Str_catf(message, "\n\t%s line %i32\n", file, (int32_t)line);
}
}
-CharBuf*
+String*
Err_make_mess(const char *file, int line, const char *func,
const char *pattern, ...) {
va_list args;
size_t guess_len = strlen(pattern) + strlen(file) + 20;
- CharBuf *message = CB_new(guess_len);
+ String *message = Str_new(guess_len);
va_start(args, pattern);
S_vcat_mess(message, file, line, func, pattern, args);
va_end(args);
@@ -131,30 +131,30 @@ void
Err_warn_at(const char *file, int line, const char *func,
const char *pattern, ...) {
va_list args;
- CharBuf *message = CB_new(0);
+ String *message = Str_new(0);
va_start(args, pattern);
S_vcat_mess(message, file, line, func, pattern, args);
va_end(args);
Err_warn_mess(message);
}
-CharBuf*
+String*
Err_Get_Mess_IMP(Err *self) {
return self->mess;
}
void
Err_Add_Frame_IMP(Err *self, const char *file, int line, const char *func) {
- if (!CB_Ends_With_Str(self->mess, "\n", 1)) {
- CB_Cat_Char(self->mess, '\n');
+ if (!Str_Ends_With_Str(self->mess, "\n", 1)) {
+ Str_Cat_Char(self->mess, '\n');
}
if (func != NULL) {
- CB_catf(self->mess, "\t%s at %s line %i32\n", func, file,
+ Str_catf(self->mess, "\t%s at %s line %i32\n", func, file,
(int32_t)line);
}
else {
- CB_catf(self->mess, "\tat %s line %i32\n", file, (int32_t)line);
+ Str_catf(self->mess, "\tat %s line %i32\n", file, (int32_t)line);
}
}
@@ -169,7 +169,7 @@ Err_throw_at(VTable *vtable, const char *file, int line,
const char *func, const char *pattern, ...) {
va_list args;
Err *err = (Err*)VTable_Make_Obj(vtable);
- err = Err_init(err, CB_new(0));
+ err = Err_init(err, Str_new(0));
va_start(args, pattern);
S_vcat_mess(err->mess, file, line, func, pattern, args);
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Err.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Err.cfh b/clownfish/runtime/core/Clownfish/Err.cfh
index aa25b3e..3f47e4f 100644
--- a/clownfish/runtime/core/Clownfish/Err.cfh
+++ b/clownfish/runtime/core/Clownfish/Err.cfh
@@ -38,21 +38,21 @@ __END_C__
*/
public class Clownfish::Err inherits Clownfish::Obj {
- CharBuf *mess;
+ String *mess;
inert void
init_class();
inert incremented Err*
- new(decremented CharBuf *mess);
+ new(decremented String *mess);
inert Err*
- init(Err *self, decremented CharBuf *mess);
+ init(Err *self, decremented String *mess);
public void
Destroy(Err *self);
- public incremented CharBuf*
+ public incremented String*
To_String(Err *self);
void*
@@ -61,9 +61,9 @@ public class Clownfish::Err inherits Clownfish::Obj {
/** Concatenate the supplied argument onto the internal "mess".
*/
public void
- Cat_Mess(Err *self, const CharBuf *mess);
+ Cat_Mess(Err *self, const String *mess);
- public CharBuf*
+ public String*
Get_Mess(Err *self);
/** Add information about the current stack frame onto <code>mess</code>.
@@ -117,7 +117,7 @@ public class Clownfish::Err inherits Clownfish::Obj {
* @param message Error message, to be output verbatim.
*/
inert void
- throw_mess(VTable *vtable, decremented CharBuf *message);
+ throw_mess(VTable *vtable, decremented String *message);
/** Invoke host exception handling.
*/
@@ -130,12 +130,12 @@ public class Clownfish::Err inherits Clownfish::Obj {
* @param message Error message, to be output verbatim.
*/
inert void
- warn_mess(decremented CharBuf *message);
+ warn_mess(decremented String *message);
/** Create a formatted error message. Ususally invoked via the MAKE_MESS
* macro.
*/
- inert CharBuf*
+ inert String*
make_mess(const char *file, int line, const char *func,
const char *pattern, ...);
@@ -211,7 +211,7 @@ __C__
CFISH_THROW(cfish_VTable *vtable, char* format, ...);
void
CFISH_WARN(char* format, ...);
- cfish_CharBuf*
+ cfish_String*
CFISH_MAKE_MESS(char* format, ...);
#endif
@@ -228,7 +228,7 @@ static CFISH_INLINE void
cfish_Err_abstract_class_check(cfish_Obj *obj, cfish_VTable *vtable) {
cfish_VTable *const my_vtable = (cfish_VTable*)((cfish_Dummy*)obj)->vtable;
if (my_vtable == vtable) {
- cfish_CharBuf *mess = CFISH_MAKE_MESS("%o is an abstract class",
+ cfish_String *mess = CFISH_MAKE_MESS("%o is an abstract class",
CFISH_Obj_Get_Class_Name(obj));
CFISH_Obj_Dec_RefCount(obj);
cfish_Err_throw_mess(CFISH_ERR, mess);
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Hash.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Hash.c b/clownfish/runtime/core/Clownfish/Hash.c
index 1fbfe42..7e3fb2e 100644
--- a/clownfish/runtime/core/Clownfish/Hash.c
+++ b/clownfish/runtime/core/Clownfish/Hash.c
@@ -27,7 +27,7 @@
#include "Clownfish/VTable.h"
#include "Clownfish/Hash.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Err.h"
#include "Clownfish/VArray.h"
#include "Clownfish/Util/Memory.h"
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Method.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Method.c b/clownfish/runtime/core/Clownfish/Method.c
index 0ad01f8..9f4bddd 100644
--- a/clownfish/runtime/core/Clownfish/Method.c
+++ b/clownfish/runtime/core/Clownfish/Method.c
@@ -21,20 +21,20 @@
#include "charmony.h"
#include "Clownfish/Method.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Err.h"
#include "Clownfish/VTable.h"
Method*
-Method_new(const CharBuf *name, cfish_method_t callback_func, size_t offset) {
+Method_new(const String *name, cfish_method_t callback_func, size_t offset) {
Method *self = (Method*)VTable_Make_Obj(METHOD);
return Method_init(self, name, callback_func, offset);
}
Method*
-Method_init(Method *self, const CharBuf *name, cfish_method_t callback_func,
+Method_init(Method *self, const String *name, cfish_method_t callback_func,
size_t offset) {
- self->name = CB_Clone(name);
+ self->name = Str_Clone(name);
self->host_alias = NULL;
self->callback_func = callback_func;
self->offset = offset;
@@ -65,12 +65,12 @@ Method_Get_RefCount_IMP(Method *self) {
return 1;
}
-CharBuf*
+String*
Method_Get_Name_IMP(Method *self) {
return self->name;
}
-CharBuf*
+String*
Method_Get_Host_Alias_IMP(Method *self) {
return self->host_alias;
}
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Method.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Method.cfh b/clownfish/runtime/core/Clownfish/Method.cfh
index 9bd32e2..521839c 100644
--- a/clownfish/runtime/core/Clownfish/Method.cfh
+++ b/clownfish/runtime/core/Clownfish/Method.cfh
@@ -21,23 +21,23 @@ parcel Clownfish;
class Clownfish::Method inherits Clownfish::Obj {
- CharBuf *name;
- CharBuf *host_alias;
+ String *name;
+ String *host_alias;
cfish_method_t callback_func;
size_t offset;
bool is_excluded;
inert Method*
- new(const CharBuf *name, cfish_method_t callback_func, size_t offset);
+ new(const String *name, cfish_method_t callback_func, size_t offset);
inert Method*
- init(Method *self, const CharBuf *name, cfish_method_t callback_func,
+ init(Method *self, const String *name, cfish_method_t callback_func,
size_t offset);
- CharBuf*
+ String*
Get_Name(Method *self);
- nullable CharBuf*
+ nullable String*
Get_Host_Alias(Method *self);
bool
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Num.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Num.c b/clownfish/runtime/core/Clownfish/Num.c
index 71ca017..728c618 100644
--- a/clownfish/runtime/core/Clownfish/Num.c
+++ b/clownfish/runtime/core/Clownfish/Num.c
@@ -29,7 +29,7 @@
#include "charmony.h"
#include "Clownfish/Num.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Err.h"
#include "Clownfish/VTable.h"
@@ -66,9 +66,9 @@ FloatNum_Compare_To_IMP(FloatNum *self, Obj *other) {
return 0;
}
-CharBuf*
+String*
FloatNum_To_String_IMP(FloatNum *self) {
- return CB_newf("%f64", FloatNum_To_F64(self));
+ return Str_newf("%f64", FloatNum_To_F64(self));
}
/***************************************************************************/
@@ -91,9 +91,9 @@ IntNum_Compare_To_IMP(IntNum *self, Obj *other) {
return 0;
}
-CharBuf*
+String*
IntNum_To_String_IMP(IntNum *self) {
- return CB_newf("%i64", IntNum_To_I64(self));
+ return Str_newf("%i64", IntNum_To_I64(self));
}
/***************************************************************************/
@@ -325,10 +325,10 @@ void
Bool_init_class() {
Bool_true_singleton = (BoolNum*)VTable_Make_Obj(BOOLNUM);
Bool_true_singleton->value = true;
- Bool_true_singleton->string = CB_newf("true");
+ Bool_true_singleton->string = Str_newf("true");
Bool_false_singleton = (BoolNum*)VTable_Make_Obj(BOOLNUM);
Bool_false_singleton->value = false;
- Bool_false_singleton->string = CB_newf("false");
+ Bool_false_singleton->string = Str_newf("false");
}
BoolNum*
@@ -374,9 +374,9 @@ Bool_Hash_Sum_IMP(BoolNum *self) {
return (int32_t)hash_sum;
}
-CharBuf*
+String*
Bool_To_String_IMP(BoolNum *self) {
- return (CharBuf*)CB_Inc_RefCount(self->string);
+ return (String*)Str_Inc_RefCount(self->string);
}
bool
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Num.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Num.cfh b/clownfish/runtime/core/Clownfish/Num.cfh
index 3f6a8d6..56983ce 100644
--- a/clownfish/runtime/core/Clownfish/Num.cfh
+++ b/clownfish/runtime/core/Clownfish/Num.cfh
@@ -37,7 +37,7 @@ abstract class Clownfish::FloatNum inherits Clownfish::Num {
public int32_t
Compare_To(FloatNum *self, Obj *other);
- public incremented CharBuf*
+ public incremented String*
To_String(FloatNum *self);
}
@@ -52,7 +52,7 @@ abstract class Clownfish::IntNum inherits Clownfish::Num {
public int32_t
Compare_To(IntNum *self, Obj *other);
- public incremented CharBuf*
+ public incremented String*
To_String(IntNum *self);
}
@@ -219,7 +219,7 @@ class Clownfish::Integer64 cnick Int64
*/
class Clownfish::BoolNum cnick Bool inherits Clownfish::IntNum {
bool value;
- CharBuf *string;
+ String *string;
inert BoolNum *true_singleton;
inert BoolNum *false_singleton;
@@ -258,7 +258,7 @@ class Clownfish::BoolNum cnick Bool inherits Clownfish::IntNum {
public bool
Equals(BoolNum *self, Obj *other);
- public incremented CharBuf*
+ public incremented String*
To_String(BoolNum *self);
incremented BoolNum*
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Obj.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Obj.c b/clownfish/runtime/core/Clownfish/Obj.c
index 86d1019..0bc8b44 100644
--- a/clownfish/runtime/core/Clownfish/Obj.c
+++ b/clownfish/runtime/core/Clownfish/Obj.c
@@ -26,7 +26,7 @@
#include <string.h>
#include "Clownfish/Obj.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Err.h"
#include "Clownfish/Hash.h"
#include "Clownfish/VTable.h"
@@ -68,16 +68,16 @@ Obj_Equals_IMP(Obj *self, Obj *other) {
return (self == other);
}
-CharBuf*
+String*
Obj_To_String_IMP(Obj *self) {
#if (SIZEOF_PTR == 4)
- return CB_newf("%o@0x%x32", Obj_Get_Class_Name(self), self);
+ return Str_newf("%o@0x%x32", Obj_Get_Class_Name(self), self);
#elif (SIZEOF_PTR == 8)
int64_t iaddress = PTR_TO_I64(self);
uint64_t address = (uint64_t)iaddress;
uint32_t address_hi = address >> 32;
uint32_t address_lo = address & 0xFFFFFFFF;
- return CB_newf("%o@0x%x32%x32", Obj_Get_Class_Name(self), address_hi,
+ return Str_newf("%o@0x%x32%x32", Obj_Get_Class_Name(self), address_hi,
address_lo);
#else
#error "Unexpected pointer size."
@@ -94,7 +94,7 @@ Obj_Get_VTable_IMP(Obj *self) {
return self->vtable;
}
-CharBuf*
+String*
Obj_Get_Class_Name_IMP(Obj *self) {
return VTable_Get_Name(self->vtable);
}
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Obj.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Obj.cfh b/clownfish/runtime/core/Clownfish/Obj.cfh
index a755d5d..fafccfc 100644
--- a/clownfish/runtime/core/Clownfish/Obj.cfh
+++ b/clownfish/runtime/core/Clownfish/Obj.cfh
@@ -118,7 +118,7 @@ public class Clownfish::Obj {
/** Return the name of the class that the object belongs to.
*/
- public CharBuf*
+ public String*
Get_Class_Name(Obj *self);
/** Indicate whether the object is a descendent of <code>ancestor</code>.
@@ -128,7 +128,7 @@ public class Clownfish::Obj {
/** Generic stringification: "ClassName@hex_mem_address".
*/
- public incremented CharBuf*
+ public incremented String*
To_String(Obj *self);
/** Convert the object to a 64-bit integer.
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/String.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/String.c b/clownfish/runtime/core/Clownfish/String.c
new file mode 100644
index 0000000..3cf3668
--- /dev/null
+++ b/clownfish/runtime/core/Clownfish/String.c
@@ -0,0 +1,912 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define C_CFISH_STRING
+#define C_CFISH_VIEWCHARBUF
+#define C_CFISH_STACKSTRING
+#define CFISH_USE_SHORT_NAMES
+#define CHY_USE_SHORT_NAMES
+
+#include "charmony.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "Clownfish/VTable.h"
+#include "Clownfish/String.h"
+
+#include "Clownfish/Err.h"
+#include "Clownfish/Util/Memory.h"
+#include "Clownfish/Util/StringHelper.h"
+
+// Helper function for throwing invalid UTF-8 error. Since THROW uses
+// a String internally, calling THROW with invalid UTF-8 would create an
+// infinite loop -- so we fwrite some of the bogus text to stderr and
+// invoke THROW with a generic message.
+#define DIE_INVALID_UTF8(text, size) \
+ S_die_invalid_utf8(text, size, __FILE__, __LINE__, CFISH_ERR_FUNC_MACRO)
+static void
+S_die_invalid_utf8(const char *text, size_t size, const char *file, int line,
+ const char *func);
+
+// Helper function for throwing invalid pattern error.
+static void
+S_die_invalid_pattern(const char *pattern);
+
+String*
+Str_new(size_t size) {
+ String *self = (String*)VTable_Make_Obj(STRING);
+ return Str_init(self, size);
+}
+
+String*
+Str_init(String *self, size_t size) {
+ // Derive.
+ self->ptr = (char*)MALLOCATE(size + 1);
+
+ // Init.
+ *self->ptr = '\0'; // Empty string.
+
+ // Assign.
+ self->size = 0;
+ self->cap = size + 1;
+
+ return self;
+}
+
+String*
+Str_new_from_utf8(const char *ptr, size_t size) {
+ if (!StrHelp_utf8_valid(ptr, size)) {
+ DIE_INVALID_UTF8(ptr, size);
+ }
+ return Str_new_from_trusted_utf8(ptr, size);
+}
+
+String*
+Str_new_from_trusted_utf8(const char *ptr, size_t size) {
+ String *self = (String*)VTable_Make_Obj(STRING);
+
+ // Derive.
+ self->ptr = (char*)MALLOCATE(size + 1);
+
+ // Copy.
+ memcpy(self->ptr, ptr, size);
+
+ // Assign.
+ self->size = size;
+ self->cap = size + 1;
+ self->ptr[size] = '\0'; // Null terminate.
+
+ return self;
+}
+
+String*
+Str_new_steal_from_trusted_str(char *ptr, size_t size, size_t cap) {
+ String *self = (String*)VTable_Make_Obj(STRING);
+ return Str_init_steal_trusted_str(self, ptr, size, cap);
+}
+
+String*
+Str_init_steal_trusted_str(String *self, char *ptr, size_t size, size_t cap) {
+ self->ptr = ptr;
+ self->size = size;
+ self->cap = cap;
+ return self;
+}
+
+String*
+Str_new_steal_str(char *ptr, size_t size, size_t cap) {
+ if (!StrHelp_utf8_valid(ptr, size)) {
+ DIE_INVALID_UTF8(ptr, size);
+ }
+ return Str_new_steal_from_trusted_str(ptr, size, cap);
+}
+
+String*
+Str_newf(const char *pattern, ...) {
+ String *self = Str_new(strlen(pattern));
+ va_list args;
+ va_start(args, pattern);
+ Str_VCatF(self, pattern, args);
+ va_end(args);
+ return self;
+}
+
+void
+Str_Destroy_IMP(String *self) {
+ FREEMEM(self->ptr);
+ SUPER_DESTROY(self, STRING);
+}
+
+int32_t
+Str_Hash_Sum_IMP(String *self) {
+ uint32_t hashvalue = 5381;
+ StackString *iterator = SSTR_WRAP(self);
+
+ const ViewCB_Nibble_t nibble = METHOD_PTR(iterator->vtable,
+ CFISH_ViewCB_Nibble);
+ while (iterator->size) {
+ uint32_t code_point = (uint32_t)nibble((ViewCharBuf*)iterator);
+ hashvalue = ((hashvalue << 5) + hashvalue) ^ code_point;
+ }
+
+ return (int32_t) hashvalue;
+}
+
+static void
+S_grow(String *self, size_t size) {
+ if (size >= self->cap) {
+ Str_Grow(self, size);
+ }
+}
+
+char*
+Str_Grow_IMP(String *self, size_t size) {
+ if (size >= self->cap) {
+ self->cap = size + 1;
+ self->ptr = (char*)REALLOCATE(self->ptr, self->cap);
+ }
+ return self->ptr;
+}
+
+static void
+S_die_invalid_utf8(const char *text, size_t size, const char *file, int line,
+ const char *func) {
+ fprintf(stderr, "Invalid UTF-8, aborting: '");
+ fwrite(text, sizeof(char), size < 200 ? size : 200, stderr);
+ if (size > 200) { fwrite("[...]", sizeof(char), 5, stderr); }
+ fprintf(stderr, "' (length %lu)\n", (unsigned long)size);
+ Err_throw_at(ERR, file, line, func, "Invalid UTF-8");
+}
+
+static void
+S_die_invalid_pattern(const char *pattern) {
+ size_t pattern_len = strlen(pattern);
+ fprintf(stderr, "Invalid pattern, aborting: '");
+ fwrite(pattern, sizeof(char), pattern_len, stderr);
+ fprintf(stderr, "'\n");
+ THROW(ERR, "Invalid pattern.");
+}
+
+void
+Str_catf(String *self, const char *pattern, ...) {
+ va_list args;
+ va_start(args, pattern);
+ Str_VCatF(self, pattern, args);
+ va_end(args);
+}
+
+void
+Str_VCatF_IMP(String *self, const char *pattern, va_list args) {
+ size_t pattern_len = strlen(pattern);
+ const char *pattern_start = pattern;
+ const char *pattern_end = pattern + pattern_len;
+ char buf[64];
+
+ for (; pattern < pattern_end; pattern++) {
+ const char *slice_end = pattern;
+
+ // Consume all characters leading up to a '%'.
+ while (slice_end < pattern_end && *slice_end != '%') { slice_end++; }
+ if (pattern != slice_end) {
+ size_t size = slice_end - pattern;
+ Str_Cat_Trusted_Str(self, pattern, size);
+ pattern = slice_end;
+ }
+
+ if (pattern < pattern_end) {
+ pattern++; // Move past '%'.
+
+ switch (*pattern) {
+ case '%': {
+ Str_Cat_Trusted_Str(self, "%", 1);
+ }
+ break;
+ case 'o': {
+ Obj *obj = va_arg(args, Obj*);
+ if (!obj) {
+ Str_Cat_Trusted_Str(self, "[NULL]", 6);
+ }
+ else if (Obj_Is_A(obj, STRING)) {
+ Str_Cat(self, (String*)obj);
+ }
+ else {
+ String *string = Obj_To_String(obj);
+ Str_Cat(self, string);
+ DECREF(string);
+ }
+ }
+ break;
+ case 'i': {
+ int64_t val = 0;
+ size_t size;
+ if (pattern[1] == '8') {
+ val = va_arg(args, int32_t);
+ pattern++;
+ }
+ else if (pattern[1] == '3' && pattern[2] == '2') {
+ val = va_arg(args, int32_t);
+ pattern += 2;
+ }
+ else if (pattern[1] == '6' && pattern[2] == '4') {
+ val = va_arg(args, int64_t);
+ pattern += 2;
+ }
+ else {
+ S_die_invalid_pattern(pattern_start);
+ }
+ size = sprintf(buf, "%" PRId64, val);
+ Str_Cat_Trusted_Str(self, buf, size);
+ }
+ break;
+ case 'u': {
+ uint64_t val = 0;
+ size_t size;
+ if (pattern[1] == '8') {
+ val = va_arg(args, uint32_t);
+ pattern += 1;
+ }
+ else if (pattern[1] == '3' && pattern[2] == '2') {
+ val = va_arg(args, uint32_t);
+ pattern += 2;
+ }
+ else if (pattern[1] == '6' && pattern[2] == '4') {
+ val = va_arg(args, uint64_t);
+ pattern += 2;
+ }
+ else {
+ S_die_invalid_pattern(pattern_start);
+ }
+ size = sprintf(buf, "%" PRIu64, val);
+ Str_Cat_Trusted_Str(self, buf, size);
+ }
+ break;
+ case 'f': {
+ if (pattern[1] == '6' && pattern[2] == '4') {
+ double num = va_arg(args, double);
+ char bigbuf[512];
+ size_t size = sprintf(bigbuf, "%g", num);
+ Str_Cat_Trusted_Str(self, bigbuf, size);
+ pattern += 2;
+ }
+ else {
+ S_die_invalid_pattern(pattern_start);
+ }
+ }
+ break;
+ case 'x': {
+ if (pattern[1] == '3' && pattern[2] == '2') {
+ unsigned long val = va_arg(args, uint32_t);
+ size_t size = sprintf(buf, "%.8lx", val);
+ Str_Cat_Trusted_Str(self, buf, size);
+ pattern += 2;
+ }
+ else {
+ S_die_invalid_pattern(pattern_start);
+ }
+ }
+ break;
+ case 's': {
+ char *string = va_arg(args, char*);
+ if (string == NULL) {
+ Str_Cat_Trusted_Str(self, "[NULL]", 6);
+ }
+ else {
+ size_t size = strlen(string);
+ if (StrHelp_utf8_valid(string, size)) {
+ Str_Cat_Trusted_Str(self, string, size);
+ }
+ else {
+ Str_Cat_Trusted_Str(self, "[INVALID UTF8]", 14);
+ }
+ }
+ }
+ break;
+ default: {
+ // Assume NULL-terminated pattern string, which
+ // eliminates the need for bounds checking if '%' is
+ // the last visible character.
+ S_die_invalid_pattern(pattern_start);
+ }
+ }
+ }
+ }
+}
+
+String*
+Str_To_String_IMP(String *self) {
+ return Str_new_from_trusted_utf8(self->ptr, self->size);
+}
+
+void
+Str_Cat_Char_IMP(String *self, uint32_t code_point) {
+ const size_t MAX_UTF8_BYTES = 4;
+ if (self->size + MAX_UTF8_BYTES >= self->cap) {
+ S_grow(self, Memory_oversize(self->size + MAX_UTF8_BYTES,
+ sizeof(char)));
+ }
+ char *end = self->ptr + self->size;
+ size_t count = StrHelp_encode_utf8_char(code_point, (uint8_t*)end);
+ self->size += count;
+ *(end + count) = '\0';
+}
+
+int32_t
+Str_Swap_Chars_IMP(String *self, uint32_t match, uint32_t replacement) {
+ int32_t num_swapped = 0;
+
+ if (match > 127) {
+ THROW(ERR, "match point too high: %u32", match);
+ }
+ else if (replacement > 127) {
+ THROW(ERR, "replacement code point too high: %u32", replacement);
+ }
+ else {
+ char *ptr = self->ptr;
+ char *const limit = ptr + self->size;
+ for (; ptr < limit; ptr++) {
+ if (*ptr == (char)match) {
+ *ptr = (char)replacement;
+ num_swapped++;
+ }
+ }
+ }
+
+ return num_swapped;
+}
+
+int64_t
+Str_To_I64_IMP(String *self) {
+ return Str_BaseX_To_I64(self, 10);
+}
+
+int64_t
+Str_BaseX_To_I64_IMP(String *self, uint32_t base) {
+ StackString *iterator = SSTR_WRAP(self);
+ int64_t retval = 0;
+ bool is_negative = false;
+
+ // Advance past minus sign.
+ if (SStr_Code_Point_At(iterator, 0) == '-') {
+ SStr_Nibble(iterator);
+ is_negative = true;
+ }
+
+ // Accumulate.
+ while (iterator->size) {
+ int32_t code_point = SStr_Nibble(iterator);
+ if (isalnum(code_point)) {
+ int32_t addend = isdigit(code_point)
+ ? code_point - '0'
+ : tolower(code_point) - 'a' + 10;
+ if (addend > (int32_t)base) { break; }
+ retval *= base;
+ retval += addend;
+ }
+ else {
+ break;
+ }
+ }
+
+ // Apply minus sign.
+ if (is_negative) { retval = 0 - retval; }
+
+ return retval;
+}
+
+static double
+S_safe_to_f64(String *self) {
+ size_t amount = self->size < 511 ? self->size : 511;
+ char buf[512];
+ memcpy(buf, self->ptr, amount);
+ buf[amount] = 0; // NULL-terminate.
+ return strtod(buf, NULL);
+}
+
+double
+Str_To_F64_IMP(String *self) {
+ char *end;
+ double value = strtod(self->ptr, &end);
+ size_t consumed = end - self->ptr;
+ if (consumed > self->size) { // strtod overran
+ value = S_safe_to_f64(self);
+ }
+ return value;
+}
+
+String*
+Str_To_CB8_IMP(String *self) {
+ return Str_new_from_trusted_utf8(self->ptr, self->size);
+}
+
+String*
+Str_Clone_IMP(String *self) {
+ return Str_new_from_trusted_utf8(self->ptr, self->size);
+}
+
+void
+Str_Mimic_Str_IMP(String *self, const char* ptr, size_t size) {
+ if (!StrHelp_utf8_valid(ptr, size)) {
+ DIE_INVALID_UTF8(ptr, size);
+ }
+ if (size >= self->cap) { S_grow(self, size); }
+ memmove(self->ptr, ptr, size);
+ self->size = size;
+ self->ptr[size] = '\0';
+}
+
+void
+Str_Mimic_IMP(String *self, Obj *other) {
+ String *twin = (String*)CERTIFY(other, STRING);
+ if (twin->size >= self->cap) { S_grow(self, twin->size); }
+ memmove(self->ptr, twin->ptr, twin->size);
+ self->size = twin->size;
+ self->ptr[twin->size] = '\0';
+}
+
+void
+Str_Cat_Str_IMP(String *self, const char* ptr, size_t size) {
+ if (!StrHelp_utf8_valid(ptr, size)) {
+ DIE_INVALID_UTF8(ptr, size);
+ }
+ Str_Cat_Trusted_Str_IMP(self, ptr, size);
+}
+
+void
+Str_Cat_Trusted_Str_IMP(String *self, const char* ptr, size_t size) {
+ const size_t new_size = self->size + size;
+ if (new_size >= self->cap) {
+ size_t amount = Memory_oversize(new_size, sizeof(char));
+ S_grow(self, amount);
+ }
+ memcpy((self->ptr + self->size), ptr, size);
+ self->size = new_size;
+ self->ptr[new_size] = '\0';
+}
+
+void
+Str_Cat_IMP(String *self, const String *other) {
+ const size_t new_size = self->size + other->size;
+ if (new_size >= self->cap) {
+ size_t amount = Memory_oversize(new_size, sizeof(char));
+ S_grow(self, amount);
+ }
+ memcpy((self->ptr + self->size), other->ptr, other->size);
+ self->size = new_size;
+ self->ptr[new_size] = '\0';
+}
+
+bool
+Str_Starts_With_IMP(String *self, const String *prefix) {
+ return Str_Starts_With_Str_IMP(self, prefix->ptr, prefix->size);
+}
+
+bool
+Str_Starts_With_Str_IMP(String *self, const char *prefix, size_t size) {
+ if (size <= self->size
+ && (memcmp(self->ptr, prefix, size) == 0)
+ ) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+bool
+Str_Equals_IMP(String *self, Obj *other) {
+ String *const twin = (String*)other;
+ if (twin == self) { return true; }
+ if (!Obj_Is_A(other, STRING)) { return false; }
+ return Str_Equals_Str_IMP(self, twin->ptr, twin->size);
+}
+
+int32_t
+Str_Compare_To_IMP(String *self, Obj *other) {
+ CERTIFY(other, STRING);
+ return Str_compare(&self, &other);
+}
+
+bool
+Str_Equals_Str_IMP(String *self, const char *ptr, size_t size) {
+ if (self->size != size) {
+ return false;
+ }
+ return (memcmp(self->ptr, ptr, self->size) == 0);
+}
+
+bool
+Str_Ends_With_IMP(String *self, const String *postfix) {
+ return Str_Ends_With_Str_IMP(self, postfix->ptr, postfix->size);
+}
+
+bool
+Str_Ends_With_Str_IMP(String *self, const char *postfix, size_t postfix_len) {
+ if (postfix_len <= self->size) {
+ char *start = self->ptr + self->size - postfix_len;
+ if (memcmp(start, postfix, postfix_len) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int64_t
+Str_Find_IMP(String *self, const String *substring) {
+ return Str_Find_Str(self, substring->ptr, substring->size);
+}
+
+int64_t
+Str_Find_Str_IMP(String *self, const char *ptr, size_t size) {
+ StackString *iterator = SSTR_WRAP(self);
+ int64_t location = 0;
+
+ while (iterator->size) {
+ if (SStr_Starts_With_Str(iterator, ptr, size)) {
+ return location;
+ }
+ SStr_Nip(iterator, 1);
+ location++;
+ }
+
+ return -1;
+}
+
+uint32_t
+Str_Trim_IMP(String *self) {
+ return Str_Trim_Top(self) + Str_Trim_Tail(self);
+}
+
+uint32_t
+Str_Trim_Top_IMP(String *self) {
+ char *ptr = self->ptr;
+ char *end = ptr + self->size;
+ uint32_t count = 0;
+
+ while (ptr < end) {
+ uint32_t code_point = StrHelp_decode_utf8_char(ptr);
+ if (!StrHelp_is_whitespace(code_point)) { break; }
+ ptr += StrHelp_UTF8_COUNT[*(uint8_t*)ptr];
+ count++;
+ }
+ if (ptr > end) {
+ DIE_INVALID_UTF8(self->ptr, self->size);
+ }
+
+ if (count) {
+ // Copy string backwards.
+ self->size = end - ptr;
+ memmove(self->ptr, ptr, self->size);
+ }
+
+ return count;
+}
+
+uint32_t
+Str_Trim_Tail_IMP(String *self) {
+ uint32_t count = 0;
+ char *const top = self->ptr;
+ const char *ptr = top + self->size;
+ size_t new_size = self->size;
+
+ while (NULL != (ptr = StrHelp_back_utf8_char(ptr, top))) {
+ uint32_t code_point = StrHelp_decode_utf8_char(ptr);
+ if (!StrHelp_is_whitespace(code_point)) { break; }
+ new_size = ptr - top;
+ count++;
+ }
+ self->size = new_size;
+
+ return count;
+}
+
+size_t
+Str_Length_IMP(String *self) {
+ size_t len = 0;
+ char *ptr = self->ptr;
+ char *end = ptr + self->size;
+ while (ptr < end) {
+ ptr += StrHelp_UTF8_COUNT[*(uint8_t*)ptr];
+ len++;
+ }
+ if (ptr != end) {
+ DIE_INVALID_UTF8(self->ptr, self->size);
+ }
+ return len;
+}
+
+size_t
+Str_Truncate_IMP(String *self, size_t count) {
+ uint32_t num_code_points;
+ StackString *iterator = SSTR_WRAP(self);
+ num_code_points = SStr_Nip(iterator, count);
+ self->size -= iterator->size;
+ return num_code_points;
+}
+
+uint32_t
+Str_Code_Point_At_IMP(String *self, size_t tick) {
+ size_t count = 0;
+ char *ptr = self->ptr;
+ char *const end = ptr + self->size;
+
+ for (; ptr < end; ptr += StrHelp_UTF8_COUNT[*(uint8_t*)ptr]) {
+ if (count == tick) {
+ if (ptr > end) {
+ DIE_INVALID_UTF8(self->ptr, self->size);
+ }
+ return StrHelp_decode_utf8_char(ptr);
+ }
+ count++;
+ }
+
+ return 0;
+}
+
+uint32_t
+Str_Code_Point_From_IMP(String *self, size_t tick) {
+ size_t count = 0;
+ char *top = self->ptr;
+ const char *ptr = top + self->size;
+
+ for (count = 0; count < tick; count++) {
+ if (NULL == (ptr = StrHelp_back_utf8_char(ptr, top))) { return 0; }
+ }
+ return StrHelp_decode_utf8_char(ptr);
+}
+
+String*
+Str_SubString_IMP(String *self, size_t offset, size_t len) {
+ StackString *iterator = SSTR_WRAP(self);
+ char *sub_start;
+ size_t byte_len;
+
+ SStr_Nip(iterator, offset);
+ sub_start = iterator->ptr;
+ SStr_Nip(iterator, len);
+ byte_len = iterator->ptr - sub_start;
+
+ return Str_new_from_trusted_utf8(sub_start, byte_len);
+}
+
+int
+Str_compare(const void *va, const void *vb) {
+ const String *a = *(const String**)va;
+ const String *b = *(const String**)vb;
+ StackString *iterator_a = SSTR_WRAP(a);
+ StackString *iterator_b = SSTR_WRAP(b);
+ while (iterator_a->size && iterator_b->size) {
+ int32_t code_point_a = SStr_Nibble(iterator_a);
+ int32_t code_point_b = SStr_Nibble(iterator_b);
+ const int32_t comparison = code_point_a - code_point_b;
+ if (comparison != 0) { return comparison; }
+ }
+ if (iterator_a->size != iterator_b->size) {
+ return iterator_a->size < iterator_b->size ? -1 : 1;
+ }
+ return 0;
+}
+
+bool
+Str_less_than(const void *va, const void *vb) {
+ return Str_compare(va, vb) < 0 ? 1 : 0;
+}
+
+void
+Str_Set_Size_IMP(String *self, size_t size) {
+ self->size = size;
+}
+
+size_t
+Str_Get_Size_IMP(String *self) {
+ return self->size;
+}
+
+uint8_t*
+Str_Get_Ptr8_IMP(String *self) {
+ return (uint8_t*)self->ptr;
+}
+
+/*****************************************************************/
+
+ViewCharBuf*
+ViewCB_new_from_utf8(const char *utf8, size_t size) {
+ if (!StrHelp_utf8_valid(utf8, size)) {
+ DIE_INVALID_UTF8(utf8, size);
+ }
+ return ViewCB_new_from_trusted_utf8(utf8, size);
+}
+
+ViewCharBuf*
+ViewCB_new_from_trusted_utf8(const char *utf8, size_t size) {
+ ViewCharBuf *self = (ViewCharBuf*)VTable_Make_Obj(VIEWCHARBUF);
+ return ViewCB_init(self, utf8, size);
+}
+
+ViewCharBuf*
+ViewCB_init(ViewCharBuf *self, const char *utf8, size_t size) {
+ self->ptr = (char*)utf8;
+ self->size = size;
+ self->cap = 0;
+ return self;
+}
+
+void
+ViewCB_Destroy_IMP(ViewCharBuf *self) {
+ // Note that we do not free self->ptr, and that we invoke the
+ // SUPER_DESTROY with STRING instead of VIEWCHARBUF.
+ SUPER_DESTROY(self, STRING);
+}
+
+void
+ViewCB_Assign_IMP(ViewCharBuf *self, const String *other) {
+ self->ptr = other->ptr;
+ self->size = other->size;
+}
+
+void
+ViewCB_Assign_Str_IMP(ViewCharBuf *self, const char *utf8, size_t size) {
+ if (!StrHelp_utf8_valid(utf8, size)) {
+ DIE_INVALID_UTF8(utf8, size);
+ }
+ self->ptr = (char*)utf8;
+ self->size = size;
+}
+
+void
+ViewCB_Assign_Trusted_Str_IMP(ViewCharBuf *self, const char *utf8, size_t size) {
+ self->ptr = (char*)utf8;
+ self->size = size;
+}
+
+uint32_t
+ViewCB_Trim_Top_IMP(ViewCharBuf *self) {
+ uint32_t count = 0;
+ char *ptr = self->ptr;
+ char *end = ptr + self->size;
+
+ while (ptr < end) {
+ uint32_t code_point = StrHelp_decode_utf8_char(ptr);
+ if (!StrHelp_is_whitespace(code_point)) { break; }
+ ptr += StrHelp_UTF8_COUNT[*(uint8_t*)ptr];
+ count++;
+ }
+
+ if (count) {
+ if (ptr > end) {
+ DIE_INVALID_UTF8(self->ptr, self->size);
+ }
+ self->size = end - ptr;
+ self->ptr = ptr;
+ }
+
+ return count;
+}
+
+size_t
+ViewCB_Nip_IMP(ViewCharBuf *self, size_t count) {
+ size_t num_nipped;
+ char *ptr = self->ptr;
+ char *end = ptr + self->size;
+ for (num_nipped = 0;
+ ptr < end && count--;
+ ptr += StrHelp_UTF8_COUNT[*(uint8_t*)ptr]
+ ) {
+ num_nipped++;
+ }
+ if (ptr > end) {
+ DIE_INVALID_UTF8(self->ptr, self->size);
+ }
+ self->size = end - ptr;
+ self->ptr = ptr;
+ return num_nipped;
+}
+
+int32_t
+ViewCB_Nibble_IMP(ViewCharBuf *self) {
+ if (self->size == 0) {
+ return 0;
+ }
+ else {
+ int32_t retval = (int32_t)StrHelp_decode_utf8_char(self->ptr);
+ size_t consumed = StrHelp_UTF8_COUNT[*(uint8_t*)self->ptr];
+ if (consumed > self->size) {
+ DIE_INVALID_UTF8(self->ptr, self->size);
+ }
+ self->ptr += consumed;
+ self->size -= consumed;
+ return retval;
+ }
+}
+
+size_t
+ViewCB_Chop_IMP(ViewCharBuf *self, size_t count) {
+ size_t num_chopped = 0;
+ char *top = self->ptr;
+ const char *ptr = top + self->size;
+ for (num_chopped = 0; num_chopped < count; num_chopped++) {
+ const char *end = ptr;
+ if (NULL == (ptr = StrHelp_back_utf8_char(ptr, top))) { break; }
+ self->size -= (end - ptr);
+ }
+ return num_chopped;
+}
+
+char*
+ViewCB_Grow_IMP(ViewCharBuf *self, size_t size) {
+ UNUSED_VAR(size);
+ THROW(ERR, "Can't grow a ViewCharBuf ('%o')", self);
+ UNREACHABLE_RETURN(char*);
+}
+
+/*****************************************************************/
+
+StackString*
+SStr_new(void *allocation) {
+ static char empty_string[] = "";
+ StackString *self
+ = (StackString*)VTable_Init_Obj(STACKSTRING, allocation);
+ self->cap = 0;
+ self->size = 0;
+ self->ptr = empty_string;
+ return self;
+}
+
+StackString*
+SStr_newf(void *allocation, size_t alloc_size, const char *pattern, ...) {
+ StackString *self
+ = (StackString*)VTable_Init_Obj(STACKSTRING, allocation);
+ self->cap = alloc_size - sizeof(StackString);
+ self->size = 0;
+ self->ptr = ((char*)allocation) + sizeof(StackString);
+
+ va_list args;
+ va_start(args, pattern);
+ SStr_VCatF(self, pattern, args);
+ va_end(args);
+
+ return self;
+}
+
+StackString*
+SStr_wrap_str(void *allocation, const char *ptr, size_t size) {
+ StackString *self
+ = (StackString*)VTable_Init_Obj(STACKSTRING, allocation);
+ self->cap = 0;
+ self->size = size;
+ self->ptr = (char*)ptr;
+ return self;
+}
+
+StackString*
+SStr_wrap(void *allocation, const String *source) {
+ return SStr_wrap_str(allocation, source->ptr, source->size);
+}
+
+size_t
+SStr_size() {
+ return sizeof(StackString);
+}
+
+void
+SStr_Destroy_IMP(StackString *self) {
+ THROW(ERR, "Can't destroy a StackString ('%o')", self);
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/String.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/String.cfh b/clownfish/runtime/core/Clownfish/String.cfh
new file mode 100644
index 0000000..2cddf4a
--- /dev/null
+++ b/clownfish/runtime/core/Clownfish/String.cfh
@@ -0,0 +1,392 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+parcel Clownfish;
+
+/**
+ * Growable buffer holding Unicode characters.
+ */
+
+class Clownfish::String cnick Str
+ inherits Clownfish::Obj {
+
+ char *ptr;
+ size_t size;
+ size_t cap; /* allocated bytes, including terminating null */
+
+ inert incremented String*
+ new(size_t size);
+
+ inert String*
+ init(String *self, size_t size);
+
+ /** Return a new String which holds a copy of the passed-in string.
+ * Check for UTF-8 validity.
+ */
+ inert incremented String*
+ new_from_utf8(const char *utf8, size_t size);
+
+ /** Return a new String which holds a copy of the passed-in string. No
+ * validity checking is performed.
+ */
+ inert incremented String*
+ new_from_trusted_utf8(const char *utf8, size_t size);
+
+ /** Return a pointer to a new String which assumes ownership of the
+ * passed-in string. Check validity of supplied UTF-8.
+ */
+ inert incremented String*
+ new_steal_str(char *ptr, size_t size, size_t cap);
+
+ /** Return a pointer to a new String which assumes ownership of the
+ * passed-in string. Do not check validity of supplied UTF-8.
+ */
+ inert incremented String*
+ new_steal_from_trusted_str(char *ptr, size_t size, size_t cap);
+
+ /** Initialize the String using the passed-in string. Do not check
+ * validity of supplied UTF-8.
+ */
+ public inert String*
+ init_steal_trusted_str(decremented String *self, char *ptr,
+ size_t size, size_t cap);
+
+ /** Return a pointer to a new String which contains formatted data
+ * expanded according to Str_VCatF.
+ *
+ * Note: a user-supplied <code>pattern</code> string is a security hole
+ * and must not be allowed.
+ */
+ inert incremented String*
+ newf(const char *pattern, ...);
+
+ /** Perform lexical comparison of two Strings, with level of indirection
+ * set to please qsort and friends.
+ */
+ inert int
+ compare(const void *va, const void *vb);
+
+ /** Perform lexical comparison of two Strings, with level of indirection
+ * set to please qsort and friends, and return true if <code>a</code> is
+ * less than <code>b</code>.
+ */
+ inert bool
+ less_than(const void *va, const void *vb);
+
+ public void
+ Mimic(String *self, Obj *other);
+
+ void
+ Mimic_Str(String *self, const char *ptr, size_t size);
+
+ /** Concatenate the passed-in string onto the end of the String.
+ */
+ void
+ Cat_Str(String *self, const char *ptr, size_t size);
+
+ /** Concatenate the contents of <code>other</code> onto the end of the
+ * caller.
+ */
+ void
+ Cat(String *self, const String *other);
+
+ /** Concatenate formatted arguments. Similar to the printf family, but
+ * only accepts minimal options (just enough for decent error messages).
+ *
+ * Objects: %o
+ * char*: %s
+ * integers: %i8 %i32 %i64 %u8 %u32 %u64
+ * floats: %f64
+ * hex: %x32
+ *
+ * Note that all Clownfish Objects, including Strings, are printed via
+ * %o (which invokes Obj_To_String()).
+ */
+ void
+ VCatF(String *self, const char *pattern, va_list args);
+
+ /** Invokes Str_VCatF to concatenate formatted arguments. Note that this
+ * is only a function and not a method.
+ */
+ inert void
+ catf(String *self, const char *pattern, ...);
+
+ /** Concatenate one Unicode character onto the end of the String.
+ */
+ void
+ Cat_Char(String *self, uint32_t code_point);
+
+ /** Replace all instances of one character for the other. For now, both
+ * the source and replacement code points must be ASCII.
+ */
+ int32_t
+ Swap_Chars(String *self, uint32_t match, uint32_t replacement);
+
+ public int64_t
+ To_I64(String *self);
+
+ /** Extract a 64-bit integer from a variable-base stringified version.
+ */
+ int64_t
+ BaseX_To_I64(String *self, uint32_t base);
+
+ public double
+ To_F64(String *self);
+
+ /** Assign more memory to the String, if it doesn't already have enough
+ * room to hold a string of <code>size</code> bytes. Cannot shrink the
+ * allocation.
+ *
+ * @return a pointer to the raw buffer.
+ */
+ char*
+ Grow(String *self, size_t size);
+
+ /** Test whether the String starts with the content of another.
+ */
+ bool
+ Starts_With(String *self, const String *prefix);
+
+ /** Test whether the String starts with the passed-in string.
+ */
+ bool
+ Starts_With_Str(String *self, const char *prefix, size_t size);
+
+ /** Test whether the String ends with the content of another.
+ */
+ bool
+ Ends_With(String *self, const String *postfix);
+
+ /** Test whether the String ends with the passed-in string.
+ */
+ bool
+ Ends_With_Str(String *self, const char *postfix, size_t size);
+
+ /** Return the location of the substring within the String (measured in
+ * code points), or -1 if the substring does not match.
+ */
+ int64_t
+ Find(String *self, const String *substring);
+
+ int64_t
+ Find_Str(String *self, const char *ptr, size_t size);
+
+ /** Test whether the String matches the passed-in string.
+ */
+ bool
+ Equals_Str(String *self, const char *ptr, size_t size);
+
+ /** Return the number of Unicode code points in the object's string.
+ */
+ size_t
+ Length(String *self);
+
+ /** Set the String's <code>size</code> attribute.
+ */
+ void
+ Set_Size(String *self, size_t size);
+
+ /** Get the String's <code>size</code> attribute.
+ */
+ size_t
+ Get_Size(String *self);
+
+ /** Return the internal backing array for the String if its internal
+ * encoding is UTF-8. If it is not encoded as UTF-8 throw an exception.
+ */
+ uint8_t*
+ Get_Ptr8(String *self);
+
+ /** Return a fresh copy of the string data in a String with an internal
+ * encoding of UTF-8.
+ */
+ String*
+ To_CB8(String *self);
+
+ public incremented String*
+ Clone(String *self);
+
+ public void
+ Destroy(String *self);
+
+ public bool
+ Equals(String *self, Obj *other);
+
+ public int32_t
+ Compare_To(String *self, Obj *other);
+
+ public int32_t
+ Hash_Sum(String *self);
+
+ public incremented String*
+ To_String(String *self);
+
+ /** Remove Unicode whitespace characters from both top and tail.
+ */
+ uint32_t
+ Trim(String *self);
+
+ /** Remove leading Unicode whitespace.
+ */
+ uint32_t
+ Trim_Top(String *self);
+
+ /** Remove trailing Unicode whitespace.
+ */
+ uint32_t
+ Trim_Tail(String *self);
+
+ /** Truncate the String so that it contains no more than
+ * <code>count</code>characters.
+ *
+ * @param count Maximum new length, in Unicode code points.
+ * @return The number of code points left in the string after truncation.
+ */
+ size_t
+ Truncate(String *self, size_t count);
+
+ /** Return the Unicode code point at the specified number of code points
+ * in. Return 0 if the string length is exceeded. (XXX It would be
+ * better to throw an exception, but that's not practical with UTF-8 and
+ * no cached length.)
+ */
+ uint32_t
+ Code_Point_At(String *self, size_t tick);
+
+ /** Return the Unicode code point at the specified number of code points
+ * counted backwards from the end of the string. Return 0 if outside the
+ * string.
+ */
+ uint32_t
+ Code_Point_From(String *self, size_t tick);
+
+ /** Return a newly allocated String containing a copy of the indicated
+ * substring.
+ * @param offset Offset from the top, in code points.
+ * @param len The desired length of the substring, in code points.
+ */
+ incremented String*
+ SubString(String *self, size_t offset, size_t len);
+
+ /** Concatenate the supplied text onto the end of the String. Don't
+ * check for UTF-8 validity.
+ */
+ void
+ Cat_Trusted_Str(String *self, const char *ptr, size_t size);
+}
+
+class Clownfish::ViewCharBuf cnick ViewCB
+ inherits Clownfish::String {
+
+ inert incremented ViewCharBuf*
+ new_from_utf8(const char *utf8, size_t size);
+
+ inert incremented ViewCharBuf*
+ new_from_trusted_utf8(const char *utf8, size_t size);
+
+ inert ViewCharBuf*
+ init(ViewCharBuf *self, const char *utf8, size_t size);
+
+ void
+ Assign(ViewCharBuf *self, const String *other);
+
+ void
+ Assign_Str(ViewCharBuf *self, const char *utf8, size_t size);
+
+ void
+ Assign_Trusted_Str(ViewCharBuf *self, const char *utf8, size_t size);
+
+ uint32_t
+ Trim_Top(ViewCharBuf *self);
+
+ /** Remove characters (measured in code points) from the top of the
+ * ViewCharBuf. Returns the number nipped.
+ */
+ size_t
+ Nip(ViewCharBuf *self, size_t count);
+
+ /** Remove one character from the top of the ViewCharBuf. Returns the
+ * code point, or 0 if the string was empty.
+ */
+ int32_t
+ Nibble(ViewCharBuf *self);
+
+ /** Remove characters (measured in code points) from the end of the
+ * ViewCharBuf. Returns the number chopped.
+ */
+ size_t
+ Chop(ViewCharBuf *self, size_t count);
+
+ /** Throws an error. */
+ char*
+ Grow(ViewCharBuf *self, size_t size);
+
+ public void
+ Destroy(ViewCharBuf *self);
+}
+
+class Clownfish::StackString cnick SStr
+ inherits Clownfish::ViewCharBuf {
+
+ /** Return a StackString with a blank string.
+ */
+ inert incremented StackString*
+ new(void *allocation);
+
+ /**
+ * @param allocation A single block of memory which will be used for both
+ * the StackString object and its buffer.
+ * @param alloc_size The size of the allocation.
+ * @param pattern A format pattern.
+ */
+ inert incremented StackString*
+ newf(void *allocation, size_t alloc_size, const char *pattern, ...);
+
+ inert incremented StackString*
+ wrap(void *allocation, const String *source);
+
+ inert incremented StackString*
+ wrap_str(void *allocation, const char *ptr, size_t size);
+
+ /** Return the size for a StackString struct.
+ */
+ inert size_t
+ size();
+
+ /** Throws an error.
+ */
+ public void
+ Destroy(StackString *self);
+}
+
+__C__
+
+#define CFISH_SStr_BLANK() cfish_SStr_new(cfish_alloca(cfish_SStr_size()))
+
+#define CFISH_SStr_WRAP(source) \
+ cfish_SStr_wrap(cfish_alloca(cfish_SStr_size()), source)
+
+#define CFISH_SStr_WRAP_STR(ptr, size) \
+ cfish_SStr_wrap_str(cfish_alloca(cfish_SStr_size()), ptr, size)
+
+#ifdef CFISH_USE_SHORT_NAMES
+ #define SStr_BLANK CFISH_SStr_BLANK
+ #define SSTR_WRAP CFISH_SStr_WRAP
+ #define SSTR_WRAP_STR CFISH_SStr_WRAP_STR
+#endif
+__END_C__
+
+
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestCharBuf.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestCharBuf.c b/clownfish/runtime/core/Clownfish/Test/TestCharBuf.c
index 50e3c23..4ea9429 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestCharBuf.c
+++ b/clownfish/runtime/core/Clownfish/Test/TestCharBuf.c
@@ -25,7 +25,7 @@
#include "Clownfish/Test/TestCharBuf.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Num.h"
#include "Clownfish/Test.h"
#include "Clownfish/TestHarness/TestBatchRunner.h"
@@ -40,33 +40,33 @@ TestCB_new() {
return (TestCharBuf*)VTable_Make_Obj(TESTCHARBUF);
}
-static CharBuf*
+static String*
S_get_cb(const char *string) {
- return CB_new_from_utf8(string, strlen(string));
+ return Str_new_from_utf8(string, strlen(string));
}
static void
test_Cat(TestBatchRunner *runner) {
- CharBuf *wanted = CB_newf("a%s", smiley);
- CharBuf *got = S_get_cb("");
+ String *wanted = Str_newf("a%s", smiley);
+ String *got = S_get_cb("");
- CB_Cat(got, wanted);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Cat");
+ Str_Cat(got, wanted);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat");
DECREF(got);
got = S_get_cb("a");
- CB_Cat_Char(got, 0x263A);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Cat_Char");
+ Str_Cat_Char(got, 0x263A);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat_Char");
DECREF(got);
got = S_get_cb("a");
- CB_Cat_Str(got, smiley, smiley_len);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Cat_Str");
+ Str_Cat_Str(got, smiley, smiley_len);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat_Str");
DECREF(got);
got = S_get_cb("a");
- CB_Cat_Trusted_Str(got, smiley, smiley_len);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Cat_Trusted_Str");
+ Str_Cat_Trusted_Str(got, smiley, smiley_len);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat_Trusted_Str");
DECREF(got);
DECREF(wanted);
@@ -74,20 +74,20 @@ test_Cat(TestBatchRunner *runner) {
static void
test_Mimic_and_Clone(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo");
- CharBuf *got = S_get_cb("bar");
+ String *wanted = S_get_cb("foo");
+ String *got = S_get_cb("bar");
- CB_Mimic(got, (Obj*)wanted);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Mimic");
+ Str_Mimic(got, (Obj*)wanted);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Mimic");
DECREF(got);
got = S_get_cb("bar");
- CB_Mimic_Str(got, "foo", 3);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Mimic_Str");
+ Str_Mimic_Str(got, "foo", 3);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Mimic_Str");
DECREF(got);
- got = CB_Clone(wanted);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Clone");
+ got = Str_Clone(wanted);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Clone");
DECREF(got);
DECREF(wanted);
@@ -95,25 +95,25 @@ test_Mimic_and_Clone(TestBatchRunner *runner) {
static void
test_Find(TestBatchRunner *runner) {
- CharBuf *string;
- CharBuf *substring = S_get_cb("foo");
+ String *string;
+ String *substring = S_get_cb("foo");
string = S_get_cb("");
- TEST_TRUE(runner, CB_Find(string, substring) == -1, "Not in empty string");
+ TEST_TRUE(runner, Str_Find(string, substring) == -1, "Not in empty string");
DECREF(string);
string = S_get_cb("foo");
- TEST_TRUE(runner, CB_Find(string, substring) == 0, "Find complete string");
+ TEST_TRUE(runner, Str_Find(string, substring) == 0, "Find complete string");
DECREF(string);
string = S_get_cb("afoo");
- TEST_TRUE(runner, CB_Find(string, substring) == 1, "Find after first");
- CB_Set_Size(string, 3);
- TEST_TRUE(runner, CB_Find(string, substring) == -1, "Don't overrun");
+ TEST_TRUE(runner, Str_Find(string, substring) == 1, "Find after first");
+ Str_Set_Size(string, 3);
+ TEST_TRUE(runner, Str_Find(string, substring) == -1, "Don't overrun");
DECREF(string);
string = S_get_cb("afood");
- TEST_TRUE(runner, CB_Find(string, substring) == 1, "Find in middle");
+ TEST_TRUE(runner, Str_Find(string, substring) == 1, "Find in middle");
DECREF(string);
DECREF(substring);
@@ -123,14 +123,14 @@ static void
test_Code_Point_At_and_From(TestBatchRunner *runner) {
uint32_t code_points[] = { 'a', 0x263A, 0x263A, 'b', 0x263A, 'c' };
uint32_t num_code_points = sizeof(code_points) / sizeof(uint32_t);
- CharBuf *string = CB_newf("a%s%sb%sc", smiley, smiley, smiley);
+ String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
uint32_t i;
for (i = 0; i < num_code_points; i++) {
uint32_t from = num_code_points - i - 1;
- TEST_INT_EQ(runner, CB_Code_Point_At(string, i), code_points[i],
+ TEST_INT_EQ(runner, Str_Code_Point_At(string, i), code_points[i],
"Code_Point_At %ld", (long)i);
- TEST_INT_EQ(runner, CB_Code_Point_At(string, from),
+ TEST_INT_EQ(runner, Str_Code_Point_At(string, from),
code_points[from], "Code_Point_From %ld", (long)from);
}
@@ -139,10 +139,10 @@ test_Code_Point_At_and_From(TestBatchRunner *runner) {
static void
test_SubString(TestBatchRunner *runner) {
- CharBuf *string = CB_newf("a%s%sb%sc", smiley, smiley, smiley);
- CharBuf *wanted = CB_newf("%sb%s", smiley, smiley);
- CharBuf *got = CB_SubString(string, 2, 3);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "SubString");
+ String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
+ String *wanted = Str_newf("%sb%s", smiley, smiley);
+ String *got = Str_SubString(string, 2, 3);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "SubString");
DECREF(wanted);
DECREF(got);
DECREF(string);
@@ -150,23 +150,23 @@ test_SubString(TestBatchRunner *runner) {
static void
test_Nip_and_Chop(TestBatchRunner *runner) {
- CharBuf *wanted;
- CharBuf *string;
+ String *wanted;
+ String *string;
StackString *got;
- wanted = CB_newf("%sb%sc", smiley, smiley);
- string = CB_newf("a%s%sb%sc", smiley, smiley, smiley);
+ wanted = Str_newf("%sb%sc", smiley, smiley);
+ string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
got = SSTR_WRAP(string);
SStr_Nip(got, 2);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Nip");
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Nip");
DECREF(wanted);
DECREF(string);
- wanted = CB_newf("a%s%s", smiley, smiley);
- string = CB_newf("a%s%sb%sc", smiley, smiley, smiley);
+ wanted = Str_newf("a%s%s", smiley, smiley);
+ string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
got = SSTR_WRAP(string);
SStr_Chop(got, 3);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Chop");
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Chop");
DECREF(wanted);
DECREF(string);
}
@@ -174,10 +174,10 @@ test_Nip_and_Chop(TestBatchRunner *runner) {
static void
test_Truncate(TestBatchRunner *runner) {
- CharBuf *wanted = CB_newf("a%s", smiley, smiley);
- CharBuf *got = CB_newf("a%s%sb%sc", smiley, smiley, smiley);
- CB_Truncate(got, 2);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "Truncate");
+ String *wanted = Str_newf("a%s", smiley, smiley);
+ String *got = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
+ Str_Truncate(got, 2);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Truncate");
DECREF(wanted);
DECREF(got);
}
@@ -192,31 +192,31 @@ test_Trim(TestBatchRunner *runner) {
};
uint32_t num_spaces = sizeof(spaces) / sizeof(uint32_t);
uint32_t i;
- CharBuf *got = CB_new(0);
+ String *got = Str_new(0);
// Surround a smiley with lots of whitespace.
- for (i = 0; i < num_spaces; i++) { CB_Cat_Char(got, spaces[i]); }
- CB_Cat_Char(got, 0x263A);
- for (i = 0; i < num_spaces; i++) { CB_Cat_Char(got, spaces[i]); }
+ for (i = 0; i < num_spaces; i++) { Str_Cat_Char(got, spaces[i]); }
+ Str_Cat_Char(got, 0x263A);
+ for (i = 0; i < num_spaces; i++) { Str_Cat_Char(got, spaces[i]); }
- TEST_TRUE(runner, CB_Trim_Top(got), "Trim_Top returns true on success");
- TEST_FALSE(runner, CB_Trim_Top(got),
+ TEST_TRUE(runner, Str_Trim_Top(got), "Trim_Top returns true on success");
+ TEST_FALSE(runner, Str_Trim_Top(got),
"Trim_Top returns false on failure");
- TEST_TRUE(runner, CB_Trim_Tail(got), "Trim_Tail returns true on success");
- TEST_FALSE(runner, CB_Trim_Tail(got),
+ TEST_TRUE(runner, Str_Trim_Tail(got), "Trim_Tail returns true on success");
+ TEST_FALSE(runner, Str_Trim_Tail(got),
"Trim_Tail returns false on failure");
- TEST_TRUE(runner, CB_Equals_Str(got, smiley, smiley_len),
+ TEST_TRUE(runner, Str_Equals_Str(got, smiley, smiley_len),
"Trim_Top and Trim_Tail worked");
// Build the spacey smiley again.
- CB_Truncate(got, 0);
- for (i = 0; i < num_spaces; i++) { CB_Cat_Char(got, spaces[i]); }
- CB_Cat_Char(got, 0x263A);
- for (i = 0; i < num_spaces; i++) { CB_Cat_Char(got, spaces[i]); }
-
- TEST_TRUE(runner, CB_Trim(got), "Trim returns true on success");
- TEST_FALSE(runner, CB_Trim(got), "Trim returns false on failure");
- TEST_TRUE(runner, CB_Equals_Str(got, smiley, smiley_len),
+ Str_Truncate(got, 0);
+ for (i = 0; i < num_spaces; i++) { Str_Cat_Char(got, spaces[i]); }
+ Str_Cat_Char(got, 0x263A);
+ for (i = 0; i < num_spaces; i++) { Str_Cat_Char(got, spaces[i]); }
+
+ TEST_TRUE(runner, Str_Trim(got), "Trim returns true on success");
+ TEST_FALSE(runner, Str_Trim(got), "Trim returns false on failure");
+ TEST_TRUE(runner, Str_Equals_Str(got, smiley, smiley_len),
"Trim worked");
DECREF(got);
@@ -224,24 +224,24 @@ test_Trim(TestBatchRunner *runner) {
static void
test_To_F64(TestBatchRunner *runner) {
- CharBuf *charbuf;
+ String *charbuf;
charbuf = S_get_cb("1.5");
- double difference = 1.5 - CB_To_F64(charbuf);
+ double difference = 1.5 - Str_To_F64(charbuf);
if (difference < 0) { difference = 0 - difference; }
TEST_TRUE(runner, difference < 0.001, "To_F64");
DECREF(charbuf);
charbuf = S_get_cb("-1.5");
- difference = 1.5 + CB_To_F64(charbuf);
+ difference = 1.5 + Str_To_F64(charbuf);
if (difference < 0) { difference = 0 - difference; }
TEST_TRUE(runner, difference < 0.001, "To_F64 negative");
DECREF(charbuf);
charbuf = S_get_cb("1.59");
- double value_full = CB_To_F64(charbuf);
- CB_Set_Size(charbuf, 3);
- double value_short = CB_To_F64(charbuf);
+ double value_full = Str_To_F64(charbuf);
+ Str_Set_Size(charbuf, 3);
+ double value_short = Str_To_F64(charbuf);
TEST_TRUE(runner, value_short < value_full,
"TO_F64 doesn't run past end of string");
DECREF(charbuf);
@@ -249,45 +249,45 @@ test_To_F64(TestBatchRunner *runner) {
static void
test_To_I64(TestBatchRunner *runner) {
- CharBuf *charbuf;
+ String *charbuf;
charbuf = S_get_cb("10");
- TEST_TRUE(runner, CB_To_I64(charbuf) == 10, "To_I64");
+ TEST_TRUE(runner, Str_To_I64(charbuf) == 10, "To_I64");
DECREF(charbuf);
charbuf = S_get_cb("-10");
- TEST_TRUE(runner, CB_To_I64(charbuf) == -10, "To_I64 negative");
+ TEST_TRUE(runner, Str_To_I64(charbuf) == -10, "To_I64 negative");
DECREF(charbuf);
}
static void
test_vcatf_s(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar bizzle baz");
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %s baz", "bizzle");
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%s");
+ String *wanted = S_get_cb("foo bar bizzle baz");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %s baz", "bizzle");
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%s");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_null_string(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar [NULL] baz");
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %s baz", NULL);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%s NULL");
+ String *wanted = S_get_cb("foo bar [NULL] baz");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %s baz", NULL);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%s NULL");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_cb(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar ZEKE baz");
- CharBuf *catworthy = S_get_cb("ZEKE");
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %o baz", catworthy);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%o CharBuf");
+ String *wanted = S_get_cb("foo bar ZEKE baz");
+ String *catworthy = S_get_cb("ZEKE");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %o baz", catworthy);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%o String");
DECREF(catworthy);
DECREF(wanted);
DECREF(got);
@@ -295,11 +295,11 @@ test_vcatf_cb(TestBatchRunner *runner) {
static void
test_vcatf_obj(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("ooga 20 booga");
+ String *wanted = S_get_cb("ooga 20 booga");
Integer32 *i32 = Int32_new(20);
- CharBuf *got = S_get_cb("ooga");
- CB_catf(got, " %o booga", i32);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%o Obj");
+ String *got = S_get_cb("ooga");
+ Str_catf(got, " %o booga", i32);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%o Obj");
DECREF(i32);
DECREF(wanted);
DECREF(got);
@@ -307,108 +307,108 @@ test_vcatf_obj(TestBatchRunner *runner) {
static void
test_vcatf_null_obj(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar [NULL] baz");
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %o baz", NULL);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%o NULL");
+ String *wanted = S_get_cb("foo bar [NULL] baz");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %o baz", NULL);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%o NULL");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_i8(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar -3 baz");
+ String *wanted = S_get_cb("foo bar -3 baz");
int8_t num = -3;
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %i8 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%i8");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %i8 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%i8");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_i32(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar -100000 baz");
+ String *wanted = S_get_cb("foo bar -100000 baz");
int32_t num = -100000;
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %i32 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%i32");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %i32 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%i32");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_i64(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar -5000000000 baz");
+ String *wanted = S_get_cb("foo bar -5000000000 baz");
int64_t num = INT64_C(-5000000000);
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %i64 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%i64");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %i64 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%i64");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_u8(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar 3 baz");
+ String *wanted = S_get_cb("foo bar 3 baz");
uint8_t num = 3;
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %u8 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%u8");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %u8 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%u8");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_u32(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar 100000 baz");
+ String *wanted = S_get_cb("foo bar 100000 baz");
uint32_t num = 100000;
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %u32 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%u32");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %u32 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%u32");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_u64(TestBatchRunner *runner) {
- CharBuf *wanted = S_get_cb("foo bar 5000000000 baz");
+ String *wanted = S_get_cb("foo bar 5000000000 baz");
uint64_t num = UINT64_C(5000000000);
- CharBuf *got = S_get_cb("foo ");
- CB_catf(got, "bar %u64 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%u64");
+ String *got = S_get_cb("foo ");
+ Str_catf(got, "bar %u64 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%u64");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_f64(TestBatchRunner *runner) {
- CharBuf *wanted;
+ String *wanted;
char buf[64];
float num = 1.3f;
- CharBuf *got = S_get_cb("foo ");
+ String *got = S_get_cb("foo ");
sprintf(buf, "foo bar %g baz", num);
- wanted = CB_new_from_trusted_utf8(buf, strlen(buf));
- CB_catf(got, "bar %f64 baz", num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%f64");
+ wanted = Str_new_from_trusted_utf8(buf, strlen(buf));
+ Str_catf(got, "bar %f64 baz", num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%f64");
DECREF(wanted);
DECREF(got);
}
static void
test_vcatf_x32(TestBatchRunner *runner) {
- CharBuf *wanted;
+ String *wanted;
char buf[64];
unsigned long num = INT32_MAX;
- CharBuf *got = S_get_cb("foo ");
+ String *got = S_get_cb("foo ");
#if (SIZEOF_LONG == 4)
sprintf(buf, "foo bar %.8lx baz", num);
#elif (SIZEOF_INT == 4)
sprintf(buf, "foo bar %.8x baz", (unsigned)num);
#endif
- wanted = CB_new_from_trusted_utf8(buf, strlen(buf));
- CB_catf(got, "bar %x32 baz", (uint32_t)num);
- TEST_TRUE(runner, CB_Equals(wanted, (Obj*)got), "%%x32");
+ wanted = Str_new_from_trusted_utf8(buf, strlen(buf));
+ Str_catf(got, "bar %x32 baz", (uint32_t)num);
+ TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "%%x32");
DECREF(wanted);
DECREF(got);
}
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestErr.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestErr.c b/clownfish/runtime/core/Clownfish/Test/TestErr.c
index bc4f434..5627d7d 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestErr.c
+++ b/clownfish/runtime/core/Clownfish/Test/TestErr.c
@@ -19,7 +19,7 @@
#include "Clownfish/Test/TestErr.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Err.h"
#include "Clownfish/Test.h"
#include "Clownfish/TestHarness/TestBatchRunner.h"
@@ -32,10 +32,10 @@ TestErr_new() {
static void
test_To_String(TestBatchRunner *runner) {
- CharBuf *message = CB_newf("oops");
+ String *message = Str_newf("oops");
Err *error = Err_new(message);
- CharBuf *string = Err_To_String(error);
- TEST_TRUE(runner, CB_Equals(message, (Obj*)string),
+ String *string = Err_To_String(error);
+ TEST_TRUE(runner, Str_Equals(message, (Obj*)string),
"Stringifies as message");
DECREF(string);
DECREF(error);
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestHash.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestHash.c b/clownfish/runtime/core/Clownfish/Test/TestHash.c
index d90dba1..1e5bfcd 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestHash.c
+++ b/clownfish/runtime/core/Clownfish/Test/TestHash.c
@@ -22,7 +22,7 @@
#include "Clownfish/Test/TestHash.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Hash.h"
#include "Clownfish/Num.h"
#include "Clownfish/Test.h"
@@ -73,7 +73,7 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
StackString *foo = SSTR_WRAP_STR("foo", 3);
for (int32_t i = 0; i < 100; i++) {
- CharBuf *cb = CB_newf("%i32", i);
+ String *cb = Str_newf("%i32", i);
Hash_Store(hash, (Obj*)cb, (Obj*)cb);
Hash_Store(dupe, (Obj*)cb, INCREF(cb));
VA_Push(expected, INCREF(cb));
@@ -135,7 +135,7 @@ test_Keys_Values_Iter(TestBatchRunner *runner) {
VArray *values;
for (uint32_t i = 0; i < 500; i++) {
- CharBuf *cb = CB_newf("%u32", i);
+ String *cb = Str_newf("%u32", i);
Hash_Store(hash, (Obj*)cb, (Obj*)cb);
VA_Push(expected, INCREF(cb));
}
@@ -190,7 +190,7 @@ test_stress(TestBatchRunner *runner) {
VArray *values;
for (uint32_t i = 0; i < 1000; i++) {
- CharBuf *cb = TestUtils_random_string(rand() % 1200);
+ String *cb = TestUtils_random_string(rand() % 1200);
while (Hash_Fetch(hash, (Obj*)cb)) {
DECREF(cb);
cb = TestUtils_random_string(rand() % 1200);
@@ -203,7 +203,7 @@ test_stress(TestBatchRunner *runner) {
// Overwrite for good measure.
for (uint32_t i = 0; i < 1000; i++) {
- CharBuf *cb = (CharBuf*)VA_Fetch(expected, i);
+ String *cb = (String*)VA_Fetch(expected, i);
Hash_Store(hash, (Obj*)cb, INCREF(cb));
}
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.c b/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
index 69f827b..515db9a 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
+++ b/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
@@ -36,7 +36,7 @@ TestLFReg_new() {
StupidHashCharBuf*
StupidHashCharBuf_new(const char *text) {
- return (StupidHashCharBuf*)CB_new_from_utf8(text, strlen(text));
+ return (StupidHashCharBuf*)Str_new_from_utf8(text, strlen(text));
}
int32_t
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh b/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
index 039c573..80db8af 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
+++ b/clownfish/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
@@ -28,7 +28,7 @@ class Clownfish::Test::TestLockFreeRegistry cnick TestLFReg
/** Private test-only class for stressing LockFreeRegistry.
*/
-class Clownfish::Test::StupidHashCharBuf inherits Clownfish::CharBuf {
+class Clownfish::Test::StupidHashCharBuf inherits Clownfish::String {
inert incremented StupidHashCharBuf*
new(const char *text);
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestNum.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestNum.c b/clownfish/runtime/core/Clownfish/Test/TestNum.c
index a1a95eb..0334aac 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestNum.c
+++ b/clownfish/runtime/core/Clownfish/Test/TestNum.c
@@ -19,7 +19,7 @@
#include "Clownfish/Test/TestNum.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Num.h"
#include "Clownfish/Test.h"
#include "Clownfish/TestHarness/TestBatchRunner.h"
@@ -37,24 +37,24 @@ test_To_String(TestBatchRunner *runner) {
Float64 *f64 = Float64_new(1.33);
Integer32 *i32 = Int32_new(INT32_MAX);
Integer64 *i64 = Int64_new(INT64_MAX);
- CharBuf *f32_string = Float32_To_String(f32);
- CharBuf *f64_string = Float64_To_String(f64);
- CharBuf *i32_string = Int32_To_String(i32);
- CharBuf *i64_string = Int64_To_String(i64);
- CharBuf *true_string = Bool_To_String(CFISH_TRUE);
- CharBuf *false_string = Bool_To_String(CFISH_FALSE);
-
- TEST_TRUE(runner, CB_Starts_With_Str(f32_string, "1.3", 3),
+ String *f32_string = Float32_To_String(f32);
+ String *f64_string = Float64_To_String(f64);
+ String *i32_string = Int32_To_String(i32);
+ String *i64_string = Int64_To_String(i64);
+ String *true_string = Bool_To_String(CFISH_TRUE);
+ String *false_string = Bool_To_String(CFISH_FALSE);
+
+ TEST_TRUE(runner, Str_Starts_With_Str(f32_string, "1.3", 3),
"Float32_To_String");
- TEST_TRUE(runner, CB_Starts_With_Str(f64_string, "1.3", 3),
+ TEST_TRUE(runner, Str_Starts_With_Str(f64_string, "1.3", 3),
"Float64_To_String");
- TEST_TRUE(runner, CB_Equals_Str(i32_string, "2147483647", 10),
+ TEST_TRUE(runner, Str_Equals_Str(i32_string, "2147483647", 10),
"Int32_To_String");
- TEST_TRUE(runner, CB_Equals_Str(i64_string, "9223372036854775807", 19),
+ TEST_TRUE(runner, Str_Equals_Str(i64_string, "9223372036854775807", 19),
"Int64_To_String");
- TEST_TRUE(runner, CB_Equals_Str(true_string, "true", 4),
+ TEST_TRUE(runner, Str_Equals_Str(true_string, "true", 4),
"Bool_To_String [true]");
- TEST_TRUE(runner, CB_Equals_Str(false_string, "false", 5),
+ TEST_TRUE(runner, Str_Equals_Str(false_string, "false", 5),
"Bool_To_String [false]");
DECREF(false_string);
@@ -200,7 +200,7 @@ test_Equals_and_Compare_To(TestBatchRunner *runner) {
"CFISH_FALSE not Equals CFISH_TRUE ");
TEST_FALSE(runner, Bool_Equals(CFISH_TRUE, (Obj*)CFISH_FALSE),
"CFISH_TRUE not Equals CFISH_FALSE ");
- TEST_FALSE(runner, Bool_Equals(CFISH_TRUE, (Obj*)CHARBUF),
+ TEST_FALSE(runner, Bool_Equals(CFISH_TRUE, (Obj*)STRING),
"CFISH_TRUE not Equals random other object ");
DECREF(i64_copy);
http://git-wip-us.apache.org/repos/asf/lucy/blob/2c3dbf15/clownfish/runtime/core/Clownfish/Test/TestObj.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/Test/TestObj.c b/clownfish/runtime/core/Clownfish/Test/TestObj.c
index b22add7..0d951be 100644
--- a/clownfish/runtime/core/Clownfish/Test/TestObj.c
+++ b/clownfish/runtime/core/Clownfish/Test/TestObj.c
@@ -24,7 +24,7 @@
#include "Clownfish/Test/TestObj.h"
-#include "Clownfish/CharBuf.h"
+#include "Clownfish/String.h"
#include "Clownfish/Err.h"
#include "Clownfish/Test.h"
#include "Clownfish/TestHarness/TestBatchRunner.h"
@@ -39,9 +39,9 @@ static Obj*
S_new_testobj() {
StackString *klass = SSTR_WRAP_STR("TestObj", 7);
Obj *obj;
- VTable *vtable = VTable_fetch_vtable((CharBuf*)klass);
+ VTable *vtable = VTable_fetch_vtable((String*)klass);
if (!vtable) {
- vtable = VTable_singleton((CharBuf*)klass, OBJ);
+ vtable = VTable_singleton((String*)klass, OBJ);
}
obj = VTable_Make_Obj(vtable);
return Obj_init(obj);
@@ -66,7 +66,7 @@ test_refcounts(TestBatchRunner *runner) {
static void
test_To_String(TestBatchRunner *runner) {
Obj *testobj = S_new_testobj();
- CharBuf *string = Obj_To_String(testobj);
+ String *string = Obj_To_String(testobj);
StackString *temp = SSTR_WRAP(string);
while (SStr_Get_Size(temp)) {
if (SStr_Starts_With_Str(temp, "TestObj", 7)) { break; }
@@ -103,14 +103,14 @@ test_Hash_Sum(TestBatchRunner *runner) {
static void
test_Is_A(TestBatchRunner *runner) {
- CharBuf *charbuf = CB_new(0);
- VTable *bb_vtable = CB_Get_VTable(charbuf);
- CharBuf *klass = CB_Get_Class_Name(charbuf);
-
- TEST_TRUE(runner, CB_Is_A(charbuf, CHARBUF), "CharBuf Is_A CharBuf.");
- TEST_TRUE(runner, CB_Is_A(charbuf, OBJ), "CharBuf Is_A Obj.");
- TEST_TRUE(runner, bb_vtable == CHARBUF, "Get_VTable");
- TEST_TRUE(runner, CB_Equals(VTable_Get_Name(CHARBUF), (Obj*)klass),
+ String *charbuf = Str_new(0);
+ VTable *bb_vtable = Str_Get_VTable(charbuf);
+ String *klass = Str_Get_Class_Name(charbuf);
+
+ TEST_TRUE(runner, Str_Is_A(charbuf, STRING), "String Is_A String.");
+ TEST_TRUE(runner, Str_Is_A(charbuf, OBJ), "String Is_A Obj.");
+ TEST_TRUE(runner, bb_vtable == STRING, "Get_VTable");
+ TEST_TRUE(runner, Str_Equals(VTable_Get_Name(STRING), (Obj*)klass),
"Get_Class_Name");
DECREF(charbuf);
@@ -154,7 +154,7 @@ S_verify_abstract_error(TestBatchRunner *runner, Err_Attempt_t routine,
Err *error = Err_trap(routine, context);
TEST_TRUE(runner, error != NULL
&& Err_Is_A(error, ERR)
- && CB_Find_Str(Err_Get_Mess(error), "bstract", 7) != -1,
+ && Str_Find_Str(Err_Get_Mess(error), "bstract", 7) != -1,
message);
DECREF(error);
}