예제 #1
0
String*
Method_lower_snake_alias(cfish_Method *method) {
    cfish_String *host_alias = CFISH_Method_Get_Host_Alias(method);
    if (host_alias) {
        return (cfish_String*)CFISH_INCREF(host_alias);
    }

    // Convert to lowercase.
    cfish_String *name = CFISH_Method_Get_Name(method);
    cfish_CharBuf *buf = cfish_CB_new(CFISH_Str_Get_Size(name));
    cfish_StringIterator *iter = CFISH_Str_Top(name);
    int32_t code_point;
    while (CFISH_STR_OOB != (code_point = CFISH_StrIter_Next(iter))) {
        if (code_point > 127) {
            THROW(CFISH_ERR, "Can't lowercase '%o'", name);
        }
        else {
            CFISH_CB_Cat_Char(buf, tolower(code_point));
        }
    }
    cfish_String *retval = CFISH_CB_Yield_String(buf);
    CFISH_DECREF(iter);
    CFISH_DECREF(buf);

    return retval;
}
예제 #2
0
파일: Err.c 프로젝트: pavansondur/lucy
void
lucy_Err_warn_mess(lucy_CharBuf *message) {
    SV *error_sv = XSBind_cb_to_sv(message);
    CFISH_DECREF(message);
    warn("%s", SvPV_nolen(error_sv));
    SvREFCNT_dec(error_sv);
}
예제 #3
0
파일: Err.c 프로젝트: pavansondur/lucy
lucy_Err*
lucy_Err_get_error() {
    lucy_Err *error
        = (lucy_Err*)lucy_Host_callback_obj(LUCY_ERR, "get_error", 0);
    CFISH_DECREF(error); // Cancel out incref from callback.
    return error;
}
예제 #4
0
lucy_RegexTokenizer*
lucy_RegexTokenizer_init(lucy_RegexTokenizer *self,
                         const lucy_CharBuf *pattern) {
    SV *token_re_sv;

    lucy_Analyzer_init((lucy_Analyzer*)self);
#define DEFAULT_PATTERN "\\w+(?:['\\x{2019}]\\w+)*"
    if (pattern) {
        if (Lucy_CB_Find_Str(pattern, "\\p", 2) != -1
                || Lucy_CB_Find_Str(pattern, "\\P", 2) != -1
           ) {
            CFISH_DECREF(self);
            THROW(LUCY_ERR, "\\p and \\P constructs forbidden");
        }
        self->pattern = Lucy_CB_Clone(pattern);
    }
    else {
        self->pattern = lucy_CB_new_from_trusted_utf8(
                            DEFAULT_PATTERN, sizeof(DEFAULT_PATTERN) - 1);
    }

    // Acquire a compiled regex engine for matching one token.
    token_re_sv = (SV*)lucy_Host_callback_host(
                      LUCY_REGEXTOKENIZER, "compile_token_re", 1,
                      CFISH_ARG_STR("pattern", self->pattern));
    S_set_token_re_but_not_pattern(self, SvRV(token_re_sv));
    SvREFCNT_dec(token_re_sv);

    return self;
}
예제 #5
0
void
LUCY_RegexTokenizer_Destroy_IMP(lucy_RegexTokenizer *self) {
    dTHX;
    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
    CFISH_DECREF(ivars->pattern);
    ReREFCNT_dec(((REGEXP*)ivars->token_re));
    CFISH_SUPER_DESTROY(self, LUCY_REGEXTOKENIZER);
}
예제 #6
0
파일: Err.c 프로젝트: pavansondur/lucy
void
lucy_Err_throw_mess(lucy_VTable *vtable, lucy_CharBuf *message) {
    Lucy_Err_Make_t make
        = CFISH_METHOD_PTR(CFISH_CERTIFY(vtable, LUCY_VTABLE), Lucy_Err_Make);
    lucy_Err *err = (lucy_Err*)CFISH_CERTIFY(make(NULL), LUCY_ERR);
    Lucy_Err_Cat_Mess(err, message);
    CFISH_DECREF(message);
    lucy_Err_do_throw(err);
}
예제 #7
0
파일: FSDirHandle.c 프로젝트: theory/lucy
FSDirHandle*
FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
    size_t  dir_path_size = CB_Get_Size(dir);
    char   *dir_path_ptr  = (char*)CB_Get_Ptr8(dir);
    char    search_string[MAX_PATH + 1];
    char   *path_ptr = search_string;

    DH_init((DirHandle*)self, dir);
    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
    ivars->sys_dir_entry    = MALLOCATE(sizeof(WIN32_FIND_DATA));
    ivars->sys_dirhandle    = INVALID_HANDLE_VALUE;
    ivars->saved_error      = NULL;

    if (dir_path_size >= MAX_PATH - 2) {
        // Deal with Windows ceiling on file path lengths.
        Err_set_error(Err_new(CB_newf("Directory path is too long: %o",
                                      dir)));
        CFISH_DECREF(self);
        return NULL;
    }

    // Append trailing wildcard so Windows lists dir contents rather than just
    // the dir name itself.
    memcpy(path_ptr, dir_path_ptr, dir_path_size);
    memcpy(path_ptr + dir_path_size, "\\*\0", 3);

    ivars->sys_dirhandle
        = FindFirstFile(search_string, (WIN32_FIND_DATA*)ivars->sys_dir_entry);
    if (INVALID_HANDLE_VALUE == ivars->sys_dirhandle) {
        // Directory inaccessible or doesn't exist.
        Err_set_error(Err_new(CB_newf("Failed to open dir '%o'", dir)));
        CFISH_DECREF(self);
        return NULL;
    }
    else {
        // Compensate for the fact that FindFirstFile has already returned the
        // first entry but DirHandle's API requires that you call Next() to
        // start the iterator.
        ivars->delayed_iter = true;
    }

    return self;
}
예제 #8
0
파일: Err.c 프로젝트: pavansondur/lucy
void
lucy_Err_do_throw(lucy_Err *err) {
    dSP;
    SV *error_sv = (SV*)Lucy_Err_To_Host(err);
    CFISH_DECREF(err);
    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(sv_2mortal(error_sv));
    PUTBACK;
    call_pv("Clownfish::Err::do_throw", G_DISCARD);
    FREETMPS;
    LEAVE;
}
예제 #9
0
lucy_RegexTokenizer*
lucy_RegexTokenizer_init(lucy_RegexTokenizer *self,
                         cfish_String *pattern) {
    lucy_Analyzer_init((lucy_Analyzer*)self);
    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
    #define DEFAULT_PATTERN "\\w+(?:['\\x{2019}]\\w+)*"
    if (pattern) {
        if (CFISH_Str_Contains_Utf8(pattern, "\\p", 2)
            || CFISH_Str_Contains_Utf8(pattern, "\\P", 2)
           ) {
            CFISH_DECREF(self);
            THROW(CFISH_ERR, "\\p and \\P constructs forbidden");
        }
        ivars->pattern = CFISH_Str_Clone(pattern);
    }
    else {
        ivars->pattern = cfish_Str_new_from_trusted_utf8(
                            DEFAULT_PATTERN, sizeof(DEFAULT_PATTERN) - 1);
    }

    // Acquire a compiled regex engine for matching one token.
    dTHX;
    SV *token_re = S_compile_token_re(aTHX_ ivars->pattern);
#if (PERL_VERSION > 10)
    REGEXP *rx = SvRX((SV*)token_re);
#else
    if (!SvROK(token_re)) {
        THROW(CFISH_ERR, "token_re is not a qr// entity");
    }
    SV *inner = SvRV(token_re);
    MAGIC *magic = NULL;
    if (SvMAGICAL((SV*)inner)) {
        magic = mg_find((SV*)inner, PERL_MAGIC_qr);
    }
    if (!magic) {
        THROW(CFISH_ERR, "token_re is not a qr// entity");
    }
    REGEXP *rx = (REGEXP*)magic->mg_obj;
#endif
    if (rx == NULL) {
        THROW(CFISH_ERR, "Failed to extract REGEXP from token_re '%s'",
              SvPV_nolen((SV*)token_re));
    }
    ivars->token_re = rx;
    (void)ReREFCNT_inc(((REGEXP*)ivars->token_re));
    SvREFCNT_dec(token_re);

    return self;
}
예제 #10
0
FSFileHandle*
FSFH_do_open(FSFileHandle *self, const CharBuf *path, uint32_t flags) {
    FH_do_open((FileHandle*)self, path, flags);
    if (!path || !CB_Get_Size(path)) {
        Err_set_error(Err_new(CB_newf("Missing required param 'path'")));
        CFISH_DECREF(self);
        return NULL;
    }

    // Attempt to open file.
    if (flags & FH_WRITE_ONLY) {
        self->fd = open((char*)CB_Get_Ptr8(path), SI_posix_flags(flags), 0666);
        if (self->fd == -1) {
            self->fd = 0;
            Err_set_error(Err_new(CB_newf("Attempt to open '%o' failed: %s",
                                          path, strerror(errno))));
            CFISH_DECREF(self);
            return NULL;
        }
        if (flags & FH_EXCLUSIVE) {
            self->len = 0;
        }
        else {
            // Derive length.
            self->len = lseek64(self->fd, I64_C(0), SEEK_END);
            if (self->len == -1) {
                Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s",
                                              self->path, strerror(errno))));
                CFISH_DECREF(self);
                return NULL;
            }
            else {
                int64_t check_val = lseek64(self->fd, I64_C(0), SEEK_SET);
                if (check_val == -1) {
                    Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s",
                                                  self->path, strerror(errno))));
                    CFISH_DECREF(self);
                    return NULL;
                }
            }
        }
    }
    else if (flags & FH_READ_ONLY) {
        if (SI_init_read_only(self)) {
            // On 64-bit systems, map the whole file up-front.
            if (IS_64_BIT && self->len) {
                self->buf = (char*)SI_map(self, 0, self->len);
                if (!self->buf) {
                    // An error occurred during SI_map, which has set
                    // Err_error for us already.
                    CFISH_DECREF(self);
                    return NULL;
                }
            }
        }
        else {
            CFISH_DECREF(self);
            return NULL;
        }
    }
    else {
        Err_set_error(Err_new(CB_newf("Must specify FH_READ_ONLY or FH_WRITE_ONLY to open '%o'",
                                      path)));
        CFISH_DECREF(self);
        return NULL;
    }

    return self;
}
예제 #11
0
파일: Inverter.c 프로젝트: rlugojr/lucy
void
LUCY_Inverter_Invert_Doc_IMP(lucy_Inverter *self, lucy_Doc *doc) {
    dTHX;
    HV  *const fields = (HV*)LUCY_Doc_Get_Fields(doc);
    I32  num_keys     = hv_iterinit(fields);

    // Prepare for the new doc.
    LUCY_Inverter_Set_Doc(self, doc);

    // Extract and invert the doc's fields.
    while (num_keys--) {
        HE *hash_entry = hv_iternext(fields);
        lucy_InverterEntry *inv_entry = S_fetch_entry(aTHX_ self, hash_entry);
        SV *value_sv = HeVAL(hash_entry);
        lucy_InverterEntryIVARS *const entry_ivars
            = lucy_InvEntry_IVARS(inv_entry);
        lucy_FieldType *type = entry_ivars->type;
        cfish_Obj *obj = NULL;

        // Get the field value, forcing text fields to UTF-8.
        switch (LUCY_FType_Primitive_ID(type) & lucy_FType_PRIMITIVE_ID_MASK) {
            case lucy_FType_TEXT: {
                    STRLEN val_len;
                    char *val_ptr = SvPVutf8(value_sv, val_len);
                    obj = (cfish_Obj*)cfish_Str_new_wrap_trusted_utf8(val_ptr,
                                                                      val_len);
                    break;
                }
            case lucy_FType_BLOB: {
                    STRLEN val_len;
                    char *val_ptr = SvPV(value_sv, val_len);
                    obj = (cfish_Obj*)cfish_Blob_new_wrap(val_ptr, val_len);
                    break;
                }
            case lucy_FType_INT32: {
                    obj = (cfish_Obj*)cfish_Int_new(SvIV(value_sv));
                    break;
                }
            case lucy_FType_INT64: {
                    // nwellnhof: Using SvNOK could avoid a int/float/int
                    // round-trip with 32-bit IVs.
                    int64_t val = sizeof(IV) == 8
                                  ? SvIV(value_sv)
                                  : (int64_t)SvNV(value_sv); // lossy
                    obj = (cfish_Obj*)cfish_Int_new(val);
                    break;
                }
            case lucy_FType_FLOAT32:
            case lucy_FType_FLOAT64: {
                    obj = (cfish_Obj*)cfish_Float_new(SvNV(value_sv));
                    break;
                }
            default:
                THROW(CFISH_ERR, "Unrecognized type: %o", type);
        }

        CFISH_DECREF(entry_ivars->value);
        entry_ivars->value = obj;

        LUCY_Inverter_Add_Field(self, inv_entry);
    }
}
예제 #12
0
파일: Err.c 프로젝트: pavansondur/lucy
void
lucy_Err_set_error(lucy_Err *error) {
    lucy_Host_callback(LUCY_ERR, "set_error", 1,
                       CFISH_ARG_OBJ("error", error));
    CFISH_DECREF(error);
}
예제 #13
0
void
lucy_RegexTokenizer_destroy(lucy_RegexTokenizer *self) {
    CFISH_DECREF(self->pattern);
    ReREFCNT_dec(((REGEXP*)self->token_re));
    LUCY_SUPER_DESTROY(self, LUCY_REGEXTOKENIZER);
}