コード例 #1
0
ファイル: mustache.c プロジェクト: rcorrieri/core
static bool RenderVariable(Writer *out,
                           const char *content, size_t content_len,
                           bool escaped,
                           Seq *hash_stack)
{
    JsonElement *var = NULL;
    if (strncmp(content, ".", content_len) == 0)
    {
        var = SeqAt(hash_stack, SeqLength(hash_stack) - 1);
    }
    else
    {
        var = LookupVariable(hash_stack, content, content_len);
    }

    if (!var)
    {
        return true;
    }

    switch (JsonGetElementType(var))
    {
    case JSON_ELEMENT_TYPE_PRIMITIVE:
        return RenderVariablePrimitive(out, var, escaped);

    case JSON_ELEMENT_TYPE_CONTAINER:
        assert(false);
        return false;
    }

    assert(false);
    return false;
}
コード例 #2
0
ファイル: mustache.c プロジェクト: amousset/core
static bool RenderVariable(Buffer *out,
                           const char *content, size_t content_len,
                           TagType conversion,
                           Seq *hash_stack)
{
    JsonElement *var = NULL;
    bool escape = conversion == TAG_TYPE_VAR;
    bool serialize = conversion == TAG_TYPE_VAR_SERIALIZED;
    bool serialize_compact = conversion == TAG_TYPE_VAR_SERIALIZED_COMPACT;

    const bool item_mode = strncmp(content, ".", content_len) == 0;
    const bool key_mode = strncmp(content, "@", content_len) == 0;

    if (item_mode || key_mode)
    {
        var = SeqAt(hash_stack, SeqLength(hash_stack) - 1);
    }
    else
    {
        var = LookupVariable(hash_stack, content, content_len);
    }

    if (!var)
    {
        return true;
    }

    switch (JsonGetElementType(var))
    {
    case JSON_ELEMENT_TYPE_PRIMITIVE:
        // note that this also covers 'serialize' on primitives
        return RenderVariablePrimitive(out, var, escape, key_mode);

    case JSON_ELEMENT_TYPE_CONTAINER:
        if (serialize || serialize_compact)
        {
            return RenderVariableContainer(out, var, serialize_compact);
        }
        else
        {
            assert(false);
            return false;
        }
    }

    assert(false);
    return false;
}
コード例 #3
0
ファイル: mustache.c プロジェクト: amousset/core
static bool Render(Buffer *out, const char *start, const char *input, Seq *hash_stack,
                   char *delim_start, size_t *delim_start_len,
                   char *delim_end, size_t *delim_end_len,
                   bool skip_content,
                   const char *section,
                   const char **section_end)
{
    while (true)
    {
        if (!input)
        {
            Log(LOG_LEVEL_ERR, "Unexpected end to Mustache template");
            return false;
        }

        Mustache tag = NextTag(input, delim_start, *delim_start_len, delim_end, *delim_end_len);

        {
            const char *line_begin = NULL;
            const char *line_end = NULL;
            if (!IsTagTypeRenderable(tag.type) && IsTagStandalone(start, tag.begin, tag.end, &line_begin, &line_end))
            {
                RenderContent(out, input, line_begin - input, false, skip_content);
                input = line_end;
            }
            else
            {
                RenderContent(out, input, tag.begin - input, false, skip_content);
                input = tag.end;
            }
        }

        switch (tag.type)
        {
        case TAG_TYPE_ERR:
            return false;

        case TAG_TYPE_DELIM:
            if (!SetDelimiters(tag.content, tag.content_len,
                               delim_start, delim_start_len,
                               delim_end, delim_end_len))
            {
                return false;
            }
            continue;

        case TAG_TYPE_COMMENT:
            continue;

        case TAG_TYPE_NONE:
            return true;

        case TAG_TYPE_VAR_SERIALIZED:
        case TAG_TYPE_VAR_SERIALIZED_COMPACT:
        case TAG_TYPE_VAR_UNESCAPED:
        case TAG_TYPE_VAR:
            if (!skip_content)
            {
                if (tag.content_len > 0)
                {
                    if (!RenderVariable(out, tag.content, tag.content_len, tag.type, hash_stack))
                    {
                        return false;
                    }
                }
                else
                {
                    RenderContent(out, delim_start, *delim_start_len, false, false);
                    RenderContent(out, delim_end, *delim_end_len, false, false);
                }
            }
            continue;

        case TAG_TYPE_INVERTED:
        case TAG_TYPE_SECTION:
            {
                char *section = xstrndup(tag.content, tag.content_len);
                JsonElement *var = LookupVariable(hash_stack, tag.content, tag.content_len);
                SeqAppend(hash_stack, var);

                if (!var)
                {
                    const char *cur_section_end = NULL;
                    if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len,
                                skip_content || tag.type != TAG_TYPE_INVERTED, section, &cur_section_end))
                    {
                        free(section);
                        return false;
                    }
                    free(section);
                    input = cur_section_end;
                    continue;
                }

                switch (JsonGetElementType(var))
                {
                case JSON_ELEMENT_TYPE_PRIMITIVE:
                    switch (JsonGetPrimitiveType(var))
                    {
                    case JSON_PRIMITIVE_TYPE_BOOL:
                        {
                            bool skip = skip_content || (!JsonPrimitiveGetAsBool(var) ^ (tag.type == TAG_TYPE_INVERTED));

                            const char *cur_section_end = NULL;
                            if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len,
                                        skip, section, &cur_section_end))
                            {
                                free(section);
                                return false;
                            }
                            free(section);
                            input = cur_section_end;
                        }
                        continue;

                    default:
                        Log(LOG_LEVEL_WARNING, "Mustache sections can only take a boolean or a container (array or map) value, but section '%s' isn't getting one of those.",
                            section);
                        return false;
                    }
                    break;

                case JSON_ELEMENT_TYPE_CONTAINER:
                    switch (JsonGetContainerType(var))
                    {
                    case JSON_CONTAINER_TYPE_OBJECT:
                    case JSON_CONTAINER_TYPE_ARRAY:
                        if (JsonLength(var) > 0)
                        {
                            const char *cur_section_end = NULL;
                            for (size_t i = 0; i < JsonLength(var); i++)
                            {
                                JsonElement *child_hash = JsonAt(var, i);
                                SeqAppend(hash_stack, child_hash);


                                if (!Render(out, start, input,
                                            hash_stack,
                                            delim_start, delim_start_len, delim_end, delim_end_len,
                                            skip_content || tag.type == TAG_TYPE_INVERTED, section, &cur_section_end))
                                {
                                    free(section);
                                    return false;
                                }
                            }
                            input = cur_section_end;
                            free(section);
                        }
                        else
                        {
                            const char *cur_section_end = NULL;
                            if (!Render(out, start, input, hash_stack, delim_start, delim_start_len, delim_end, delim_end_len,
                                        tag.type != TAG_TYPE_INVERTED, section, &cur_section_end))
                            {
                                free(section);
                                return false;
                            }
                            free(section);
                            input = cur_section_end;
                        }
                        break;
                    }
                    break;
                }
            }
            continue;
        case TAG_TYPE_SECTION_END:
            if (!section)
            {
                char *varname = xstrndup(tag.content, tag.content_len);
                Log(LOG_LEVEL_WARNING, "Unknown section close in mustache template '%s'", varname);
                free(varname);
                return false;
            }
            else
            {
                SeqRemove(hash_stack, SeqLength(hash_stack) - 1);
                *section_end = input;
                return true;
            }
            break;

        default:
            assert(false);
            return false;
        }
    }

    assert(false);
}
コード例 #4
0
bool cGenreParseInfo::DoVarSubstitution( TSTRING &rval ) //throw( eParserHelper )
{
    cDebug d("cConfigFile::DoVarSubst()");
    d.TraceDebug("ORIG: %s\n", rval.c_str());

    // walk through string
    //      look for $(
    //          find matching )
    //          pick out subset
    //          look up in symbol table
    //          substitute subset
    //      continue iterating

    // step through string
    // iterate to (slen-1), because we are looking for a two-character sentinel "$("
    bool fEscaping = false;
    for (TSTRING::size_type i = 0; i < rval.size(); i++) 
    {
        TCHAR c = rval[i];

        // is it the "$(" sentinel? (an escaped '$' is not a variable)
        if (c == '$' && ! fEscaping ) 
        {
            c = rval[i+1];
            if (c == '(') 
            {
                // ooh, wow!  it's a variable!  find the end
                bool found = false;
                TSTRING::size_type j;

                for (j = i+1; j < rval.size(); j++) 
                {
                    if (rval[j] == ')') 
                    {
                        found = true;
                        break;
                    }
                }

                // did we find it?
                if (!found) 
                {
                    // TODO: throw error
                    return false;
                }

                // otherwise, cut out the variable name
                TSTRING::size_type begin = i + 2;
                TSTRING::size_type size = j - i - 2;
                TSTRING varname;
                varname = rval.substr(begin, size);

                d.TraceDebug("symbol = %s\n", varname.c_str());

                // look up in symbol table
                TSTRING varvalue;
                if ( ! LookupVariable( varname, varvalue ) ) 
                    throw eParserUseUndefVar( varname );

                // replace varname with varvalue
                rval.replace(begin-2, size+3, varvalue);

                d.TraceDebug("POST: %s\n", rval.c_str());

                // no no no
                // we should exit function, and get called again


                // update counters
                //      we should bump the cursor over by the length of the 
                //          varvalue (minus one, to compensate for post-increment of index)
                i += varvalue.size() - 1;
                goto nextchar;
            }
        }
        else if (c == '\\')
        {
            fEscaping = ! fEscaping;
        }
        else
        {
            fEscaping = false;
        }
nextchar:
        ;
    }



    d.TraceDebug("DONE: %s\n", rval.c_str());

    // switch around
    return true;
}