ngx_int_t
ngx_http_script_compile(ngx_http_script_compile_t *sc)
{
    u_char       ch;
    ngx_str_t    name;
    ngx_uint_t   i, bracket;
    if (ngx_http_script_init_arrays(sc) != NGX_OK) {
        return NGX_ERROR;
    }
    for (i = 0; i < sc->source->len;   ) {
        name.len = 0;
        if (sc->source->data[i] == '$') {
            if (++i == sc->source->len) {
                goto invalid_variable;
            }
#if (NGX_PCRE)
            {
            ngx_uint_t  n;
            if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
                n = sc->source->data[i] - '0';
                if (sc->captures_mask & (1 << n)) {
                    sc->dup_capture = 1;
                }
                sc->captures_mask |= 1 << n;
                if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {
                    return NGX_ERROR;
                }
                i++;
                continue;
            }
            }
#endif
            if (sc->source->data[i] == '{') {
                bracket = 1;
                if (++i == sc->source->len) {
                    goto invalid_variable;
                }
                name.data = &sc->source->data[i];
            } else {
                bracket = 0;
                name.data = &sc->source->data[i];
            }
            for (   ; i < sc->source->len; i++, name.len++) {
                ch = sc->source->data[i];
                if (ch == '}' && bracket) {
                    i++;
                    bracket = 0;
                    break;
                }
                if ((ch >= 'A' && ch <= 'Z')
                    || (ch >= 'a' && ch <= 'z')
                    || (ch >= '0' && ch <= '9')
                    || ch == '_')
                {
                    continue;
                }
                break;
            }
            if (bracket) {
                ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
                                   "the closing bracket in \"%V\" "
                                   "variable is missing", &name);
                return NGX_ERROR;
            }
            if (name.len == 0) {
                goto invalid_variable;
            }
            sc->variables++;
            if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {
                return NGX_ERROR;
            }
            continue;
        }
        if (sc->source->data[i] == '?' && sc->compile_args) {
            sc->args = 1;
            sc->compile_args = 0;
            if (ngx_http_script_add_args_code(sc) != NGX_OK) {
                return NGX_ERROR;
            }
            i++;
            continue;
        }
        name.data = &sc->source->data[i];
        while (i < sc->source->len) {
            if (sc->source->data[i] == '$') {
                break;
            }
            if (sc->source->data[i] == '?') {
                sc->args = 1;
                if (sc->compile_args) {
                    break;
                }
            }
            i++;
            name.len++;
        }
        sc->size += name.len;
        if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
            != NGX_OK)
        {
            return NGX_ERROR;
        }
    }
    return ngx_http_script_done(sc);
invalid_variable:
    ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
    return NGX_ERROR;
}
['static char *\nngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)\n{\n    u_char                            *data;\n    size_t                             len;\n    ngx_int_t                          rv;\n    ngx_str_t                         *value, v;\n    ngx_uint_t                         i, key;\n    ngx_http_map_conf_ctx_t           *ctx;\n    ngx_http_complex_value_t           cv, *cvp;\n    ngx_http_variable_value_t         *var, **vp;\n    ngx_http_compile_complex_value_t   ccv;\n    ctx = cf->ctx;\n    value = cf->args->elts;\n    if (cf->args->nelts == 1\n        && ngx_strcmp(value[0].data, "hostnames") == 0)\n    {\n        ctx->hostnames = 1;\n        return NGX_CONF_OK;\n    } else if (cf->args->nelts != 2) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           "invalid number of the map parameters");\n        return NGX_CONF_ERROR;\n    }\n    if (ngx_strcmp(value[0].data, "include") == 0) {\n        return ngx_conf_include(cf, dummy, conf);\n    }\n    key = 0;\n    for (i = 0; i < value[1].len; i++) {\n        key = ngx_hash(key, value[1].data[i]);\n    }\n    key %= ctx->keys.hsize;\n    vp = ctx->values_hash[key].elts;\n    if (vp) {\n        for (i = 0; i < ctx->values_hash[key].nelts; i++) {\n            if (vp[i]->valid) {\n                data = vp[i]->data;\n                len = vp[i]->len;\n            } else {\n                cvp = (ngx_http_complex_value_t *) vp[i]->data;\n                data = cvp->value.data;\n                len = cvp->value.len;\n            }\n            if (value[1].len != len) {\n                continue;\n            }\n            if (ngx_strncmp(value[1].data, data, len) == 0) {\n                var = vp[i];\n                goto found;\n            }\n        }\n    } else {\n        if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4,\n                           sizeof(ngx_http_variable_value_t *))\n            != NGX_OK)\n        {\n            return NGX_CONF_ERROR;\n        }\n    }\n    var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t));\n    if (var == NULL) {\n        return NGX_CONF_ERROR;\n    }\n    v.len = value[1].len;\n    v.data = ngx_pstrdup(ctx->keys.pool, &value[1]);\n    if (v.data == NULL) {\n        return NGX_CONF_ERROR;\n    }\n    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));\n    ccv.cf = ctx->cf;\n    ccv.value = &v;\n    ccv.complex_value = &cv;\n    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {\n        return NGX_CONF_ERROR;\n    }\n    if (cv.lengths != NULL) {\n        cvp = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_complex_value_t));\n        if (cvp == NULL) {\n            return NGX_CONF_ERROR;\n        }\n        *cvp = cv;\n        var->len = 0;\n        var->data = (u_char *) cvp;\n        var->valid = 0;\n    } else {\n        var->len = v.len;\n        var->data = v.data;\n        var->valid = 1;\n    }\n    var->no_cacheable = 0;\n    var->not_found = 0;\n    vp = ngx_array_push(&ctx->values_hash[key]);\n    if (vp == NULL) {\n        return NGX_CONF_ERROR;\n    }\n    *vp = var;\nfound:\n    if (ngx_strcmp(value[0].data, "default") == 0) {\n        if (ctx->default_value) {\n            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                               "duplicate default map parameter");\n            return NGX_CONF_ERROR;\n        }\n        ctx->default_value = var;\n        return NGX_CONF_OK;\n    }\n#if (NGX_PCRE)\n    if (value[0].len && value[0].data[0] == \'~\') {\n        ngx_regex_compile_t    rc;\n        ngx_http_map_regex_t  *regex;\n        u_char                 errstr[NGX_MAX_CONF_ERRSTR];\n        regex = ngx_array_push(&ctx->regexes);\n        if (regex == NULL) {\n            return NGX_CONF_ERROR;\n        }\n        value[0].len--;\n        value[0].data++;\n        ngx_memzero(&rc, sizeof(ngx_regex_compile_t));\n        if (value[0].data[0] == \'*\') {\n            value[0].len--;\n            value[0].data++;\n            rc.options = NGX_REGEX_CASELESS;\n        }\n        rc.pattern = value[0];\n        rc.err.len = NGX_MAX_CONF_ERRSTR;\n        rc.err.data = errstr;\n        regex->regex = ngx_http_regex_compile(ctx->cf, &rc);\n        if (regex->regex == NULL) {\n            return NGX_CONF_ERROR;\n        }\n        regex->value = var;\n        return NGX_CONF_OK;\n    }\n#endif\n    if (value[0].len && value[0].data[0] == \'\\\\\') {\n        value[0].len--;\n        value[0].data++;\n    }\n    rv = ngx_hash_add_key(&ctx->keys, &value[0], var,\n                          (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);\n    if (rv == NGX_OK) {\n        return NGX_CONF_OK;\n    }\n    if (rv == NGX_DECLINED) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           "invalid hostname or wildcard \\"%V\\"", &value[0]);\n    }\n    if (rv == NGX_BUSY) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           "conflicting parameter \\"%V\\"", &value[0]);\n    }\n    return NGX_CONF_ERROR;\n}', 'u_char *\nngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)\n{\n    u_char  *dst;\n    dst = ngx_pnalloc(pool, src->len);\n    if (dst == NULL) {\n        return NULL;\n    }\n    ngx_memcpy(dst, src->data, src->len);\n    return dst;\n}', "ngx_int_t\nngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)\n{\n    ngx_str_t                  *v;\n    ngx_uint_t                  i, n, nv, nc;\n    ngx_array_t                 flushes, lengths, values, *pf, *pl, *pv;\n    ngx_http_script_compile_t   sc;\n    v = ccv->value;\n    nv = 0;\n    nc = 0;\n    for (i = 0; i < v->len; i++) {\n        if (v->data[i] == '$') {\n            if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {\n                nc++;\n            } else {\n                nv++;\n            }\n        }\n    }\n    if ((v->len == 0 || v->data[0] != '$')\n        && (ccv->conf_prefix || ccv->root_prefix))\n    {\n        if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {\n            return NGX_ERROR;\n        }\n        ccv->conf_prefix = 0;\n        ccv->root_prefix = 0;\n    }\n    ccv->complex_value->value = *v;\n    ccv->complex_value->flushes = NULL;\n    ccv->complex_value->lengths = NULL;\n    ccv->complex_value->values = NULL;\n    if (nv == 0 && nc == 0) {\n        return NGX_OK;\n    }\n    n = nv + 1;\n    if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))\n        != NGX_OK)\n    {\n        return NGX_ERROR;\n    }\n    n = nv * (2 * sizeof(ngx_http_script_copy_code_t)\n                  + sizeof(ngx_http_script_var_code_t))\n        + sizeof(uintptr_t);\n    if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {\n        return NGX_ERROR;\n    }\n    n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)\n                   + sizeof(ngx_http_script_var_code_t))\n                + sizeof(uintptr_t)\n                + v->len\n                + sizeof(uintptr_t) - 1)\n            & ~(sizeof(uintptr_t) - 1);\n    if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {\n        return NGX_ERROR;\n    }\n    pf = &flushes;\n    pl = &lengths;\n    pv = &values;\n    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));\n    sc.cf = ccv->cf;\n    sc.source = v;\n    sc.flushes = &pf;\n    sc.lengths = &pl;\n    sc.values = &pv;\n    sc.complete_lengths = 1;\n    sc.complete_values = 1;\n    sc.zero = ccv->zero;\n    sc.conf_prefix = ccv->conf_prefix;\n    sc.root_prefix = ccv->root_prefix;\n    if (ngx_http_script_compile(&sc) != NGX_OK) {\n        return NGX_ERROR;\n    }\n    if (flushes.nelts) {\n        ccv->complex_value->flushes = flushes.elts;\n        ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;\n    }\n    ccv->complex_value->lengths = lengths.elts;\n    ccv->complex_value->values = values.elts;\n    return NGX_OK;\n}", 'ngx_int_t\nngx_http_script_compile(ngx_http_script_compile_t *sc)\n{\n    u_char       ch;\n    ngx_str_t    name;\n    ngx_uint_t   i, bracket;\n    if (ngx_http_script_init_arrays(sc) != NGX_OK) {\n        return NGX_ERROR;\n    }\n    for (i = 0; i < sc->source->len;   ) {\n        name.len = 0;\n        if (sc->source->data[i] == \'$\') {\n            if (++i == sc->source->len) {\n                goto invalid_variable;\n            }\n#if (NGX_PCRE)\n            {\n            ngx_uint_t  n;\n            if (sc->source->data[i] >= \'1\' && sc->source->data[i] <= \'9\') {\n                n = sc->source->data[i] - \'0\';\n                if (sc->captures_mask & (1 << n)) {\n                    sc->dup_capture = 1;\n                }\n                sc->captures_mask |= 1 << n;\n                if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {\n                    return NGX_ERROR;\n                }\n                i++;\n                continue;\n            }\n            }\n#endif\n            if (sc->source->data[i] == \'{\') {\n                bracket = 1;\n                if (++i == sc->source->len) {\n                    goto invalid_variable;\n                }\n                name.data = &sc->source->data[i];\n            } else {\n                bracket = 0;\n                name.data = &sc->source->data[i];\n            }\n            for (   ; i < sc->source->len; i++, name.len++) {\n                ch = sc->source->data[i];\n                if (ch == \'}\' && bracket) {\n                    i++;\n                    bracket = 0;\n                    break;\n                }\n                if ((ch >= \'A\' && ch <= \'Z\')\n                    || (ch >= \'a\' && ch <= \'z\')\n                    || (ch >= \'0\' && ch <= \'9\')\n                    || ch == \'_\')\n                {\n                    continue;\n                }\n                break;\n            }\n            if (bracket) {\n                ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,\n                                   "the closing bracket in \\"%V\\" "\n                                   "variable is missing", &name);\n                return NGX_ERROR;\n            }\n            if (name.len == 0) {\n                goto invalid_variable;\n            }\n            sc->variables++;\n            if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {\n                return NGX_ERROR;\n            }\n            continue;\n        }\n        if (sc->source->data[i] == \'?\' && sc->compile_args) {\n            sc->args = 1;\n            sc->compile_args = 0;\n            if (ngx_http_script_add_args_code(sc) != NGX_OK) {\n                return NGX_ERROR;\n            }\n            i++;\n            continue;\n        }\n        name.data = &sc->source->data[i];\n        while (i < sc->source->len) {\n            if (sc->source->data[i] == \'$\') {\n                break;\n            }\n            if (sc->source->data[i] == \'?\') {\n                sc->args = 1;\n                if (sc->compile_args) {\n                    break;\n                }\n            }\n            i++;\n            name.len++;\n        }\n        sc->size += name.len;\n        if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))\n            != NGX_OK)\n        {\n            return NGX_ERROR;\n        }\n    }\n    return ngx_http_script_done(sc);\ninvalid_variable:\n    ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");\n    return NGX_ERROR;\n}']