Ejemplo n.º 1
0
static ejsval
_ejs_path_resolve (ejsval env, ejsval _this, uint32_t argc, ejsval* args)
{
    // FIXME node's implementation is a lot more flexible.  we just combine the paths with a / between them.
    ejsval from = args[0];
    ejsval to = args[1];
    return _ejs_string_concat (from, _ejs_string_concat (_ejs_string_new_utf8("/"), to));
}
Ejemplo n.º 2
0
// ECMA262 15.3.4.5
static ejsval
_ejs_Function_prototype_bind (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    /* 1. Let Target be the this value. */
    ejsval Target = _this;

    /* 2. If IsCallable(Target) is false, throw a TypeError exception. */
    if (!EJSVAL_IS_CALLABLE(Target)) {
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function");
    }

    ejsval thisArg = _ejs_undefined;
    if (argc > 0)
        thisArg = args[0];

    /* 3. Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order. */
    int bound_argc = argc > 1 ? argc - 1 : 0;

    /* 4. Let F be a new native ECMAScript object . */

    ejsval bound_env = EJS_BOUNDFUNC_ENV_NEW(bound_argc);
    EJS_BOUNDFUNC_ENV_SET_TARGET(bound_env, Target);
    EJS_BOUNDFUNC_ENV_SET_THIS(bound_env, thisArg);
    EJS_BOUNDFUNC_ENV_SET_ARGC(bound_env, NUMBER_TO_EJSVAL(bound_argc));
    for (int i = 0; i < bound_argc; i ++) {
        EJS_BOUNDFUNC_ENV_SET_ARG(bound_env, i, args[i+1]);
    }

    ejsval target_name = _ejs_object_getprop (Target, _ejs_atom_name);
    ejsval bound_name;
    if (EJSVAL_IS_STRING(target_name))
        bound_name = _ejs_string_concat(_ejs_atom_bound_space, target_name);
    else
        bound_name = _ejs_atom_bound_space;
    

    ejsval F = _ejs_function_new (bound_env, bound_name, bound_wrapper);
    EJSFunction *F_ = (EJSFunction*)EJSVAL_TO_OBJECT(F);

    F_->bound = EJS_TRUE;

    return F;
}
Ejemplo n.º 3
0
static ejsval
Encode (ejsval string, ejsval unescaped)
{
    EJSPrimString *stringObj = EJSVAL_TO_STRING(string);
    jschar *unescapedStr = EJSVAL_TO_FLAT_STRING(unescaped);

    /* 1. Let strLen be the number of code units in string. */
    int32_t strLen = stringObj->length;

    /* 2. Let R be the empty String. */
    ejsval R = _ejs_atom_empty;

    /* 3. Let k be 0. */
    int32_t k = 0;

    /* 4. Repeat. */
    for (;;) {
        /* a. If k equals strLen, return R. */
        if (k == strLen)
            return R;

        /* b. Let C be the code unit at index k within string. */
        jschar C = _ejs_string_ucs2_at (stringObj, k);
        jschar C_arr [2] = { C, 0 };

        /* c. If C is in unescapedSet, then */
        jschar *p = ucs2_strstr (unescapedStr, C_arr);
        if (p) {
            /* i. Let S be a String containing only the code unit C. */
            ejsval S = _ejs_string_new_substring (string, k, 1);

            /* ii. Let R be a new String value computed by concatenating the previous value of R and S. */
            R = _ejs_string_concat (R, S);
        }
        /* d. Else C is not in unescapedSet, */
        else {
            /* i. If the code unit value of C is not less than 0xDC00 and not greater than 0xDFFF, throw a URIError exception. */
            if (C >= 0xDC00 && C <= 0xDFFF)
                _ejs_throw_nativeerror_utf8 (EJS_URI_ERROR, "URI malformed");

            /* ii. If the code unit value of C is less than 0xD800 or greater than 0xDBFF, then Let V be the code unit value of C. */
            jschar V;
            if (C < 0xD800 || C > 0xDBFF)
                V = C;
            /* iii. Else, */
            else {
                /* 1. Increase k by 1. */
                k++;

                /* 2. If k equals strLen, throw a URIError exception. */
                if (k == strLen)
                    _ejs_throw_nativeerror_utf8 (EJS_URI_ERROR, "URI malformed");

                /* 3. Let kChar be the code unit value of the code unit at index k within string. */
                jschar kChar = _ejs_string_ucs2_at (stringObj, k);

                /* 4. If kChar is less than 0xDC00 or greater than 0xDFFF, throw a URIError exception. */
                if (kChar < 0xDC00 || kChar > 0xDFFF)
                    _ejs_throw_nativeerror_utf8 (EJS_URI_ERROR, "URI malformed");

                /* 5. Let V be (((the code unit value of C) – 0xD800) × 0x400 + (kChar – 0xDC00) + 0x10000). */
                V = (C - 0xD800) * 0x400 + (kChar - 0xDC00) + 0x10000;
            }

            /* iv. Let Octets be the array of octets resulting by applying the UTF-8 transformation to V, and let L be the array size. */
            char octets[4];
            int32_t L = ucs2_to_utf8_char (V, octets);

            /* v. Let j be 0. */
            int32_t j = 0;

            /* vi. Repeat, while j < L. */
            while (j < L) {
                /* 1.  Let jOctet be the value at index j within Octets. */
                char jOctet = octets [j];

                /* 2. Let S be a String containing three code units “%XY” where XY are two uppercase hexadecimal
                 * digits encoding the value of jOctet. */
                char buff[4];
                sprintf(buff, "%%%X", jOctet);
                ejsval S = _ejs_string_new_utf8 (buff);

                /* 3. Let R be a new String value computed by concatenating the previous value of R and S. */
                R = _ejs_string_concat (R, S);

                /* 4. Increase j by 1. */
                j++;
            }
        }

        /* e. Increase k by 1. */
        k++;
    }
}
Ejemplo n.º 4
0
static ejsval JA(StringifyState *state, ejsval value);
static ejsval JO(StringifyState *state, ejsval value);
static ejsval Quote(StringifyState *state, ejsval value);
static ejsval Str(StringifyState *state, ejsval key, ejsval holder);

static ejsval
JA(StringifyState *state, ejsval value)
{
    ejsval final;

    /* 1. If stack contains value then throw a TypeError exception because the structure is cyclical. */
    /* 2. Append value to stack. */
    /* 3. Let stepback be indent. */
    ejsval stepback = state->indent;
    /* 4. Let indent be the concatenation of indent and gap. */
    state->indent = _ejs_string_concat (state->indent, state->gap);
    /* 5. Let partial be an empty List. */
    ejsval partial = _ejs_array_new (0, EJS_FALSE);

    /* 6. Let len be the result of calling the [[Get]] internal method of value with argument "length". */
    int len = EJS_ARRAY_LEN(value);

    /* 7. Let index be 0. */
    int index = 0;

    /* 8. Repeat while index < len */
    while (index < len) {
        /*    a. Let strP be the result of calling the abstract operation Str with arguments ToString(index) and value.  */
        ejsval strP = Str (state, NUMBER_TO_EJSVAL(index), value);
        /*    b. If strP is undefined */
        if (EJSVAL_IS_UNDEFINED(strP)) {
Ejemplo n.º 5
0
static ejsval
_ejs_path_relative (ejsval env, ejsval _this, uint32_t argc, ejsval* args)
{
    ejsval from = _ejs_undefined;
    ejsval to   = _ejs_undefined;

    if (argc > 0) from = args[0];
    if (argc > 1) to   = args[1];

    if (!EJSVAL_IS_STRING(from) || !EJSVAL_IS_STRING(to))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Arguments to path.relative must be strings");

    char *from_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(from));
    char *to_utf8   = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(to));

    if (from_utf8[0] != '/') from_utf8 = make_absolute(from_utf8);
    if (to_utf8[0]   != '/') to_utf8   = make_absolute(to_utf8);

    char* p = to_utf8 + strlen(to_utf8) - 1;
    int up = 0;
    EJSBool seen_slash = EJS_FALSE;

    while (p != to_utf8) {
        if (*p == '/') {
            if (seen_slash) continue; // skip adjacent slashes
            seen_slash = EJS_TRUE;
            char* prefix = strndup(to_utf8, p - to_utf8);
            if (!strcmp(from_utf8, prefix)) {
                up = -1;
                free (prefix);
                goto done;
            }
            if (strstr(from_utf8, prefix) == from_utf8) {
                free (prefix);
                goto done;
            }
            free (prefix);
            up ++;
        }
        else {
            seen_slash = EJS_FALSE;
        }
        p--;
    }
    // we made it all the way to the end, fall through to building up our string

 done:
    {
        ejsval dotdotslash = _ejs_string_new_utf8("../");
        ejsval rv = _ejs_string_new_utf8(p+1);
        while (up >= 0) {
            rv = _ejs_string_concat(dotdotslash, rv);
            up--;
        }

        free (from_utf8);
        free (to_utf8);

        return rv;
    }
}
Ejemplo n.º 6
0
ejsval
_ejs_regexp_replace(ejsval str, ejsval search_re, ejsval replace)
{
    EJSRegExp* re = (EJSRegExp*)EJSVAL_TO_OBJECT(search_re);

    pcre16_extra extra;
    memset (&extra, 0, sizeof(extra));

    pcre16* code = (pcre16*)re->compiled_pattern;

    int capture_count;
    pcre16_fullinfo (code, NULL, PCRE_INFO_CAPTURECOUNT, &capture_count);

    int ovec_count = 3 * (1 + capture_count);
    int* ovec = malloc(sizeof(int) * ovec_count);
    int cur_off = 0;

    do {
        EJSPrimString *flat_str = _ejs_string_flatten (str);
        jschar *chars_str = flat_str->data.flat;

        int rv = pcre16_exec(code, &extra,
                             chars_str, flat_str->length, cur_off,
                             PCRE_NO_UTF16_CHECK, ovec, ovec_count);

        if (rv < 0)
            break;

        ejsval replaceval;

        if (EJSVAL_IS_FUNCTION(replace)) {
            ejsval substr_match = _ejs_string_new_substring (str, ovec[0], ovec[1] - ovec[0]);
            ejsval capture = _ejs_string_new_substring (str, ovec[2], ovec[3] - ovec[2]);

            _ejs_log ("substring match is %s\n", ucs2_to_utf8(_ejs_string_flatten(substr_match)->data.flat));
            _ejs_log ("capture is %s\n", ucs2_to_utf8(_ejs_string_flatten(capture)->data.flat));

            int argc = 3;
            ejsval args[3];

            args[0] = substr_match;
            args[1] = capture;
            args[2] = _ejs_undefined;

            replaceval = ToString(_ejs_invoke_closure (replace, _ejs_undefined, argc, args));
        }
        else {
            replaceval = ToString(replace);
        }

        if (ovec[0] == 0) {
            // we matched from the beginning of the string, so nothing from there to prepend
            str = _ejs_string_concat (replaceval, _ejs_string_new_substring (str, ovec[1], flat_str->length - ovec[1]));
        }
        else {
            str = _ejs_string_concatv (_ejs_string_new_substring (str, 0, ovec[0]),
                                       replaceval,
                                       _ejs_string_new_substring (str, ovec[1], flat_str->length - ovec[1]),
                                       _ejs_null);
        }

        cur_off = ovec[1];

        // if the RegExp object was created without a 'g' flag, only replace the first match
        if (!re->global)
            break;
    } while (EJS_TRUE);

    free (ovec);
    return str;
}