Просмотр исходного кода

ncd: Remove ComposedString type along with the buffer module.
It was a fancy feature, but with questionable utility and with a general maintenance burden.

Ambroz Bizjak 11 лет назад
Родитель
Сommit
98ed187623

+ 0 - 148
examples/ncdval_test.c

@@ -39,100 +39,6 @@
 
 #define FORCE(cmd) if (!(cmd)) { fprintf(stderr, "failed\n"); exit(1); }
 
-struct composed_string {
-    BRefTarget ref_target;
-    size_t length;
-    size_t chunk_size;
-    char **chunks;
-};
-
-static void composed_string_ref_target_func_release (BRefTarget *ref_target)
-{
-    struct composed_string *cs = UPPER_OBJECT(ref_target, struct composed_string, ref_target);
-    
-    size_t num_chunks = cs->length / cs->chunk_size;
-    if (cs->length % cs->chunk_size) {
-        num_chunks++;
-    }
-    
-    for (size_t i = 0; i < num_chunks; i++) {
-        BFree(cs->chunks[i]);
-    }
-    
-    BFree(cs->chunks);
-    BFree(cs);
-}
-
-static void composed_string_func_getptr (void *user, size_t offset, const char **out_data, size_t *out_length)
-{
-    struct composed_string *cs = user;
-    ASSERT(offset < cs->length)
-    
-    *out_data = cs->chunks[offset / cs->chunk_size] + (offset % cs->chunk_size);
-    *out_length = cs->chunk_size - (offset % cs->chunk_size);
-}
-
-static NCDValRef build_composed_string (NCDValMem *mem, const char *data, size_t length, size_t chunk_size)
-{
-    ASSERT(chunk_size > 0)
-    
-    struct composed_string *cs = BAlloc(sizeof(*cs));
-    if (!cs) {
-        goto fail0;
-    }
-    
-    cs->length = length;
-    cs->chunk_size = chunk_size;
-    
-    size_t num_chunks = cs->length / cs->chunk_size;
-    if (cs->length % cs->chunk_size) {
-        num_chunks++;
-    }
-    
-    cs->chunks = BAllocArray(num_chunks, sizeof(cs->chunks[0]));
-    if (!cs->chunk_size) {
-        goto fail1;
-    }
-    
-    size_t i;
-    for (i = 0; i < num_chunks; i++) {
-        cs->chunks[i] = BAlloc(cs->chunk_size);
-        if (!cs->chunks[i]) {
-            goto fail2;
-        }
-        
-        size_t to_copy = length;
-        if (to_copy > cs->chunk_size) {
-            to_copy = cs->chunk_size;
-        }
-        
-        memcpy(cs->chunks[i], data, to_copy);
-        data += to_copy;
-        length -= to_copy;
-    }
-    
-    BRefTarget_Init(&cs->ref_target, composed_string_ref_target_func_release);
-    
-    NCDValComposedStringResource resource;
-    resource.func_getptr = composed_string_func_getptr;
-    resource.user = cs;
-    resource.ref_target = &cs->ref_target;
-    
-    NCDValRef val = NCDVal_NewComposedString(mem, resource, 0, cs->length);
-    BRefTarget_Deref(&cs->ref_target);
-    return val;
-    
-fail2:
-    while (i-- > 0) {
-        BFree(cs->chunks[i]);
-    }
-    BFree(cs->chunks);
-fail1:
-    BFree(cs);
-fail0:
-    return NCDVal_NewInvalid();
-}
-
 static void test_string (NCDValRef str, const char *data, size_t length)
 {
     FORCE( !NCDVal_IsInvalid(str) )
@@ -320,60 +226,6 @@ int main ()
     
     NCDValMem_Free(&mem);
     
-    NCDValMem_Init(&mem);
-    
-    NCDValRef cstr1 = build_composed_string(&mem, "Hello World", 11, 3);
-    test_string(cstr1, "Hello World", 11);
-    FORCE( NCDVal_IsComposedString(cstr1) )
-    FORCE( !NCDVal_IsContinuousString(cstr1) )
-    FORCE( NCDVal_StringEquals(cstr1, "Hello World") )
-    FORCE( !NCDVal_StringEquals(cstr1, "Hello World ") )
-    FORCE( !NCDVal_StringEquals(cstr1, "Hello WorlD") )
-    
-    NCDValRef cstr2 = build_composed_string(&mem, "GoodBye", 7, 1);
-    test_string(cstr2, "GoodBye", 7);
-    FORCE( NCDVal_IsComposedString(cstr2) )
-    FORCE( !NCDVal_IsContinuousString(cstr2) )
-    FORCE( NCDVal_StringEquals(cstr2, "GoodBye") )
-    FORCE( !NCDVal_StringEquals(cstr2, " GoodBye") )
-    FORCE( !NCDVal_StringEquals(cstr2, "goodBye") )
-    
-    NCDValRef cstr3 = build_composed_string(&mem, "Bad\x00String", 10, 4);
-    test_string(cstr3, "Bad\x00String", 10);
-    FORCE( NCDVal_IsComposedString(cstr3) )
-    FORCE( !NCDVal_IsContinuousString(cstr3) )
-    
-    FORCE( NCDVal_StringMemCmp(cstr1, cstr2, 1, 2, 3) < 0 )
-    FORCE( NCDVal_StringMemCmp(cstr1, cstr2, 7, 1, 4) > 0 )
-    
-    char buf[10];
-    NCDVal_StringCopyOut(cstr1, 1, 10, buf);
-    FORCE( !memcmp(buf, "ello World", 10) )
-    
-    NCDValRef clist1 = NCDVal_NewList(&mem, 3);
-    FORCE( !NCDVal_IsInvalid(clist1) )
-    FORCE( NCDVal_ListAppend(clist1, cstr1) )
-    FORCE( NCDVal_ListAppend(clist1, cstr2) )
-    FORCE( NCDVal_ListAppend(clist1, cstr3) )
-    FORCE( NCDVal_ListCount(clist1) == 3 )
-    
-    FORCE( NCDValMem_ConvertNonContinuousStrings(&mem, &clist1) )
-    FORCE( NCDVal_ListCount(clist1) == 3 )
-    
-    NCDValRef fixed_str1 = NCDVal_ListGet(clist1, 0);
-    NCDValRef fixed_str2 = NCDVal_ListGet(clist1, 1);
-    NCDValRef fixed_str3 = NCDVal_ListGet(clist1, 2);
-    
-    FORCE( NCDVal_IsContinuousString(fixed_str1) )
-    FORCE( NCDVal_IsContinuousString(fixed_str2) )
-    FORCE( NCDVal_IsContinuousString(fixed_str3) )
-    
-    test_string(fixed_str1, "Hello World", 11);
-    test_string(fixed_str2, "GoodBye", 7);
-    test_string(fixed_str3, "Bad\x00String", 10);
-    
-    NCDValMem_Free(&mem);
-    
     NCDStringIndex_Free(&string_index);
     
     return 0;

+ 0 - 1
ncd/CMakeLists.txt

@@ -145,7 +145,6 @@ set(NCDINTERPRETER_SOURCES
     modules/depend_scope.c
     modules/substr.c
     modules/log.c
-    modules/buffer.c
     modules/getenv.c
     modules/basic_functions.c
     ${NCD_ADDITIONAL_SOURCES}

+ 0 - 8
ncd/NCDInterpreter.c

@@ -925,14 +925,6 @@ void process_advance (struct process *p)
         goto fail0;
     }
     
-    // convert non-continuous strings unless the module can handle them
-    if (!(module->module.flags & NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS)) {
-        if (!NCDValMem_ConvertNonContinuousStrings(&ps->args_mem, &args)) {
-            STATEMENT_LOG(ps, BLOG_ERROR, "NCDValMem_ConvertNonContinuousStrings failed");
-            goto fail1;
-        }
-    }
-    
     // allocate memory
     if (!statement_allocate_memory(ps, module->module.alloc_size)) {
         STATEMENT_LOG(ps, BLOG_ERROR, "failed to allocate memory");

+ 1 - 8
ncd/NCDModule.c

@@ -431,14 +431,7 @@ int NCDModuleProcess_InitValue (NCDModuleProcess *o, NCDModuleInst *n, NCDValRef
     if (NCDVal_IsIdString(template_name)) {
         template_name_id = NCDVal_IdStringId(template_name);
     } else {
-        NCDValContString cts;
-        if (!NCDVal_StringContinuize(template_name, &cts)) {
-            BLog(BLOG_ERROR, "NCDVal_StringContinuize failed");
-            return 0;
-        }
-        
-        template_name_id = NCDStringIndex_GetBin(n->params->iparams->string_index, cts.data, NCDVal_StringLength(template_name));
-        NCDValContString_Free(&cts);
+        template_name_id = NCDStringIndex_GetBin(n->params->iparams->string_index, NCDVal_StringData(template_name), NCDVal_StringLength(template_name));
         if (template_name_id < 0) {
             BLog(BLOG_ERROR, "NCDStringIndex_GetBin failed");
             return 0;

+ 2 - 14
ncd/NCDModule.h

@@ -261,9 +261,7 @@ struct NCDModuleInst_new_params {
     /**
      * A reference to the argument list for the module instance.
      * The reference remains valid as long as the backend instance
-     * exists. Unless the module has the NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
-     * flag set, it is guaranteed that any strings within the arguments will be
-     * some kind of ContinuousString.
+     * exists.
      */
     NCDValRef args;
     
@@ -424,10 +422,7 @@ typedef struct NCDModuleProcess_s {
  *                       The caller must ensure that the NCDObject that was used is of the type
  *                       expected by the module being instanciated.
  * @param args arguments to the module. Must be a list value. Must be available and unchanged
- *             as long as the instance exists. Unless the module has the
- *             NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS flag set, any strings within the
- *             arguments must be some kind of ContinuousString. This can be ensured by calling
- *             {@link NCDValMem_ConvertNonContinuousStrings}.
+ *             as long as the instance exists.
  * @param user argument to callback functions
  * @param params more parameters, see {@link NCDModuleInst_params}
  */
@@ -850,7 +845,6 @@ typedef int (*NCDModule_func_getobj) (void *o, NCD_string_id_t name, NCDObject *
 typedef void (*NCDModule_func_clean) (void *o);
 
 #define NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN (1 << 0)
-#define NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS (1 << 1)
 
 /**
  * Structure encapsulating the implementation of a module backend.
@@ -912,12 +906,6 @@ struct NCDModule {
      *   Whether the interpreter is allowed to call func_getvar and func_getobj
      *   even when the backend instance is in down state (as opposed to just
      *   in up state.
-     * 
-     * - NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
-     *   If not set, strings within arguments which are not some kind of ContinuousString
-     *   will be converted to some kind of ContinuousString before the module's init
-     *   function is called. If set, they will not be, and the module must work with any
-     *   kind of strings (i.e. {@link NCDVal_StringData} may not be allowed).
      */
     int flags;
     

+ 8 - 438
ncd/NCDVal.c

@@ -53,7 +53,6 @@
 #define STOREDSTRING_TYPE (NCDVAL_STRING | (0 << 3))
 #define IDSTRING_TYPE (NCDVAL_STRING | (1 << 3))
 #define EXTERNALSTRING_TYPE (NCDVAL_STRING | (2 << 3))
-#define COMPOSEDSTRING_TYPE (NCDVAL_STRING | (3 << 3))
 
 #define NCDVAL_INSTR_PLACEHOLDER 0
 #define NCDVAL_INSTR_REINSERT 1
@@ -98,20 +97,6 @@ struct NCDVal__externalstring {
     struct NCDVal__ref ref;
 };
 
-struct NCDVal__composedstring {
-    int type;
-    size_t offset;
-    size_t length;
-    void (*func_getptr) (void *, size_t, const char **, size_t *);
-    void *user;
-    struct NCDVal__ref ref;
-};
-
-struct NCDVal__cms_link {
-    NCDVal__idx link_idx;
-    NCDVal__idx next_cms_link;
-};
-
 typedef struct NCDVal__mapelem NCDVal__maptree_entry;
 typedef NCDValMem *NCDVal__maptree_arg;
 
@@ -150,8 +135,7 @@ static int make_type (int internal_type, int depth)
            internal_type == NCDVAL_MAP ||
            internal_type == STOREDSTRING_TYPE ||
            internal_type == IDSTRING_TYPE ||
-           internal_type == EXTERNALSTRING_TYPE ||
-           internal_type == COMPOSEDSTRING_TYPE)
+           internal_type == EXTERNALSTRING_TYPE)
     ASSERT(depth >= 0)
     ASSERT(depth <= NCDVAL_MAX_DEPTH)
     
@@ -316,13 +300,6 @@ static void NCDVal__AssertValOnly (NCDValMem *mem, NCDVal__idx idx)
             ASSERT(!exs_e->ref.target || exs_e->ref.next >= -1)
             ASSERT(!exs_e->ref.target || exs_e->ref.next < mem->used)
         } break;
-        case COMPOSEDSTRING_TYPE: {
-            ASSERT(idx + sizeof(struct NCDVal__composedstring) <= mem->used)
-            struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(mem, idx);
-            ASSERT(cms_e->func_getptr)
-            ASSERT(!cms_e->ref.target || cms_e->ref.next >= -1)
-            ASSERT(!cms_e->ref.target || cms_e->ref.next < mem->used)
-        } break;
         default: ASSERT(0);
     }
 #endif
@@ -383,39 +360,6 @@ static int NCDVal__Depth (NCDValRef val)
     return depth;
 }
 
-static int NCDValMem__NeedRegisterLink (NCDValMem *mem, NCDVal__idx val_idx)
-{
-    NCDVal__AssertValOnly(mem, val_idx);
-    
-    return !(val_idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(mem, val_idx)) == COMPOSEDSTRING_TYPE;
-}
-
-static int NCDValMem__RegisterLink (NCDValMem *mem, NCDVal__idx val_idx, NCDVal__idx link_idx)
-{
-    NCDVal__AssertValOnly(mem, val_idx);
-    ASSERT(NCDValMem__NeedRegisterLink(mem, val_idx))
-    
-    NCDVal__idx cms_link_idx = NCDValMem__Alloc(mem, sizeof(struct NCDVal__cms_link), __alignof(struct NCDVal__cms_link));
-    if (cms_link_idx < 0) {
-        return 0;
-    }
-    
-    struct NCDVal__cms_link *cms_link = NCDValMem__BufAt(mem, cms_link_idx);
-    cms_link->link_idx = link_idx;
-    cms_link->next_cms_link = mem->first_cms_link;
-    mem->first_cms_link = cms_link_idx;
-    
-    return 1;
-}
-
-static void NCDValMem__PopLastRegisteredLink (NCDValMem *mem)
-{
-    ASSERT(mem->first_cms_link != -1)
-    
-    struct NCDVal__cms_link *cms_link = NCDValMem__BufAt(mem, mem->first_cms_link);
-    mem->first_cms_link = cms_link->next_cms_link;
-}
-
 static void NCDValMem__RegisterRef (NCDValMem *o, NCDVal__idx refidx, struct NCDVal__ref *ref)
 {
     ASSERT(ref == NCDValMem__BufAt(o, refidx))
@@ -425,55 +369,6 @@ static void NCDValMem__RegisterRef (NCDValMem *o, NCDVal__idx refidx, struct NCD
     o->first_ref = refidx;
 }
 
-static NCDValRef NCDVal__CopyComposedStringToStored (NCDValRef val)
-{
-    ASSERT(NCDVal_IsComposedString(val))
-    
-    struct NCDVal__composedstring cms_e = *(struct NCDVal__composedstring *)NCDValMem__BufAt(val.mem, val.idx);
-    
-    NCDValRef copy = NCDVal_NewStringUninitialized(val.mem, cms_e.length);
-    if (NCDVal_IsInvalid(copy)) {
-        return NCDVal_NewInvalid();
-    }
-    
-    char *copy_data = (char *)NCDVal_StringData(copy);
-    
-    size_t pos = 0;
-    while (pos < cms_e.length) {
-        const char *chunk_data;
-        size_t chunk_len;
-        cms_e.func_getptr(cms_e.user, cms_e.offset + pos, &chunk_data, &chunk_len);
-        ASSERT(chunk_data)
-        ASSERT(chunk_len > 0)
-        if (chunk_len > cms_e.length - pos) {
-            chunk_len = cms_e.length - pos;
-        }
-        memcpy(copy_data + pos, chunk_data, chunk_len);
-        pos += chunk_len;
-    }
-    
-    return copy;
-}
-
-static const char * NCDVal__composedstring_cstring_func (const b_cstring *cstr, size_t offset, size_t *out_length)
-{
-    ASSERT(offset < cstr->length)
-    ASSERT(out_length)
-    ASSERT(cstr->func == NCDVal__composedstring_cstring_func)
-    
-    size_t str_offset = cstr->user1.size;
-    NCDVal_ComposedString_func_getptr func_getptr = (NCDVal_ComposedString_func_getptr)cstr->user2.fptr;
-    void *user = cstr->user3.ptr;
-    
-    const char *data;
-    func_getptr(user, str_offset + offset, &data, out_length);
-    
-    ASSERT(data)
-    ASSERT(*out_length > 0)
-    
-    return data;
-}
-
 #include "NCDVal_maptree.h"
 #include <structure/CAvl_impl.h>
 
@@ -483,7 +378,6 @@ void NCDValMem_Init (NCDValMem *o)
     o->size = NCDVAL_FASTBUF_SIZE;
     o->used = 0;
     o->first_ref = -1;
-    o->first_cms_link = -1;
 }
 
 void NCDValMem_Free (NCDValMem *o)
@@ -510,7 +404,6 @@ int NCDValMem_InitCopy (NCDValMem *o, NCDValMem *other)
     o->size = other->size;
     o->used = other->used;
     o->first_ref = other->first_ref;
-    o->first_cms_link = other->first_cms_link;
     
     if (!other->buf) {
         o->buf = NULL;
@@ -549,41 +442,6 @@ fail0:
     return 0;
 }
 
-int NCDValMem_ConvertNonContinuousStrings (NCDValMem *o, NCDValRef *root_val)
-{
-    NCDVal__AssertMem(o);
-    ASSERT(root_val)
-    ASSERT(root_val->mem == o)
-    NCDVal__AssertValOnly(o, root_val->idx);
-    
-    while (o->first_cms_link != -1) {
-        struct NCDVal__cms_link cms_link = *(struct NCDVal__cms_link *)NCDValMem__BufAt(o, o->first_cms_link);
-        
-        NCDVal__idx val_idx = *(NCDVal__idx *)NCDValMem__BufAt(o, cms_link.link_idx);
-        NCDValRef val = NCDVal__Ref(o, val_idx);
-        ASSERT(NCDVal_IsComposedString(val))
-        
-        NCDValRef copy = NCDVal__CopyComposedStringToStored(val);
-        if (NCDVal_IsInvalid(copy)) {
-            return 0;
-        }
-        
-        *(int *)NCDValMem__BufAt(o, cms_link.link_idx) = copy.idx;
-        
-        o->first_cms_link = cms_link.next_cms_link;
-    }
-    
-    if (NCDVal_IsComposedString(*root_val)) {
-        NCDValRef copy = NCDVal__CopyComposedStringToStored(*root_val);
-        if (NCDVal_IsInvalid(copy)) {
-            return 0;
-        }
-        *root_val = copy;
-    }
-    
-    return 1;
-}
-
 void NCDVal_Assert (NCDValRef val)
 {
     ASSERT(val.idx == -1 || (NCDVal__AssertVal(val), 1))
@@ -690,12 +548,6 @@ NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val)
                     goto fail;
                 }
                 
-                if (NCDValMem__NeedRegisterLink(mem, elem_copy.idx)) {
-                    if (!NCDValMem__RegisterLink(mem, elem_copy.idx, idx + offsetof(struct NCDVal__list, elem_indices) + i * sizeof(NCDVal__idx))) {
-                        goto fail;
-                    }
-                }
-                
                 list_e = NCDValMem__BufAt(val.mem, val.idx);
                 new_list_e = NCDValMem__BufAt(mem, idx);
                 
@@ -751,17 +603,6 @@ NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val)
             return NCDVal_NewExternalString(mem, exs_e->data, exs_e->length, exs_e->ref.target);
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            struct NCDVal__composedstring *cms_e = ptr;
-            
-            NCDValComposedStringResource resource;
-            resource.func_getptr = cms_e->func_getptr;
-            resource.user = cms_e->user;
-            resource.ref_target = cms_e->ref.target;
-            
-            return NCDVal_NewComposedString(mem, resource, cms_e->offset, cms_e->length);
-        } break;
-        
         default: ASSERT(0);
     }
     
@@ -898,47 +739,6 @@ int NCDVal_GetSafeRefPlaceholderId (NCDValSafeRef sval)
     return (sval.idx - NCDVAL_MINIDX);
 }
 
-int NCDVal_HasOnlyContinuousStrings (NCDValRef val)
-{
-    NCDVal__AssertVal(val);
-    
-    switch (NCDVal_Type(val)) {
-        case NCDVAL_STRING: {
-            if (!NCDVal_IsContinuousString(val)) {
-                return 0;
-            }
-        } break;
-        
-        case NCDVAL_LIST: {
-            size_t count = NCDVal_ListCount(val);
-            for (size_t i = 0; i < count; i++) {
-                NCDValRef elem = NCDVal_ListGet(val, i);
-                if (!NCDVal_HasOnlyContinuousStrings(elem)) {
-                    return 0;
-                }
-            }
-        } break;
-        
-        case NCDVAL_MAP: {
-            for (NCDValMapElem me = NCDVal_MapFirst(val); !NCDVal_MapElemInvalid(me); me = NCDVal_MapNext(val, me)) {
-                NCDValRef e_key = NCDVal_MapElemKey(val, me);
-                NCDValRef e_val = NCDVal_MapElemVal(val, me);
-                if (!NCDVal_HasOnlyContinuousStrings(e_key) || !NCDVal_HasOnlyContinuousStrings(e_val)) {
-                    return 0;
-                }
-            }
-        } break;
-        
-        case NCDVAL_PLACEHOLDER: {
-        } break;
-        
-        default:
-            ASSERT(0);
-    }
-    
-    return 1;
-}
-
 int NCDVal_IsString (NCDValRef val)
 {
     NCDVal__AssertVal(val);
@@ -946,24 +746,6 @@ int NCDVal_IsString (NCDValRef val)
     return NCDVal_Type(val) == NCDVAL_STRING;
 }
 
-int NCDVal_IsContinuousString (NCDValRef val)
-{
-    NCDVal__AssertVal(val);
-    
-    if (val.idx < -1) {
-        return 0;
-    }
-    
-    switch (get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx))) {
-        case STOREDSTRING_TYPE:
-        case IDSTRING_TYPE:
-        case EXTERNALSTRING_TYPE:
-            return 1;
-        default:
-            return 0;
-    }
-}
-
 int NCDVal_IsStoredString (NCDValRef val)
 {
     NCDVal__AssertVal(val);
@@ -985,13 +767,6 @@ int NCDVal_IsExternalString (NCDValRef val)
     return !(val.idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx)) == EXTERNALSTRING_TYPE;
 }
 
-int NCDVal_IsComposedString (NCDValRef val)
-{
-    NCDVal__AssertVal(val);
-    
-    return !(val.idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx)) == COMPOSEDSTRING_TYPE;
-}
-
 int NCDVal_IsStringNoNulls (NCDValRef val)
 {
     NCDVal__AssertVal(val);
@@ -1121,46 +896,11 @@ fail:
     return NCDVal_NewInvalid();
 }
 
-NCDValRef NCDVal_NewComposedString (NCDValMem *mem, NCDValComposedStringResource resource, size_t offset, size_t length)
+const char * NCDVal_StringData (NCDValRef string)
 {
-    NCDVal__AssertMem(mem);
-    ASSERT(resource.func_getptr)
-    
-    NCDVal__idx size = sizeof(struct NCDVal__composedstring);
-    NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__composedstring));
-    if (idx < 0) {
-        goto fail;
-    }
-    
-    if (resource.ref_target) {
-        if (!BRefTarget_Ref(resource.ref_target)) {
-            goto fail;
-        }
-    }
-    
-    struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(mem, idx);
-    cms_e->type = make_type(COMPOSEDSTRING_TYPE, 0);
-    cms_e->offset = offset;
-    cms_e->length = length;
-    cms_e->func_getptr = resource.func_getptr;
-    cms_e->user = resource.user;
-    cms_e->ref.target = resource.ref_target;
-    
-    if (resource.ref_target) {
-        NCDValMem__RegisterRef(mem, idx + offsetof(struct NCDVal__composedstring, ref), &cms_e->ref);
-    }
-    
-    return NCDVal__Ref(mem, idx);
-    
-fail:
-    return NCDVal_NewInvalid();
-}
-
-const char * NCDVal_StringData (NCDValRef contstring)
-{
-    ASSERT(NCDVal_IsContinuousString(contstring))
+    ASSERT(NCDVal_IsString(string))
     
-    void *ptr = NCDValMem__BufAt(contstring.mem, contstring.idx);
+    void *ptr = NCDValMem__BufAt(string.mem, string.idx);
     
     switch (get_internal_type(*(int *)ptr)) {
         case STOREDSTRING_TYPE: {
@@ -1207,28 +947,12 @@ size_t NCDVal_StringLength (NCDValRef string)
             return exs_e->length;
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            struct NCDVal__composedstring *cms_e = ptr;
-            return cms_e->length;
-        } break;
-        
         default:
             ASSERT(0);
             return 0;
     }
 }
 
-b_cstring NCDValComposedStringResource_Cstring (NCDValComposedStringResource resource, size_t offset, size_t length)
-{
-    b_cstring cstr;
-    cstr.length = length;
-    cstr.func = NCDVal__composedstring_cstring_func;
-    cstr.user1.size = offset;
-    cstr.user2.fptr = (void (*) (void))resource.func_getptr;
-    cstr.user3.ptr = resource.user;
-    return cstr;
-}
-
 b_cstring NCDVal_StringCstring (NCDValRef string)
 {
     ASSERT(NCDVal_IsString(string))
@@ -1251,17 +975,6 @@ b_cstring NCDVal_StringCstring (NCDValRef string)
             return b_cstring_make_buf(exs_e->data, exs_e->length);
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            struct NCDVal__composedstring *cms_e = ptr;
-            b_cstring cstr;
-            cstr.length = cms_e->length;
-            cstr.func = NCDVal__composedstring_cstring_func;
-            cstr.user1.size = cms_e->offset;
-            cstr.user2.fptr = (void (*) (void))cms_e->func_getptr;
-            cstr.user3.ptr = cms_e->user;
-            return cstr;
-        } break;
-        
         default: {
             ASSERT(0);
             return b_cstring_make_empty();
@@ -1304,27 +1017,6 @@ int NCDVal_StringNullTerminate (NCDValRef string, NCDValNullTermString *out)
             return 1;
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            struct NCDVal__composedstring *cms_e = ptr;
-            size_t length = cms_e->length;
-            
-            if (length == SIZE_MAX) {
-                return 0;
-            }
-            
-            char *copy = BAlloc(length + 1);
-            if (!copy) {
-                return 0;
-            }
-            
-            NCDVal_StringCopyOut(string, 0, length, copy);
-            copy[length] = '\0';
-            
-            out->data = copy;
-            out->is_allocated = 1;
-            return 1;
-        } break;
-        
         default:
             ASSERT(0);
             return 0;
@@ -1346,46 +1038,6 @@ void NCDValNullTermString_Free (NCDValNullTermString *o)
     }
 }
 
-int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out)
-{
-    ASSERT(NCDVal_IsString(string))
-    ASSERT(out)
-    
-    if (NCDVal_IsContinuousString(string)) {
-        out->data = (char *)NCDVal_StringData(string);
-        out->is_allocated = 0;
-        return 1;
-    }
-    
-    size_t length = NCDVal_StringLength(string);
-    
-    char *data = BAlloc(length);
-    if (!data) {
-        return 0;
-    }
-    
-    NCDVal_StringCopyOut(string, 0, length, data);
-    
-    out->data = data;
-    out->is_allocated = 1;
-    return 1;
-}
-
-NCDValContString NCDValContString_NewDummy (void)
-{
-    NCDValContString cts;
-    cts.data = NULL;
-    cts.is_allocated = 0;
-    return cts;
-}
-
-void NCDValContString_Free (NCDValContString *o)
-{
-    if (o->is_allocated) {
-        BFree(o->data);
-    }
-}
-
 void NCDVal_IdStringGet (NCDValRef idstring, NCD_string_id_t *out_string_id,
                          NCDStringIndex **out_string_index)
 {
@@ -1422,29 +1074,6 @@ BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring)
     return exs_e->ref.target;
 }
 
-NCDValComposedStringResource NCDVal_ComposedStringResource (NCDValRef composedstring)
-{
-    ASSERT(NCDVal_IsComposedString(composedstring))
-    
-    struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(composedstring.mem, composedstring.idx);
-    
-    NCDValComposedStringResource res;
-    res.func_getptr = cms_e->func_getptr;
-    res.user = cms_e->user;
-    res.ref_target = cms_e->ref.target;
-    
-    return res;
-}
-
-size_t NCDVal_ComposedStringOffset (NCDValRef composedstring)
-{
-    ASSERT(NCDVal_IsComposedString(composedstring))
-    
-    struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(composedstring.mem, composedstring.idx);
-    
-    return cms_e->offset;
-}
-
 int NCDVal_StringHasNulls (NCDValRef string)
 {
     ASSERT(NCDVal_IsString(string))
@@ -1464,11 +1093,6 @@ int NCDVal_StringHasNulls (NCDValRef string)
             return !!memchr(data, '\0', length);
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            b_cstring cstr = NCDVal_StringCstring(string);
-            return b_cstring_memchr(cstr, 0, cstr.length, '\0', NULL);
-        } break;
-        
         default:
             ASSERT(0);
             return 0;
@@ -1515,13 +1139,6 @@ int NCDVal_StringEqualsId (NCDValRef string, NCD_string_id_t string_id,
             return (string_length == exs_e->length) && !memcmp(string_data, exs_e->data, string_length);
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            struct NCDVal__composedstring *cms_e = ptr;
-            const char *string_data = NCDStringIndex_Value(string_index, string_id);
-            size_t string_length = NCDStringIndex_Length(string_index, string_id);
-            return (string_length == cms_e->length) && NCDVal_StringRegionEquals(string, 0, string_length, string_data);
-        } break;
-        
         default:
             ASSERT(0);
             return 0;
@@ -1537,13 +1154,7 @@ int NCDVal_StringMemCmp (NCDValRef string1, NCDValRef string2, size_t start1, si
     ASSERT(length <= NCDVal_StringLength(string1) - start1)
     ASSERT(length <= NCDVal_StringLength(string2) - start2)
     
-    if (NCDVal_IsContinuousString(string1) && NCDVal_IsContinuousString(string2)) {
-        return memcmp(NCDVal_StringData(string1) + start1, NCDVal_StringData(string2) + start2, length);
-    }
-    
-    b_cstring cstr1 = NCDVal_StringCstring(string1);
-    b_cstring cstr2 = NCDVal_StringCstring(string2);
-    return b_cstring_memcmp(cstr1, cstr2, start1, start2, length);
+    return memcmp(NCDVal_StringData(string1) + start1, NCDVal_StringData(string2) + start2, length);
 }
 
 void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *dst)
@@ -1552,13 +1163,7 @@ void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *
     ASSERT(start <= NCDVal_StringLength(string))
     ASSERT(length <= NCDVal_StringLength(string) - start)
     
-    if (NCDVal_IsContinuousString(string)) {
-        memcpy(dst, NCDVal_StringData(string) + start, length);
-        return;
-    }
-    
-    b_cstring cstr = NCDVal_StringCstring(string);
-    b_cstring_copy_to_buf(cstr, start, length, dst);
+    memcpy(dst, NCDVal_StringData(string) + start, length);
 }
 
 int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, const char *data)
@@ -1567,12 +1172,7 @@ int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, co
     ASSERT(start <= NCDVal_StringLength(string))
     ASSERT(length <= NCDVal_StringLength(string) - start)
     
-    if (NCDVal_IsContinuousString(string)) {
-        return !memcmp(NCDVal_StringData(string) + start, data, length);
-    }
-    
-    b_cstring cstr = NCDVal_StringCstring(string);
-    return b_cstring_equals_buffer(cstr, start, length, data);
+    return !memcmp(NCDVal_StringData(string) + start, data, length);
 }
 
 int NCDVal_IsList (NCDValRef val)
@@ -1621,13 +1221,6 @@ int NCDVal_ListAppend (NCDValRef list, NCDValRef elem)
         return 0;
     }
     
-    if (NCDValMem__NeedRegisterLink(list.mem, elem.idx)) {
-        if (!NCDValMem__RegisterLink(list.mem, elem.idx, list.idx + offsetof(struct NCDVal__list, elem_indices) + list_e->count * sizeof(NCDVal__idx))) {
-            return 0;
-        }
-        list_e = NCDValMem__BufAt(list.mem, list.idx);
-    }
-    
     list_e->type = new_type;
     list_e->elem_indices[list_e->count++] = elem.idx;
     
@@ -1764,20 +1357,6 @@ int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inse
     
     NCDVal__idx elemidx = NCDVal__MapElemIdx(map.idx, map_e->count);
     
-    if (NCDValMem__NeedRegisterLink(map.mem, key.idx)) {
-        if (!NCDValMem__RegisterLink(map.mem, key.idx, elemidx + offsetof(struct NCDVal__mapelem, key_idx))) {
-            goto fail0;
-        }
-        map_e = NCDValMem__BufAt(map.mem, map.idx);
-    }
-    
-    if (NCDValMem__NeedRegisterLink(map.mem, val.idx)) {
-        if (!NCDValMem__RegisterLink(map.mem, val.idx, elemidx + offsetof(struct NCDVal__mapelem, val_idx))) {
-            goto fail1;
-        }
-        map_e = NCDValMem__BufAt(map.mem, map.idx);
-    }
-    
     struct NCDVal__mapelem *me_e = NCDValMem__BufAt(map.mem, elemidx);
     ASSERT(me_e == &map_e->elems[map_e->count])
     me_e->key_idx = key.idx;
@@ -1799,10 +1378,6 @@ int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inse
     }
     return 1;
     
-fail1:
-    if (NCDValMem__NeedRegisterLink(map.mem, key.idx)) {
-        NCDValMem__PopLastRegisteredLink(map.mem);
-    }
 fail0:
     return 0;
 }
@@ -1965,8 +1540,7 @@ static void replaceprog_build_recurser (NCDValMem *mem, NCDVal__idx idx, size_t
     switch (get_internal_type(*((int *)(ptr)))) {
         case STOREDSTRING_TYPE:
         case IDSTRING_TYPE:
-        case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE: {
+        case EXTERNALSTRING_TYPE: {
         } break;
         
         case NCDVAL_LIST: {
@@ -2132,10 +1706,6 @@ int NCDValReplaceProg_Execute (NCDValReplaceProg prog, NCDValMem *mem, NCDVal_re
                 }
                 ASSERT(repval.mem == mem)
                 
-                if (NCDValMem__NeedRegisterLink(mem, repval.idx)) {
-                    NCDValMem__RegisterLink(mem, repval.idx, instr.placeholder.plidx);
-                }
-                
                 NCDVal__idx *plptr = NCDValMem__BufAt(mem, instr.placeholder.plidx);
                 *plptr = repval.idx;
             } break;

+ 11 - 129
ncd/NCDVal.h

@@ -83,19 +83,6 @@ void NCDValMem_Free (NCDValMem *o);
  */
 int NCDValMem_InitCopy (NCDValMem *o, NCDValMem *other) WARN_UNUSED;
 
-/**
- * For each internal link (e.g. list element) to a ComposedString in the memory
- * object, copies the ComposedString to some kind ContinuousString, and updates
- * the link to point to the new ContinuousString.
- * Additionally, if *\a root_val points to a ComposedString, copies it to a new
- * ContinuousString and updates *\a root_val to point to it.
- * \a root_val must be non-NULL and *\a root_val must not be an invalid value
- * reference.
- * Returns 1 on success and 0 on failure. On failure, some strings may have
- * been converted, but the memory object is left in a consistent state.
- */
-int NCDValMem_ConvertNonContinuousStrings (NCDValMem *o, NCDValRef *root_val) WARN_UNUSED;
-
 /**
  * Does nothing.
  * The value reference object must either point to a valid value within a valid
@@ -192,31 +179,15 @@ int NCDVal_IsSafeRefPlaceholder (NCDValSafeRef sval);
  */
 int NCDVal_GetSafeRefPlaceholderId (NCDValSafeRef sval);
 
-/**
- * Determines if all strings within this value are ContinuousString's,
- * by recusively walking the entire value.
- * If all strings are ContinuousString's, returns 1; if there is at least
- * one string which is not a ContinuousString, returns 0.
- * The value reference must not be an invalid reference.
- */
-int NCDVal_HasOnlyContinuousStrings (NCDValRef val);
-
 /**
  * Determines if the value implements the String interface.
  * The value reference must not be an invalid reference.
  */
 int NCDVal_IsString (NCDValRef val);
 
-/**
- * Determines if the value implements the ContinuousString interface.
- * A ContinuousString also implements the String interface.
- * The value reference must not be an invalid reference.
- */
-int NCDVal_IsContinuousString (NCDValRef val);
-
 /**
  * Determines if the value is a StoredString.
- * A StoredString implements the ContinuousString interface.
+ * A StoredString implements the String interface.
  * The value reference must not be an invalid reference.
  */
 int NCDVal_IsStoredString (NCDValRef val);
@@ -224,7 +195,7 @@ int NCDVal_IsStoredString (NCDValRef val);
 /**
  * Determines if the value is an IdString. See {@link NCDVal_NewIdString}
  * for details.
- * An IdString implements the ContinuousString interface.
+ * An IdString implements the String interface.
  * The value reference must not be an invalid reference.
  */
 int NCDVal_IsIdString (NCDValRef val);
@@ -232,17 +203,11 @@ int NCDVal_IsIdString (NCDValRef val);
 /**
  * Determines if a value is an ExternalString.
  * See {@link NCDVal_NewExternalString} for details.
- * An ExternalString implements the ContinuousString interface.
+ * An ExternalString implements the String interface.
  * The value reference must not be an invalid reference.
  */
 int NCDVal_IsExternalString (NCDValRef val);
 
-/**
- * Determines if a value is a ComposedString.
- * A ComposedString implements the String interface.
- */
-int NCDVal_IsComposedString (NCDValRef val);
-
 /**
  * Determines if a value is a String which contains no null bytes.
  * The value reference must not be an invalid reference.
@@ -262,7 +227,7 @@ NCDValRef NCDVal_NewString (NCDValMem *mem, const char *data);
  * memory object specified. In particular, you may NOT use this
  * function to copy a string that resides in the same memory object.
  * 
- * A StoredString is a kind of ContinuousString which is represented directly in the
+ * A StoredString is a kind of String which is represented directly in the
  * value memory object.
  */
 NCDValRef NCDVal_NewStringBin (NCDValMem *mem, const uint8_t *data, size_t len);
@@ -279,7 +244,7 @@ NCDValRef NCDVal_NewStringUninitialized (NCDValMem *mem, size_t len);
  * Returns a reference to the new value, or an invalid reference
  * on out of memory.
  * 
- * An IdString is a kind of ContinuousString which is represented efficiently as a string
+ * An IdString is a kind of String which is represented efficiently as a string
  * identifier via {@link NCDStringIndex}.
  */
 NCDValRef NCDVal_NewIdString (NCDValMem *mem, NCD_string_id_t string_id,
@@ -292,67 +257,19 @@ NCDValRef NCDVal_NewIdString (NCDValMem *mem, NCD_string_id_t string_id,
  * Returns a reference to the new value, or an invalid reference
  * on out of memory.
  * 
- * An ExternalString is a kind of ContinuousString where the actual string contents are
+ * An ExternalString is a kind of String where the actual string contents are
  * stored outside of the value memory object.
  */
 NCDValRef NCDVal_NewExternalString (NCDValMem *mem, const char *data, size_t len,
                                     BRefTarget *ref_target);
 
 /**
- * Callback function which is called for ComposedString's to access the underlying string resource.
- * \a user is whatever was passed to 'resource.user' in {@link NCDVal_NewComposedString}.
- * \a offset is the offset from the beginning of the string exposed by the resource; it will be
- * >= 'offset' and < 'offset' + 'length' as given to NCDVal_NewComposedString.
- * This callback must set *\a out_data and *\a out_length to represent a continuous (sub-)region
- * of the string that starts at the byte at index \a offset. The pointed-to data must remain
- * valid and unchanged until all references to the string resource are released.
- * \a *out_data must be set to non-NULL and *\a out_length must be set to greater than zero,
- * since the conditions above imply that there is at least one byte available from \a offset.
- */
-typedef void (*NCDVal_ComposedString_func_getptr) (void *user, size_t offset, const char **out_data, size_t *out_length);
-
-/**
- * Structure representing a string resource used by ComposedString's,
- * to simplify {@link NCDVal_NewComposedString} and {@link NCDVal_ComposedStringResource}.
- */
-typedef struct {
-    NCDVal_ComposedString_func_getptr func_getptr;
-    void *user;
-    BRefTarget *ref_target;
-} NCDValComposedStringResource;
-
-/**
- * Returns a cstring referencing a range within a {@link NCDValComposedStringResource}.
- * \a offset and \a length specify the range within the resource which the returned
- * cstring will reference. To reference the contents of a ComposedString, use:
- *   - resource = NCDVal_ComposedStringResource(composedstring),
- *   - offset = NCDVal_ComposedStringOffset(composedstring),
- *   - length = NCDVal_StringLength(composedstring).
- * 
- * The returned cstring is valid as long as the resource is not released. Note that
- * a reference to resource.ref_target may need to be taken to ensure the resource
- * is not released while it is being referenced by the returned cstring (unless
- * resource.ref_target is NULL).
- */
-b_cstring NCDValComposedStringResource_Cstring (NCDValComposedStringResource resource, size_t offset, size_t length);
-
-/**
- * Builds a new ComposedString from a string resource.
- * A reference to the underlying string resource via the {@link BRefTarget} object
- * specified in 'resource.ref_target'.
- * 
- * A ComposedString is a kind of String with an abstract representation exposed via the
- * {@link NCDVal_ComposedString_func_getptr} callback.
- */
-NCDValRef NCDVal_NewComposedString (NCDValMem *mem, NCDValComposedStringResource resource, size_t offset, size_t length);
-
-/**
- * Returns a pointer to the data of a ContinuousString.
+ * Returns a pointer to the data of a String.
  * WARNING: the string data may not be null-terminated. To get a null-terminated
  * version, use {@link NCDVal_StringNullTerminate}.
- * The value reference must point to a ContinuousString.
+ * The value reference must point to a String.
  */
-const char * NCDVal_StringData (NCDValRef contstring);
+const char * NCDVal_StringData (NCDValRef string);
 
 /**
  * Returns the length of a String.
@@ -369,10 +286,10 @@ size_t NCDVal_StringLength (NCDValRef string);
 b_cstring NCDVal_StringCstring (NCDValRef string);
 
 /**
- * Produces a null-terminated continuous version of a String. On success, the result is
+ * Produces a null-terminated version of a String. On success, the result is
  * stored into an {@link NCDValNullTermString} structure, and the null-terminated
  * string is available via its 'data' member. This function may either simply pass
- * through the data pointer (if the string is known to be continuous and null-terminated) or
+ * through the data pointer (if the string is known to be null-terminated) or
  * produce a null-terminated dynamically allocated copy.
  * On success, {@link NCDValNullTermString_Free} should be called to release any allocated
  * memory when the null-terminated string is no longer needed. This must be called before
@@ -394,31 +311,6 @@ NCDValNullTermString NCDValNullTermString_NewDummy (void);
  */
 void NCDValNullTermString_Free (NCDValNullTermString *o);
 
-/**
- * Produces a continuous version of a String. On success, the result is stored into an
- * {@link NCDValContString} structure, and the continuous string is available via its
- * 'data' member. This function may either simply pass through the data pointer (if the
- * string is known to be continuous) or produce a continuous dynamically allocated copy.
- * On success, {@link NCDValContString_Free} should be called to release any allocated
- * memory when the continuous string is no longer needed. This must be called before
- * the memory object is freed, because it may point to data inside the memory object.
- * It is guaranteed that *out is not modified on failure.
- * Returns 1 on success and 0 on failure.
- */
-int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out) WARN_UNUSED;
-
-/**
- * Returns a dummy {@link NCDValContString} which can be freed using
- * {@link NCDValContString_Free}, but need not be.
- */
-NCDValContString NCDValContString_NewDummy (void);
-
-/**
- * Releases any memory which was dynamically allocated by {@link NCDVal_StringContinuize}
- * to continuize a string.
- */
-void NCDValContString_Free (NCDValContString *o);
-
 /**
  * Returns the string ID and the string index of an IdString.
  * Both the \a out_string_id and \a out_string_index pointers must be non-NULL.
@@ -442,16 +334,6 @@ NCDStringIndex * NCDVal_IdStringStringIndex (NCDValRef idstring);
  */
 BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring);
 
-/**
- * Returns the underlying string resource of a ComposedString.
- */
-NCDValComposedStringResource NCDVal_ComposedStringResource (NCDValRef composedstring);
-
-/**
- * Returns the resource offset of a ComposedString.
- */
-size_t NCDVal_ComposedStringOffset (NCDValRef composedstring);
-
 /**
  * Determines if the String has any null bytes in its contents.
  */

+ 0 - 6
ncd/NCDVal_types.h

@@ -46,7 +46,6 @@ typedef struct {
     NCDVal__idx size;
     NCDVal__idx used;
     NCDVal__idx first_ref;
-    NCDVal__idx first_cms_link;
     union {
         char fastbuf[NCDVAL_FASTBUF_SIZE];
         bmax_align_t align_max;
@@ -78,9 +77,4 @@ typedef struct {
     int is_allocated;
 } NCDValNullTermString;
 
-typedef struct {
-    char *data;
-    int is_allocated;
-} NCDValContString;
-
 #endif

+ 0 - 2
ncd/extra/address_utils.h

@@ -49,7 +49,6 @@ static int ncd_read_bconnection_addr (NCDValRef val, struct BConnection_addr *ou
 static int ncd_read_baddr (NCDValRef val, BAddr *out)
 {
     ASSERT(!NCDVal_IsInvalid(val))
-    ASSERT(NCDVal_HasOnlyContinuousStrings(val))
     ASSERT(out)
     
     if (!NCDVal_IsList(val)) {
@@ -236,7 +235,6 @@ fail:
 static int ncd_read_bconnection_addr (NCDValRef val, struct BConnection_addr *out_addr)
 {
     ASSERT(!NCDVal_IsInvalid(val))
-    ASSERT(NCDVal_HasOnlyContinuousStrings(val))
     
     if (!NCDVal_IsList(val)) {
         goto fail;

+ 3 - 27
ncd/extra/value_utils.c

@@ -88,13 +88,7 @@ int ncd_read_uintmax (NCDValRef val, uintmax_t *out)
     
     size_t length = NCDVal_StringLength(val);
     
-    if (NCDVal_IsContinuousString(val)) {
-        return parse_unsigned_integer_bin(NCDVal_StringData(val), length, out);
-    }
-    
-    b_cstring cstr = NCDVal_StringCstring(val);
-    
-    return parse_unsigned_integer_cstr(cstr, 0, cstr.length, out);
+    return parse_unsigned_integer_bin(NCDVal_StringData(val), length, out);
 }
 
 int ncd_read_time (NCDValRef val, btime_t *out)
@@ -121,21 +115,9 @@ NCD_string_id_t ncd_get_string_id (NCDValRef string, NCDStringIndex *string_inde
     
     if (NCDVal_IsIdString(string)) {
         return NCDVal_IdStringId(string);
-    } else if (NCDVal_IsContinuousString(string)) {
-        return NCDStringIndex_GetBin(string_index, NCDVal_StringData(string), NCDVal_StringLength(string));
-    }
-    
-    b_cstring cstr = NCDVal_StringCstring(string);
-    
-    char *temp = b_cstring_strdup(cstr, 0, cstr.length);
-    if (!temp) {
-        return -1;
     }
     
-    NCD_string_id_t res = NCDStringIndex_GetBin(string_index, temp, cstr.length);
-    BFree(temp);
-    
-    return res;
+    return NCDStringIndex_GetBin(string_index, NCDVal_StringData(string), NCDVal_StringLength(string));
 }
 
 NCDValRef ncd_make_uintmax (NCDValMem *mem, uintmax_t value)
@@ -160,13 +142,7 @@ char * ncd_strdup (NCDValRef stringnonulls)
     
     size_t length = NCDVal_StringLength(stringnonulls);
     
-    if (NCDVal_IsContinuousString(stringnonulls)) {
-        return b_strdup_bin(NCDVal_StringData(stringnonulls), length);
-    }
-    
-    b_cstring cstr = NCDVal_StringCstring(stringnonulls);
-    
-    return b_cstring_strdup(cstr, 0, cstr.length);
+    return b_strdup_bin(NCDVal_StringData(stringnonulls), length);
 }
 
 int ncd_eval_func_args_ext (NCDCall const *call, size_t start, size_t count, NCDValMem *mem, NCDValRef *out)

+ 11 - 22
ncd/modules/arithmetic.c

@@ -321,68 +321,57 @@ static struct NCDModule modules[] = {
         .type = "num_lesser",
         .func_new2 = func_new_lesser,
         .func_getvar2 = boolean_func_getvar2,
-        .alloc_size = sizeof(struct boolean_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct boolean_instance)
     }, {
         .type = "num_greater",
         .func_new2 = func_new_greater,
         .func_getvar2 = boolean_func_getvar2,
-        .alloc_size = sizeof(struct boolean_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct boolean_instance)
     }, {
         .type = "num_lesser_equal",
         .func_new2 = func_new_lesser_equal,
         .func_getvar2 = boolean_func_getvar2,
-        .alloc_size = sizeof(struct boolean_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct boolean_instance)
     }, {
         .type = "num_greater_equal",
         .func_new2 = func_new_greater_equal,
         .func_getvar2 = boolean_func_getvar2,
-        .alloc_size = sizeof(struct boolean_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct boolean_instance)
     }, {
         .type = "num_equal",
         .func_new2 = func_new_equal,
         .func_getvar2 = boolean_func_getvar2,
-        .alloc_size = sizeof(struct boolean_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct boolean_instance)
     }, {
         .type = "num_different",
         .func_new2 = func_new_different,
         .func_getvar2 = boolean_func_getvar2,
-        .alloc_size = sizeof(struct boolean_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct boolean_instance)
     }, {
         .type = "num_add",
         .func_new2 = func_new_add,
         .func_getvar2 = number_func_getvar2,
-        .alloc_size = sizeof(struct number_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct number_instance)
     }, {
         .type = "num_subtract",
         .func_new2 = func_new_subtract,
         .func_getvar2 = number_func_getvar2,
-        .alloc_size = sizeof(struct number_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct number_instance)
     }, {
         .type = "num_multiply",
         .func_new2 = func_new_multiply,
         .func_getvar2 = number_func_getvar2,
-        .alloc_size = sizeof(struct number_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct number_instance)
     }, {
         .type = "num_divide",
         .func_new2 = func_new_divide,
         .func_getvar2 = number_func_getvar2,
-        .alloc_size = sizeof(struct number_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct number_instance)
     }, {
         .type = "num_modulo",
         .func_new2 = func_new_modulo,
         .func_getvar2 = number_func_getvar2,
-        .alloc_size = sizeof(struct number_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct number_instance)
     }, {
         .type = NULL
     }

+ 1 - 6
ncd/modules/basic_functions.c

@@ -375,13 +375,8 @@ static void decode_value_eval (NCDCall call)
     if (!NCDVal_IsString(arg)) {
         return;
     }
-    NCDValContString cts;
-    if (!NCDVal_StringContinuize(arg, &cts)) {
-        return FunctionLog(&call, BLOG_ERROR, "decode_value: NCDVal_StringContinuize failed");
-    }
     NCDValRef value;
-    int res = NCDValParser_Parse(cts.data, NCDVal_StringLength(arg), NCDCall_ResMem(&call), &value);
-    NCDValContString_Free(&cts);
+    int res = NCDValParser_Parse(NCDVal_StringData(arg), NCDVal_StringLength(arg), NCDCall_ResMem(&call), &value);
     if (!res) {
         return FunctionLog(&call, BLOG_ERROR, "decode_value: NCDValParser_Parse failed");
     }

+ 5 - 12
ncd/modules/call2.c

@@ -365,16 +365,9 @@ static void func_new_call_with_caller_target (void *vo, NCDModuleInst *i, const
         goto fail0;
     }
     
-    NCDValContString cts;
-    if (!NCDVal_StringContinuize(caller_target_arg, &cts)) {
-        ModuleLog(i, BLOG_ERROR, "NCDVal_StringContinuize failed");
-        goto fail0;
-    }
-    
     struct instance_with_caller_target *o = vo;
     
-    int res = CallNames_InitNames(o, i->params->iparams->string_index, cts.data, NCDVal_StringLength(caller_target_arg));
-    NCDValContString_Free(&cts);
+    int res = CallNames_InitNames(o, i->params->iparams->string_index, NCDVal_StringData(caller_target_arg), NCDVal_StringLength(caller_target_arg));
     if (!res) {
         ModuleLog(i, BLOG_ERROR, "CallerNames_InitNames failed");
         goto fail0;
@@ -588,7 +581,7 @@ static struct NCDModule modules[] = {
         .func_die = func_die,
         .func_clean = func_clean,
         .func_getobj = func_getobj,
-        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS,
+        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN,
         .alloc_size = sizeof(struct instance)
     }, {
         .type = "call_with_caller_target",
@@ -596,7 +589,7 @@ static struct NCDModule modules[] = {
         .func_die = func_die,
         .func_clean = func_clean,
         .func_getobj = func_getobj,
-        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS,
+        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN,
         .alloc_size = sizeof(struct instance_with_caller_target)
     }, {
         .type = "embcall2_multif",
@@ -604,7 +597,7 @@ static struct NCDModule modules[] = {
         .func_die = func_die,
         .func_clean = func_clean,
         .func_getobj = func_getobj,
-        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS,
+        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN,
         .alloc_size = sizeof(struct instance)
     }, {
         .type = "inline_code",
@@ -617,7 +610,7 @@ static struct NCDModule modules[] = {
         .func_die = func_die,
         .func_clean = func_clean,
         .func_getobj = func_getobj,
-        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS,
+        .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN,
         .alloc_size = sizeof(struct inline_code_call)
     }, {
         .type = NULL

+ 2 - 4
ncd/modules/concat.c

@@ -167,15 +167,13 @@ static struct NCDModule modules[] = {
         .func_new2 = func_new_concat,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "concatv",
         .func_new2 = func_new_concatv,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = NULL
     }

+ 1 - 2
ncd/modules/daemon.c

@@ -282,8 +282,7 @@ static struct NCDModule modules[] = {
         .type = "daemon",
         .func_new2 = func_new,
         .func_die = func_die,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = NULL
     }

+ 4 - 8
ncd/modules/file.c

@@ -319,24 +319,20 @@ static struct NCDModule modules[] = {
         .func_new2 = read_func_new,
         .func_die = read_func_die,
         .func_getvar2 = read_func_getvar2,
-        .alloc_size = sizeof(struct read_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct read_instance)
     }, {
         .type = "file_write",
-        .func_new2 = write_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = write_func_new
     }, {
         .type = "file_stat",
         .func_new2 = stat_func_new,
         .func_getvar2 = stat_func_getvar2,
-        .alloc_size = sizeof(struct stat_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct stat_instance)
     }, {
         .type = "file_lstat",
         .func_new2 = lstat_func_new,
         .func_getvar2 = stat_func_getvar2,
-        .alloc_size = sizeof(struct stat_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct stat_instance)
     }, {
         .type = NULL
     }

+ 5 - 10
ncd/modules/file_open.c

@@ -550,27 +550,22 @@ static struct NCDModule modules[] = {
         .func_new2 = open_func_new,
         .func_die = open_func_die,
         .func_getvar2 = open_func_getvar,
-        .alloc_size = sizeof(struct open_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct open_instance)
     }, {
         .type = "file_open::read",
         .func_new2 = read_func_new,
         .func_die = read_func_die,
         .func_getvar2 = read_func_getvar,
-        .alloc_size = sizeof(struct read_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct read_instance)
     }, {
         .type = "file_open::write",
-        .func_new2 = write_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = write_func_new
     }, {
         .type = "file_open::seek",
-        .func_new2 = seek_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = seek_func_new
     }, {
         .type = "file_open::close",
-        .func_new2 = close_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = close_func_new
     }, {
         .type = NULL
     }

+ 0 - 2
ncd/modules/modules.h

@@ -78,7 +78,6 @@ extern const struct NCDModuleGroup ncdmodule_backtrack;
 extern const struct NCDModuleGroup ncdmodule_depend_scope;
 extern const struct NCDModuleGroup ncdmodule_substr;
 extern const struct NCDModuleGroup ncdmodule_log;
-extern const struct NCDModuleGroup ncdmodule_buffer;
 extern const struct NCDModuleGroup ncdmodule_getenv;
 extern const struct NCDModuleGroup ncdmodule_basic_functions;
 #ifndef BADVPN_EMSCRIPTEN
@@ -165,7 +164,6 @@ static const struct NCDModuleGroup *ncd_modules[] = {
     &ncdmodule_depend_scope,
     &ncdmodule_substr,
     &ncdmodule_log,
-    &ncdmodule_buffer,
     &ncdmodule_getenv,
     &ncdmodule_basic_functions,
 #ifndef BADVPN_EMSCRIPTEN

+ 4 - 8
ncd/modules/print.c

@@ -177,24 +177,20 @@ static void rprintln_func_new (void *vo, NCDModuleInst *i, const struct NCDModul
 static struct NCDModule modules[] = {
     {
         .type = "print",
-        .func_new2 = print_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = print_func_new
     }, {
         .type = "println",
-        .func_new2 = println_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = println_func_new
     }, {
         .type = "rprint",
         .func_new2 = rprint_func_new,
         .func_die = rprint_func_die,
-        .alloc_size = sizeof(struct rprint_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct rprint_instance)
      }, {
         .type = "rprintln",
         .func_new2 = rprintln_func_new,
         .func_die = rprint_func_die,
-        .alloc_size = sizeof(struct rprint_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct rprint_instance)
     }, {
         .type = NULL
     }

+ 3 - 6
ncd/modules/process_manager.c

@@ -515,16 +515,13 @@ static struct NCDModule modules[] = {
         .type = "process_manager",
         .func_new2 = func_new,
         .func_die = func_die,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "process_manager::start",
-        .func_new2 = start_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = start_func_new
     }, {
         .type = "process_manager::stop",
-        .func_new2 = stop_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = stop_func_new
     }, {
         .type = NULL
     }

+ 1 - 2
ncd/modules/run.c

@@ -175,8 +175,7 @@ static struct NCDModule modules[] = {
         .type = "run",
         .func_new2 = func_new,
         .func_die = func_die,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = NULL
     }

+ 1 - 2
ncd/modules/runonce.c

@@ -320,8 +320,7 @@ static struct NCDModule modules[] = {
         .func_new2 = func_new,
         .func_die = func_die,
         .func_getvar = func_getvar,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = NULL
     }

+ 5 - 10
ncd/modules/socket.c

@@ -1032,32 +1032,27 @@ static struct NCDModule modules[] = {
         .func_new2 = connect_func_new,
         .func_die = connect_func_die,
         .func_getvar2 = connect_func_getvar,
-        .alloc_size = sizeof(struct connection),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct connection)
     }, {
         .type = "sys.socket::read",
         .func_new2 = read_func_new,
         .func_die = read_func_die,
         .func_getvar2 = read_func_getvar,
-        .alloc_size = sizeof(struct read_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct read_instance)
     }, {
         .type = "sys.socket::write",
         .func_new2 = write_func_new,
         .func_die = write_func_die,
-        .alloc_size = sizeof(struct write_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct write_instance)
     }, {
         .type = "sys.socket::close",
-        .func_new2 = close_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = close_func_new
     }, {
         .type = "sys.listen",
         .func_new2 = listen_func_new,
         .func_die = listen_func_die,
         .func_getvar2 = listen_func_getvar,
-        .alloc_size = sizeof(struct listen_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct listen_instance)
     }, {
         .type = NULL
     }

+ 9 - 18
ncd/modules/sys_start_process.c

@@ -1208,54 +1208,45 @@ static struct NCDModule modules[] = {
         .func_new2 = process_func_new,
         .func_die = process_func_die,
         .func_getvar2 = process_func_getvar,
-        .alloc_size = sizeof(struct process_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct process_instance)
     }, {
         .type = "sys.start_process::wait",
         .func_new2 = wait_func_new,
         .func_die = wait_func_die,
         .func_getvar2 = wait_func_getvar,
-        .alloc_size = sizeof(struct wait_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct wait_instance)
     }, {
         .type = "sys.start_process::terminate",
-        .func_new2 = terminate_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = terminate_func_new
     }, {
         .type = "sys.start_process::kill",
-        .func_new2 = kill_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = kill_func_new
     }, {
         .type = "sys.start_process::read_pipe",
         .func_new2 = read_pipe_func_new,
         .func_die = read_pipe_func_die,
         .func_getvar2 = read_pipe_func_getvar,
-        .alloc_size = sizeof(struct read_pipe_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct read_pipe_instance)
     }, {
         .type = "sys.start_process::read_pipe::read",
         .func_new2 = read_func_new,
         .func_die = read_func_die,
         .func_getvar2 = read_func_getvar,
-        .alloc_size = sizeof(struct read_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct read_instance)
     }, {
         .type = "sys.start_process::write_pipe",
         .func_new2 = write_pipe_func_new,
         .func_die = write_pipe_func_die,
         .func_getvar2 = write_pipe_func_getvar,
-        .alloc_size = sizeof(struct write_pipe_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct write_pipe_instance)
     }, {
         .type = "sys.start_process::write_pipe::write",
         .func_new2 = write_func_new,
         .func_die = write_func_die,
-        .alloc_size = sizeof(struct write_instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct write_instance)
     }, {
         .type = "sys.start_process::write_pipe::close",
-        .func_new2 = close_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = close_func_new
     }, {
         .type = NULL
     }

+ 1 - 2
ncd/modules/to_string.c

@@ -102,8 +102,7 @@ static struct NCDModule modules[] = {
         .func_new2 = func_new,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = NULL
     }

+ 19 - 114
ncd/modules/value.c

@@ -171,7 +171,6 @@
 #define STOREDSTRING_TYPE (NCDVAL_STRING | (0 << 3))
 #define IDSTRING_TYPE (NCDVAL_STRING | (1 << 3))
 #define EXTERNALSTRING_TYPE (NCDVAL_STRING | (2 << 3))
-#define COMPOSEDSTRING_TYPE (NCDVAL_STRING | (3 << 3))
 
 struct value;
 
@@ -222,11 +221,6 @@ struct value {
             size_t length;
             BRefTarget *ref_target;
         } externalstring;
-        struct {
-            NCDValComposedStringResource resource;
-            size_t offset;
-            size_t length;
-        } composedstring;
         struct {
             IndexedList list_contents_il;
         } list;
@@ -242,7 +236,6 @@ static void value_delete (struct value *v);
 static struct value * value_init_storedstring (NCDModuleInst *i, const char *str, size_t len);
 static struct value * value_init_idstring (NCDModuleInst *i, NCD_string_id_t id, NCDStringIndex *string_index);
 static struct value * value_init_externalstring (NCDModuleInst *i, const char *data, size_t length, BRefTarget *ref_target);
-static struct value * value_init_composedstring (NCDModuleInst *i, NCDValComposedStringResource resource, size_t offset, size_t length);
 static int value_is_string (struct value *v);
 static size_t value_string_length (struct value *v);
 static void value_string_copy_out (struct value *v, char *dest);
@@ -288,7 +281,6 @@ static const char * get_type_str (int type)
         case STOREDSTRING_TYPE:
         case IDSTRING_TYPE:
         case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE:
             return "string";
         case NCDVAL_LIST:
             return "list";
@@ -319,12 +311,6 @@ static void value_cleanup (struct value *v)
             }
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            if (v->composedstring.resource.ref_target) {
-                BRefTarget_Deref(v->composedstring.resource.ref_target);
-            }
-        } break;
-        
         case NCDVAL_LIST: {
             while (value_list_len(v) > 0) {
                 struct value *ev = value_list_at(v, 0);
@@ -382,12 +368,6 @@ static void value_delete (struct value *v)
             }
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            if (v->composedstring.resource.ref_target) {
-                BRefTarget_Deref(v->composedstring.resource.ref_target);
-            }
-        } break;
-        
         case NCDVAL_LIST: {
             while (value_list_len(v) > 0) {
                 struct value *ev = value_list_at(v, 0);
@@ -493,44 +473,12 @@ fail0:
     return NULL;
 }
 
-static struct value * value_init_composedstring (NCDModuleInst *i, NCDValComposedStringResource resource, size_t offset, size_t length)
-{
-    struct value *v = malloc(sizeof(*v));
-    if (!v) {
-        ModuleLog(i, BLOG_ERROR, "malloc failed");
-        goto fail0;
-    }
-    
-    if (resource.ref_target) {
-        if (!BRefTarget_Ref(resource.ref_target)) {
-            ModuleLog(i, BLOG_ERROR, "BRefTarget_Ref failed");
-            goto fail1;
-        }
-    }
-    
-    LinkedList0_Init(&v->refs_list);
-    v->parent = NULL;
-    v->type = COMPOSEDSTRING_TYPE;
-    
-    v->composedstring.resource = resource;
-    v->composedstring.offset = offset;
-    v->composedstring.length = length;
-    
-    return v;
-    
-fail1:
-    free(v);
-fail0:
-    return NULL;
-}
-
 static int value_is_string (struct value *v)
 {
     switch (v->type) {
         case STOREDSTRING_TYPE:
         case IDSTRING_TYPE:
         case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE:
             return 1;
         default:
             return 0;
@@ -548,8 +496,6 @@ static size_t value_string_length (struct value *v)
             return NCDStringIndex_Length(v->idstring.string_index, v->idstring.id);
         case EXTERNALSTRING_TYPE:
             return v->externalstring.length;
-        case COMPOSEDSTRING_TYPE:
-            return v->composedstring.length;
         default:
             ASSERT(0);
             return 0;
@@ -570,10 +516,6 @@ static void value_string_copy_out (struct value *v, char *dest)
         case EXTERNALSTRING_TYPE:
             memcpy(dest, v->externalstring.data, v->externalstring.length);
             break;
-        case COMPOSEDSTRING_TYPE: {
-            b_cstring cstr = NCDValComposedStringResource_Cstring(v->composedstring.resource, v->composedstring.offset, v->composedstring.length);
-            b_cstring_copy_to_buf(cstr, 0, cstr.length, dest);
-        } break;
         default:
             ASSERT(0);
     }
@@ -598,12 +540,6 @@ static void value_string_set_allocd (struct value *v, char *data, size_t length)
             }
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            if (v->composedstring.resource.ref_target) {
-                BRefTarget_Deref(v->composedstring.resource.ref_target);
-            }
-        } break;
-        
         default:
             ASSERT(0);
     }
@@ -793,8 +729,6 @@ static struct value * value_init_fromvalue (NCDModuleInst *i, NCDValRef value)
                 v = value_init_idstring(i, NCDVal_IdStringId(value), NCDVal_IdStringStringIndex(value));
             } else if (NCDVal_IsExternalString(value)) {
                 v = value_init_externalstring(i, NCDVal_StringData(value), NCDVal_StringLength(value), NCDVal_ExternalStringTarget(value));
-            } else if (NCDVal_IsComposedString(value)) {
-                v = value_init_composedstring(i, NCDVal_ComposedStringResource(value), NCDVal_ComposedStringOffset(value), NCDVal_StringLength(value));
             } else {
                 size_t length = NCDVal_StringLength(value);
                 v = value_init_storedstring(i, NULL, length);
@@ -899,13 +833,6 @@ static int value_to_value (NCDModuleInst *i, struct value *v, NCDValMem *mem, NC
             }
         } break;
         
-        case COMPOSEDSTRING_TYPE: {
-            *out_value = NCDVal_NewComposedString(mem, v->composedstring.resource, v->composedstring.offset, v->composedstring.length);
-            if (NCDVal_IsInvalid(*out_value)) {
-                goto fail;
-            }
-        } break;
-        
         case NCDVAL_LIST: {
             *out_value = NCDVal_NewList(mem, value_list_len(v));
             if (NCDVal_IsInvalid(*out_value)) {
@@ -967,8 +894,7 @@ static struct value * value_get (NCDModuleInst *i, struct value *v, NCDValRef wh
     switch (v->type) {
         case STOREDSTRING_TYPE:
         case IDSTRING_TYPE:
-        case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE: {
+        case EXTERNALSTRING_TYPE: {
             if (!no_error) ModuleLog(i, BLOG_ERROR, "cannot resolve into a string");
             goto fail;
         } break;
@@ -1040,8 +966,7 @@ static struct value * value_insert (NCDModuleInst *i, struct value *v, NCDValRef
     switch (v->type) {
         case STOREDSTRING_TYPE:
         case IDSTRING_TYPE:
-        case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE: {
+        case EXTERNALSTRING_TYPE: {
             ModuleLog(i, BLOG_ERROR, "cannot insert into a string");
             goto fail1;
         } break;
@@ -1153,8 +1078,7 @@ static int value_remove (NCDModuleInst *i, struct value *v, NCDValRef where)
     switch (v->type) {
         case STOREDSTRING_TYPE:
         case IDSTRING_TYPE:
-        case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE: {
+        case EXTERNALSTRING_TYPE: {
             ModuleLog(i, BLOG_ERROR, "cannot remove from a string");
             goto fail;
         } break;
@@ -1230,8 +1154,7 @@ static int value_append (NCDModuleInst *i, struct value *v, NCDValRef data)
         } break;
         
         case IDSTRING_TYPE:
-        case EXTERNALSTRING_TYPE:
-        case COMPOSEDSTRING_TYPE: {
+        case EXTERNALSTRING_TYPE: {
             if (!NCDVal_IsString(data)) {
                 ModuleLog(i, BLOG_ERROR, "cannot append non-string to string");
                 return 0;
@@ -1846,9 +1769,6 @@ static void func_new_substr (void *vo, NCDModuleInst *i, const struct NCDModuleI
         case EXTERNALSTRING_TYPE: {
             v = value_init_externalstring(i, mov->externalstring.data + start, amount, mov->externalstring.ref_target);
         } break;
-        case COMPOSEDSTRING_TYPE: {
-            v = value_init_composedstring(i, mov->composedstring.resource, mov->composedstring.offset + start, amount);
-        } break;
         default:
             ASSERT(0);
     }
@@ -1985,104 +1905,89 @@ static struct NCDModule modules[] = {
         .func_new2 = func_new_value,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::get",
         .base_type = "value",
         .func_new2 = func_new_get,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::try_get",
         .base_type = "value",
         .func_new2 = func_new_try_get,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::getpath",
         .base_type = "value",
         .func_new2 = func_new_getpath,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::insert",
         .base_type = "value",
         .func_new2 = func_new_insert,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::replace",
         .base_type = "value",
         .func_new2 = func_new_replace,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::replace_this",
         .base_type = "value",
         .func_new2 = func_new_replace_this,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::insert_undo",
         .base_type = "value",
         .func_new2 = func_new_insert_undo,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::replace_undo",
         .base_type = "value",
         .func_new2 = func_new_replace_undo,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::replace_this_undo",
         .base_type = "value",
         .func_new2 = func_new_replace_this_undo,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::remove",
-        .func_new2 = remove_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = remove_func_new
     }, {
         .type = "value::delete",
-        .func_new2 = delete_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = delete_func_new
     }, {
         .type = "value::reset",
-        .func_new2 = reset_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = reset_func_new
     }, {
         .type = "value::substr",
         .base_type = "value",
         .func_new2 = func_new_substr,
         .func_die = func_die,
         .func_getvar2 = func_getvar2,
-        .alloc_size = sizeof(struct instance),
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .alloc_size = sizeof(struct instance)
     }, {
         .type = "value::append",
-        .func_new2 = append_func_new,
-        .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS
+        .func_new2 = append_func_new
     }, {
         .type = NULL
     }

+ 0 - 18
ncd/tests/value.ncd

@@ -197,24 +197,6 @@ process main {
     val_equal(v, {"1", "2", "3", "4"})  a;
     assert(a);
     
-    buffer() buf;
-    buf->append("123");
-    value(buf) v;
-    val_equal(v, "123") a;
-    assert(a);
-    v->substr("2") sub_v;
-    val_equal(sub_v, "3") a;
-    assert(a);
-    v->append("456789012345");
-    val_equal(v, "123456789012345") a;
-    assert(a);
-    buffer() numbuf;
-    numbuf->append("1");
-    numbuf->append("2");
-    v->substr(numbuf) sub_v;
-    val_equal(sub_v, "345") a;
-    assert(a);
-    
     concat("hello", "world") cnc;
     value(cnc) v;
     val_equal(v, "helloworld") a;