size_t _FindMainFunction( eastl::string& str )//找到主函数段 { size_t start_pos = 0; do { start_pos = str.find("main", start_pos); if( start_pos != eastl::string::npos ) { size_t i = -1; bool istype = false; do { istype = ! Utility::NotVariablePart( str[ start_pos + i-- ] ); } while ( !istype ); if ( 'd' == str[start_pos + ++i] ) { start_pos = str.find("{", start_pos); return start_pos + 1; } } start_pos++; } while ( start_pos != eastl::string::npos ); return eastl::string::npos; }
bool _VariableModifier_Type( eastl::string& str, const eastl::string& vname, const char* modifier, eastl::string& type )//是否为某种修饰类型的变量 { size_t start_pos = 0; do { start_pos = str.find( vname, start_pos ); if ( start_pos != eastl::string::npos ) { size_t trunk = str.find_last_of( ';', start_pos ); trunk = trunk != eastl::string::npos ? trunk : 0; string substr = str.substr( trunk, start_pos - trunk ); size_t istype = substr.find( modifier ); if ( istype != eastl::string::npos ) { type = substr.substr( substr.find_first_of(' ') ); return true; } start_pos += vname.size(); } } while ( start_pos != eastl::string::npos ); return false; }
// Parses the entire shader string buffer to match instances of the program meta flag // Format of the shader usage flags: "!!>:(Flag Type, <Values, sep. by comma>)" // Flag Type can be either Usage or Permute void UProgramPermutor::ParseProgramMetaFlags(const eastl::string& inShaderBufferString, eastl::vector<SShaderMetaFlagInstance>& outMetaFlagInstances) { // Find all occurrences of shader meta flag string size_t currentFindIndex = inShaderBufferString.find(s_shaderMetaFlagString, 0); outMetaFlagInstances.clear(); while (currentFindIndex != eastl::string::npos) { eastl::string metaFlagInstanceString; currentFindIndex += UProgramPermutor::s_shaderMetaFlagString.length(); while (inShaderBufferString[currentFindIndex] != ')') { metaFlagInstanceString += inShaderBufferString[currentFindIndex]; ++currentFindIndex; } ++currentFindIndex; // Skip past the ending parentheses if (metaFlagInstanceString.empty()) { LOG(LogProgramPermutor, Warning, "Warning: Shader usage instance #%d has an empty description pair!", outMetaFlagInstances.size()); return; } eastl::vector<eastl::string> metaFlagSubstrings; SShaderMetaFlagInstance currentMetaFlagInstance; // Split the meta flag string by coma size_t currentCommaIndex = 0; size_t nextCommaIndex = metaFlagInstanceString.find(',', currentCommaIndex); while (nextCommaIndex != eastl::string::npos) { eastl::string flagValueString = metaFlagInstanceString.substr(currentCommaIndex, (nextCommaIndex - currentCommaIndex)); metaFlagSubstrings.emplace_back(flagValueString); currentCommaIndex = nextCommaIndex + 1; nextCommaIndex = metaFlagInstanceString.find(',', currentCommaIndex); if (nextCommaIndex == eastl::string::npos) { eastl::string lastFlagValueString = metaFlagInstanceString.substr(currentCommaIndex, (nextCommaIndex - currentCommaIndex)); // On the last iteration, we need to add the last string metaFlagSubstrings.emplace_back(lastFlagValueString); } } // Flag string count sanity check if (metaFlagSubstrings.size() == 0) { LOG(LogProgramPermutor, Warning, "Warning: Shader usage instance #%d has more than one separation commas!", outMetaFlagInstances.size()); return; } // First substring is the flag type currentMetaFlagInstance.MetaFlagType = ConvertStringToFlagType(metaFlagSubstrings.front()); if (currentMetaFlagInstance.MetaFlagType == EMetaFlagType::EMetaFlagType_Invalid) { LOG(LogProgramPermutor, Warning, "Warning: Shader usage instance #%d has an invalid meta flag type!", outMetaFlagInstances.size()); return; } // Rest of the substrings are the parameter values (if applicable) for (size_t i = 1; i < metaFlagSubstrings.size(); ++i) { currentMetaFlagInstance.MetaFlagValues.emplace_back(metaFlagSubstrings[i]); } outMetaFlagInstances.emplace_back(currentMetaFlagInstance); currentFindIndex = inShaderBufferString.find(UProgramPermutor::s_shaderMetaFlagString, currentFindIndex); } }