コード例 #1
0
ファイル: Err.c プロジェクト: theory/lucy
void
Err_throw_mess(VTable *vtable, CharBuf *message) {
    Err_Make_t make
        = METHOD_PTR(CERTIFY(vtable, VTABLE), Cfish_Err_Make);
    Err *err = (Err*)CERTIFY(make(NULL), ERR);
    Err_Cat_Mess(err, message);
    DECREF(message);
    Err_do_throw(err);
}
コード例 #2
0
ファイル: Highlighter.c プロジェクト: hernan604/lucy
static String*
S_do_encode(Highlighter *self, String *text, CharBuf **encode_buf) {
    VTable *vtable = Highlighter_Get_VTable(self);
    Highlighter_Encode_t my_meth
        = (Highlighter_Encode_t)METHOD_PTR(vtable, LUCY_Highlighter_Encode);
    Highlighter_Encode_t orig_meth
        = (Highlighter_Encode_t)METHOD_PTR(HIGHLIGHTER, LUCY_Highlighter_Encode);

    if (my_meth != orig_meth) {
        return my_meth(self, text);
    }
    else {
        if (*encode_buf == NULL) {
            *encode_buf = CB_new(0);
        }
        return S_encode_entities(text, *encode_buf);
    }
}
コード例 #3
0
ファイル: String.c プロジェクト: srcclrapache1/lucy-clownfish
size_t
Str_Hash_Sum_IMP(String *self) {
    size_t hashvalue = 5381;
    StringIterator *iter = STACK_ITER(self, 0);

    const StrIter_Next_t next = METHOD_PTR(STRINGITERATOR, CFISH_StrIter_Next);
    int32_t code_point;
    while (STR_OOB != (code_point = next(iter))) {
        hashvalue = ((hashvalue << 5) + hashvalue) ^ (size_t)code_point;
    }

    return hashvalue;
}
コード例 #4
0
ファイル: CharBuf.c プロジェクト: pavansondur/lucy
int32_t
CB_hash_sum(CharBuf *self) {
    uint32_t hashvalue = 5381;
    ZombieCharBuf *iterator = ZCB_WRAP(self);

    const CB_Nip_One_t nip_one = METHOD_PTR(iterator->vtable, Lucy_CB_Nip_One);
    while (iterator->size) {
        uint32_t code_point = (uint32_t)nip_one((CharBuf*)iterator);
        hashvalue = ((hashvalue << 5) + hashvalue) ^ code_point;
    }

    return (int32_t) hashvalue;
}
コード例 #5
0
ファイル: Err.c プロジェクト: pavansondur/lucy
void
THROW(VTable *vtable, char *pattern, ...) {
    va_list args;
    Err_Make_t make = METHOD_PTR(CERTIFY(vtable, VTABLE), Lucy_Err_Make);
    Err *err = (Err*)CERTIFY(make(NULL), ERR);
    CharBuf *mess = Err_Get_Mess(err);

    va_start(args, pattern);
    CB_VCatF(mess, pattern, args);
    va_end(args);

    Err_do_throw(err);
}
コード例 #6
0
ファイル: Hash.c プロジェクト: pavansondur/lucy
Obj*
Hash_load(Hash *self, Obj *dump) {
    Hash *source = (Hash*)CERTIFY(dump, HASH);
    CharBuf *class_name = (CharBuf*)Hash_Fetch_Str(source, "_class", 6);
    UNUSED_VAR(self);

    // Assume that the presence of the "_class" key paired with a valid class
    // name indicates the output of a Dump rather than an ordinary Hash. */
    if (class_name && CB_Is_A(class_name, CHARBUF)) {
        VTable *vtable = VTable_fetch_vtable(class_name);

        if (!vtable) {
            CharBuf *parent_class = VTable_find_parent_class(class_name);
            if (parent_class) {
                VTable *parent = VTable_singleton(parent_class, NULL);
                vtable = VTable_singleton(class_name, parent);
                DECREF(parent_class);
            }
            else {
                // TODO: Fix Hash_Load() so that it works with ordinary hash
                // keys named "_class".
                THROW(ERR, "Can't find class '%o'", class_name);
            }
        }

        // Dispatch to an alternate Load() method.
        if (vtable) {
            Obj_Load_t load = METHOD_PTR(vtable, Lucy_Obj_Load);
            if (load == Obj_load) {
                THROW(ERR, "Abstract method Load() not defined for %o",
                      VTable_Get_Name(vtable));
            }
            else if (load != (Obj_Load_t)Hash_load) { // stop inf loop
                return VTable_Load_Obj(vtable, dump);
            }
        }
    }

    // It's an ordinary Hash.
    Hash *loaded = Hash_new(source->size);
    Obj *key;
    Obj *value;
    Hash_Iterate(source);
    while (Hash_Next(source, &key, &value)) {
        Hash_Store(loaded, key, Obj_Load(value, value));
    }

    return (Obj*)loaded;

}
コード例 #7
0
ファイル: Err.c プロジェクト: pavansondur/lucy
void
Err_throw_at(VTable *vtable, const char *file, int line,
             const char *func, const char *pattern, ...) {
    va_list args;
    Err_Make_t make = METHOD_PTR(CERTIFY(vtable, VTABLE), Lucy_Err_Make);
    Err *err = (Err*)CERTIFY(make(NULL), ERR);
    CharBuf *mess = Err_Get_Mess(err);

    va_start(args, pattern);
    S_vcat_mess(mess, file, line, func, pattern, args);
    va_end(args);

    Err_do_throw(err);
}
コード例 #8
0
ファイル: SortExternal.c プロジェクト: kidaa/lucy
void
SortEx_Sort_Buffer_IMP(SortExternal *self) {
    SortExternalIVARS *const ivars = SortEx_IVARS(self);
    if (ivars->buf_tick != 0) {
        THROW(ERR, "Cant Sort_Buffer() after fetching %u32 items", ivars->buf_tick);
    }
    if (ivars->buf_max != 0) {
        Class *klass = SortEx_get_class(self);
        CFISH_Sort_Compare_t compare
            = (CFISH_Sort_Compare_t)METHOD_PTR(klass, LUCY_SortEx_Compare);
        if (ivars->scratch_cap < ivars->buf_cap) {
            ivars->scratch_cap = ivars->buf_cap;
            ivars->scratch
                = (Obj**)REALLOCATE(ivars->scratch,
                                    ivars->scratch_cap * sizeof(Obj*));
        }
        Sort_mergesort(ivars->buffer, ivars->scratch, ivars->buf_max,
                       sizeof(Obj*), compare, self);
    }
}
コード例 #9
0
ファイル: SortExternal.c プロジェクト: kstarsinic/lucy
void
SortEx_Sort_Cache_IMP(SortExternal *self) {
    SortExternalIVARS *const ivars = SortEx_IVARS(self);
    if (ivars->cache_tick != 0) {
        THROW(ERR, "Cant Sort_Cache() after fetching %u32 items", ivars->cache_tick);
    }
    if (ivars->cache_max != 0) {
        VTable *vtable = SortEx_Get_VTable(self);
        CFISH_Sort_Compare_t compare
            = (CFISH_Sort_Compare_t)METHOD_PTR(vtable, LUCY_SortEx_Compare);
        if (ivars->scratch_cap < ivars->cache_cap) {
            ivars->scratch_cap = ivars->cache_cap;
            ivars->scratch
                = (uint8_t*)REALLOCATE(ivars->scratch,
                                       ivars->scratch_cap * ivars->width);
        }
        Sort_mergesort(ivars->cache, ivars->scratch, ivars->cache_max,
                       ivars->width, compare, self);
    }
}
コード例 #10
0
ファイル: SortExternal.c プロジェクト: kidaa/lucy
static uint32_t
S_find_slice_size(SortExternal *self, SortExternalIVARS *ivars,
                  Obj **endpost) {
    int32_t          lo      = ivars->buf_tick - 1;
    int32_t          hi      = ivars->buf_max;
    Obj            **buffer  = ivars->buffer;
    SortEx_Compare_t compare
        = METHOD_PTR(SortEx_get_class(self), LUCY_SortEx_Compare);

    // Binary search.
    while (hi - lo > 1) {
        const int32_t mid   = lo + ((hi - lo) / 2);
        const int32_t delta = compare(self, buffer + mid, endpost);
        if (delta > 0) { hi = mid; }
        else           { lo = mid; }
    }

    // If lo is still -1, we didn't find anything.
    return lo == -1
           ? 0
           : (lo - ivars->buf_tick) + 1;
}
コード例 #11
0
ファイル: SortExternal.c プロジェクト: kstarsinic/lucy
static uint32_t
S_find_slice_size(SortExternal *self, SortExternalIVARS *ivars,
                  uint8_t *endpost) {
    int32_t          lo      = ivars->cache_tick - 1;
    int32_t          hi      = ivars->cache_max;
    uint8_t *const   cache   = ivars->cache;
    const size_t     width   = ivars->width;
    SortEx_Compare_t compare
        = METHOD_PTR(SortEx_Get_VTable(self), LUCY_SortEx_Compare);

    // Binary search.
    while (hi - lo > 1) {
        const int32_t mid   = lo + ((hi - lo) / 2);
        const int32_t delta = compare(self, cache + mid * width, endpost);
        if (delta > 0) { hi = mid; }
        else           { lo = mid; }
    }

    // If lo is still -1, we didn't find anything.
    return lo == -1
           ? 0
           : (lo - ivars->cache_tick) + 1;
}
コード例 #12
0
ファイル: SortExternal.c プロジェクト: kidaa/lucy
static void
S_absorb_slices(SortExternal *self, SortExternalIVARS *ivars,
                Obj **endpost) {
    uint32_t    num_runs     = Vec_Get_Size(ivars->runs);
    Obj      ***slice_starts = ivars->slice_starts;
    uint32_t   *slice_sizes  = ivars->slice_sizes;
    Class      *klass        = SortEx_get_class(self);
    CFISH_Sort_Compare_t compare
        = (CFISH_Sort_Compare_t)METHOD_PTR(klass, LUCY_SortEx_Compare);

    if (ivars->buf_max != 0) { THROW(ERR, "Can't refill unless empty"); }

    // Move all the elements in range into the main buffer as slices.
    for (uint32_t i = 0; i < num_runs; i++) {
        SortExternal *const run = (SortExternal*)Vec_Fetch(ivars->runs, i);
        SortExternalIVARS *const run_ivars = SortEx_IVARS(run);
        uint32_t slice_size = S_find_slice_size(run, run_ivars, endpost);

        if (slice_size) {
            // Move slice content from run buffer to main buffer.
            if (ivars->buf_max + slice_size > ivars->buf_cap) {
                size_t cap = Memory_oversize(ivars->buf_max + slice_size,
                                             sizeof(Obj*));
                SortEx_Grow_Buffer(self, cap);
            }
            memcpy(ivars->buffer + ivars->buf_max,
                   run_ivars->buffer + run_ivars->buf_tick,
                   slice_size * sizeof(Obj*));
            run_ivars->buf_tick += slice_size;
            ivars->buf_max += slice_size;

            // Track number of slices and slice sizes.
            slice_sizes[ivars->num_slices++] = slice_size;
        }
    }

    // Transform slice starts from ticks to pointers.
    uint32_t total = 0;
    for (uint32_t i = 0; i < ivars->num_slices; i++) {
        slice_starts[i] = ivars->buffer + total;
        total += slice_sizes[i];
    }

    // The main buffer now consists of several slices.  Sort the main buffer,
    // but exploit the fact that each slice is already sorted.
    if (ivars->scratch_cap < ivars->buf_cap) {
        ivars->scratch_cap = ivars->buf_cap;
        ivars->scratch = (Obj**)REALLOCATE(
                            ivars->scratch, ivars->scratch_cap * sizeof(Obj*));
    }

    // Exploit previous sorting, rather than sort buffer naively.
    // Leave the first slice intact if the number of slices is odd. */
    while (ivars->num_slices > 1) {
        uint32_t i = 0;
        uint32_t j = 0;

        while (i < ivars->num_slices) {
            if (ivars->num_slices - i >= 2) {
                // Merge two consecutive slices.
                const uint32_t merged_size = slice_sizes[i] + slice_sizes[i + 1];
                Sort_merge(slice_starts[i], slice_sizes[i],
                           slice_starts[i + 1], slice_sizes[i + 1], ivars->scratch,
                           sizeof(Obj*), compare, self);
                slice_sizes[j]  = merged_size;
                slice_starts[j] = slice_starts[i];
                memcpy(slice_starts[j], ivars->scratch, merged_size * sizeof(Obj*));
                i += 2;
                j += 1;
            }
            else if (ivars->num_slices - i >= 1) {
                // Move single slice pointer.
                slice_sizes[j]  = slice_sizes[i];
                slice_starts[j] = slice_starts[i];
                i += 1;
                j += 1;
            }
        }
        ivars->num_slices = j;
    }

    ivars->num_slices = 0;
}