static std::string FixShaderCode(char *text, int textLength, const UniformRules &uniformsRename, bool vertexShader)
{
    struct ReplacePair
    {
        ReplacePair(const char *pat, const char *rep) :
            pattern(boost::xpressive::sregex::compile(pat,
                                                      (boost::xpressive::regex_constants::ECMAScript |
                                                       boost::xpressive::regex_constants::optimize))),
            replace(rep)
        {
        }

        boost::xpressive::sregex pattern;
        std::string replace;
    };

    static const ReplacePair sFixPairs[] =
    {
        ReplacePair("\\.0+E\\+0+\\b", ".0"),
        ReplacePair("0*E\\+0+\\b", ""),
        ReplacePair("(\\d+)\\.([0-9][1-9])0*E\\+0+2\\b", "$1$2.0"),
        ReplacePair("(\\d+)\\.([1-9])0*E\\+0+1\\b", "$1$2.0"),
        ReplacePair("(\\d+)\\.0+E\\-0+1\\b", "0.$1"),
        ReplacePair("(\\d+)\\.00+E(\\+\\d+)\\b", "$1.0E$2"),
        ReplacePair("ATI_draw_buffers", "ARB_draw_buffers"),
        ReplacePair("\\:require\\n", ":enable\n"),
        ReplacePair("#version \\d+", ""),
    };

    static const boost::xpressive::sregex structPattern(boost::xpressive::sregex::compile("\\bstruct\\s+(\\w+)\\s*{[^}]*};",
                                                                                          (boost::xpressive::regex_constants::ECMAScript |
                                                                                           boost::xpressive::regex_constants::optimize)));
    static const int subs[] = {1};

    std::string newtext(text, textLength);

    // Find all the struct declarations
    std::list<std::string> structsList;
    boost::xpressive::sregex_token_iterator cur(newtext.begin(), newtext.end(), structPattern, subs);
    boost::xpressive::sregex_token_iterator end;
    for(; cur != end; ++cur )
    {
        structsList.push_back(*cur);
    }

    // Remove unused struct declarations
    if (!structsList.empty())
    {
        const std::list<std::string>::const_iterator itEnd(structsList.end());
        for (std::list<std::string>::const_iterator it = structsList.begin(); it != itEnd; ++it)
        {
            const std::string &structName(*it);
            boost::xpressive::sregex_iterator cur(newtext.begin(), newtext.end(),
                                                  (boost::xpressive::_b >> structName >> boost::xpressive::_b));
            boost::xpressive::sregex_iterator end;
            int count = 0;
            for(; cur != end; ++cur, ++count)
            {
            }
            if (1 >= count)
            {
                const boost::xpressive::sregex removeStructPattern(boost::xpressive::sregex::compile("\\bstruct\\s+" + structName + "\\s*{[^}]*};"));
                newtext = regex_replace(newtext, removeStructPattern, std::string(""));
            }
        }
        structsList.clear();
    }

    // Fix numbers and GLSL 'require's
    const size_t numPairs = sizeof(sFixPairs) / sizeof(ReplacePair);
    for (size_t n = 0; n < numPairs; n++)
    {
        newtext = regex_replace(newtext, sFixPairs[n].pattern, sFixPairs[n].replace);
    }

    // Fix names of uniform values
    const UniformRules::const_iterator itEnd(uniformsRename.end());
    for (UniformRules::const_iterator it = uniformsRename.begin(); it != itEnd; ++it)
    {
        newtext = regex_replace(newtext, (it->first), (it->second));
    }

    // Fix vertex attributes
    if (vertexShader)
    {
        struct AttributeReplaceRule
        {
            AttributeReplaceRule(const char *src, const char *dst, const char *tn) :
                re(boost::xpressive::_b >> src >> boost::xpressive::_b),
                replace(dst),
                typeName(tn)
            {
            }

            boost::xpressive::sregex re;
            std::string replace;
            const char *typeName;
        };

        static const AttributeReplaceRule sAttributeReplaceRules[] =
        {
            AttributeReplaceRule("gl_Vertex",         "ATTR0",  "vec4"),
            AttributeReplaceRule("gl_Normal",         "ATTR2",  "vec3"),
            AttributeReplaceRule("gl_Color",          "ATTR3",  "vec4"),
            AttributeReplaceRule("gl_SecondaryColor", "ATTR4",  "vec4"),
            AttributeReplaceRule("gl_FogCoord",       "ATTR5",  "float"),
            AttributeReplaceRule("gl_MultiTexCoord0", "ATTR8",  "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord1", "ATTR9",  "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord2", "ATTR10", "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord3", "ATTR11", "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord4", "ATTR12", "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord5", "ATTR13", "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord6", "ATTR14", "vec4"),
            AttributeReplaceRule("gl_MultiTexCoord7", "ATTR15", "vec4")
        };

        const size_t numRules = sizeof(sAttributeReplaceRules) / sizeof(AttributeReplaceRule);
        for (size_t n = numRules; n--; )
        {
            const AttributeReplaceRule &rule(sAttributeReplaceRules[n]);
            if (regex_search(newtext, rule.re))
            {
                newtext = regex_replace(newtext, rule.re, rule.replace);
                newtext = std::string("attribute ") + rule.typeName + " " + rule.replace + ";" + newtext;
            }
        }
    }
Exemple #2
0
std::string Regex::Match::replace(std::string rep, unsigned int index)
{
    ReplaceMap tmp;
    tmp.insert(ReplacePair(index,rep));
    return replace(tmp);
}