static boolean createTagsForWildcardUsingFindfirst (const char *const pattern) { boolean resize = FALSE; const size_t dirLength = baseFilename (pattern) - pattern; #if defined (HAVE_FINDFIRST) struct ffblk fileInfo; int result = findfirst (pattern, &fileInfo, FA_DIREC); while (result == 0) { const char *const entry = (const char *) fileInfo.ff_name; resize |= createTagsForWildcardEntry (pattern, dirLength, entry); result = findnext (&fileInfo); } #elif defined (HAVE__FINDFIRST) struct _finddata_t fileInfo; findfirst_t hFile = _findfirst (pattern, &fileInfo); if (hFile != -1L) { do { const char *const entry = (const char *) fileInfo.name; resize |= createTagsForWildcardEntry (pattern, dirLength, entry); } while (_findnext (hFile, &fileInfo) == 0); _findclose (hFile); } #endif return resize; }
/* Reject any tag "main" from a file named "configure". These appear in * here-documents in GNU autoconf scripts and will add a haystack to the * needle. */ static boolean hackReject (const vString* const tagName) { const char *const scriptName = baseFilename (vStringValue (File.name)); boolean result = (boolean) (strcmp (scriptName, "configure") == 0 && strcmp (vStringValue (tagName), "main") == 0); return result; }
/* Reject any tag "main" from a file named "configure". These appear in * here-documents in GNU autoconf scripts and will add a haystack to the * needle. */ static bool hackReject (const vString* const tagName) { const char *const scriptName = baseFilename (getInputFileName ()); bool result = (bool) (strcmp (scriptName, "configure") == 0 && strcmp (vStringValue (tagName), "main") == 0); return result; }
static langType getPatternLanguage (const char *const fileName) { langType result = LANG_IGNORE; const char* base = baseFilename (fileName); unsigned int i; for (i = 0 ; i < LanguageCount && result == LANG_IGNORE ; ++i) { stringList* const ptrns = LanguageTable [i]->currentPatterns; if (ptrns != NULL && stringListFileMatched (ptrns, base)) result = i; } return result; }
extern void setExecutableName (const char *const path) { ExecutableProgram = path; ExecutableName = baseFilename (path); #ifdef VAXC { /* remove filetype from executable name */ char *p = strrchr (ExecutableName, '.'); if (p != NULL) *p = '\0'; } #endif }
static void setOwnerDirectoryOfInputFile (const char *const fileName) { const char *const head = fileName; const char *const tail = baseFilename (head); if (File.path != NULL) vStringDelete (File.path); if (tail == head) File.path = NULL; else { const size_t length = tail - head - 1; File.path = vStringNew (); vStringNCopyS (File.path, fileName, length); } }
std::string baseFilename(const std::string &path) { size_t sep = path.find_last_of("/\\"); std::string filename; if (sep == std::string::npos) { filename = path; } else if (sep == path.size() - 1) { return baseFilename(path.substr(0, path.size() - 1)); } else { filename = path.substr(sep + 1); } return filename; }
static bool createTagsForWildcardUsingFindfirst (const char *const pattern) { bool resize = false; const size_t dirLength = baseFilename (pattern) - pattern; #if defined (HAVE__FINDFIRST) struct _finddata_t fileInfo; findfirst_t hFile = _findfirst (pattern, &fileInfo); if (hFile != -1L) { do { const char *const entry = (const char *) fileInfo.name; resize |= createTagsForWildcardEntry (pattern, dirLength, entry); } while (_findnext (hFile, &fileInfo) == 0); _findclose (hFile); } #endif return resize; }
extern void makeFileTag (const char *const fileName) { boolean via_line_directive = (strcmp (fileName, getInputFileName()) != 0); xtagType xtag = XTAG_UNKNOWN; if (isXtagEnabled(XTAG_FILE_NAMES)) xtag = XTAG_FILE_NAMES; if (isXtagEnabled(XTAG_FILE_NAMES_WITH_TOTAL_LINES)) xtag = XTAG_FILE_NAMES_WITH_TOTAL_LINES; if (xtag != XTAG_UNKNOWN) { tagEntryInfo tag; kindOption *kind; kind = getInputLanguageFileKind(); Assert (kind); kind->enabled = isXtagEnabled(XTAG_FILE_NAMES); /* TODO: you can return here if enabled == FALSE. */ initTagEntry (&tag, baseFilename (fileName), kind); tag.isFileEntry = TRUE; tag.lineNumberEntry = TRUE; markTagExtraBit (&tag, xtag); if (via_line_directive || (!isXtagEnabled(XTAG_FILE_NAMES_WITH_TOTAL_LINES))) { tag.lineNumber = 1; } else { while (readLineFromInputFile () != NULL) ; /* Do nothing */ tag.lineNumber = getInputLineNumber (); } makeTagEntry (&tag); } }
// This takes all the names of all the files in baseFilenames and places each // in a FilenameTriple with inputSuffix appended as the input filename, with // placeholderSuffix appended as the placeholder filename, replacing the // directory path with placeholderDirectory, and with outputSuffix appended // as the output file, replacing the directory path with outputDirectory. inline void FilePlaceholderManager::PrepareFilenames( std::vector< std::string > const& baseFilenames, std::string const inputDirectory, std::string const& placeholderDirectory, std::string const& outputDirectory ) { filenameTriples.clear(); EnsureDirectoryExists( placeholderDirectory ); EnsureDirectoryExists( outputDirectory ); for( std::vector< std::string >::const_iterator baseFilename( baseFilenames.begin() ); baseFilenames.end() > baseFilename; ++baseFilename ) { currentTriple.inputFile.assign( inputDirectory + "/" + (*baseFilename) + inputSuffix ); currentTriple.placeholderFile.assign( placeholderDirectory + "/" + (*baseFilename) + placeholderSuffix ); currentTriple.outputFile.assign( outputDirectory + "/" + (*baseFilename) + outputSuffix ); filenameTriples.push_back( currentTriple ); } whichTriple = filenameTriples.begin(); }
extern void setExecutableName (const char *const path) { ExecutableProgram = path; ExecutableName = baseFilename (path); }
int main(int argc, char** argv) { if (argc != 6) { std::cout << "This program takes in input glad.h and outputs the include and implementation files for OSMesa OpenGL function and regular OpenGL functions." << std::endl; std::cout << "Usage: generateGLIncludes <glad.h path> <output dir path> <namespace name> <baseFileName> <inlcude glad debug symbols>" << std::endl; std::cout << "Example: generateGLIncludes /Users/alexandre/development/Natron/Global/gladRel/include/glad/glad.h /Users/alexandre/development/Natron/Engine Natron OSGLFunctions 1" << std::endl; return 1; } QFile f(argv[1]); if ( !f.open(QIODevice::ReadOnly) ) { std::cout << "Could not open " << argv[1] << std::endl; return 1; } // Check that output path exists QDir outputDir(argv[2]); if ( !outputDir.exists() ) { std::cout << argv[2] << " does not seem to be a valid directory" << std::endl; return 1; } QString namespaceName(argv[3]); QString baseFilename(argv[4]); bool supportGladDebug; { QString supportDebugSymbolsStr(argv[5]); supportGladDebug = (bool)supportDebugSymbolsStr.toInt(); } QString absoluteDirPath = outputDir.absolutePath(); QString outputHeaderFilename = absoluteDirPath + "/" + baseFilename + ".h"; QFile of_header(outputHeaderFilename); if ( !of_header.open(QIODevice::WriteOnly) ) { std::cout << "Could not open " << outputHeaderFilename.toStdString() << std::endl; return 1; } QTextStream ots_header(&of_header); QTextStream its(&f); QString definesStr; std::list<FunctionSignature> signatures; QString functionTypedefsStr; QString prevLine; while ( !its.atEnd() ) { // Read each line of glad.h QString line = its.readLine(); { // Search for a define QString toFind = "#define GL_"; int found = line.indexOf(toFind); if (found != -1) { definesStr += line; definesStr += "\n"; } } // Search for a function QString typedefToken("typedef "); QString pfnToken("(APIENTRYP PFNGL"); int foundFuncDef = line.indexOf(typedefToken); int foundPNFToken = line.indexOf(pfnToken); if ( (foundFuncDef != -1) && (foundPNFToken != -1) ) { int pos = foundPNFToken + pfnToken.size(); int foundFirstEndParenthesis = line.indexOf(')', pos); assert(foundFirstEndParenthesis != -1); FunctionSignature signature; QString lastFuncNameCaps = line.mid(pos, foundFirstEndParenthesis - pos); signature.signature = line.mid(foundFirstEndParenthesis); // "near" and "far" are defined as macros in windows.h signature.signature.replace("GLdouble near, GLdouble far", "GLdouble nearVal, GLdouble farVal"); signature.returnType = line.mid( foundFuncDef + typedefToken.size(), foundPNFToken - 1 - ( foundFuncDef + typedefToken.size() ) ); QString funcTypeDefStr = "typedef "; funcTypeDefStr += signature.returnType; funcTypeDefStr += " (*PFNGL"; funcTypeDefStr += lastFuncNameCaps; funcTypeDefStr += signature.signature; funcTypeDefStr += "\n"; functionTypedefsStr += funcTypeDefStr; // Remove the extraneous ; at the end of the signature // Also remove the prepending ) signature.signature.remove(0, 1); signature.signature.remove(signature.signature.size() - 1, 1); signature.funcPNType = "PFNGL"; signature.funcPNType += lastFuncNameCaps; // extract parameters { int i = 1; // start after the leading ( while ( i < signature.signature.size() ) { QString param; while ( signature.signature[i] != QChar(',') && signature.signature[i] != QChar(')') ) { param.append(signature.signature[i]); ++i; } // Now only keep the name of the parameter { int j = param.size() - 1; while ( j >= 0 && param[j].isLetterOrNumber() ) { --j; } param = param.mid(j + 1); } signature.parameters.append(param); assert( signature.signature[i] == QChar(',') || signature.signature[i] == QChar(')') ); ++i; // bypass last character if ( signature.signature[i] == QChar(')') ) { break; } } } // we caught a function typedef before, we expect to read the following #define glXxxx function with the appropriate case // in release glad.h, the next line is of the type GLAPI PFNGLCOLOR4FVPROC glad_glColor4fv; // the line after that is the one we want #define glColor4fv glad_glColor4fv line = its.readLine(); assert( !its.atEnd() ); line = its.readLine(); QString toFind("#define gl"); int foundDefine = line.indexOf(toFind); if (foundDefine == -1) { std::cout << "Parser failed to find #define glXXX statement 2 lines after a function typedef, make sure that you are running this program against a release version of glad.h" << std::endl; return 1; } // Check that this is the same symbol // Remove the PROC at the end of the func def lastFuncNameCaps.remove("PROC"); int checkIndex = toFind.size(); QString symbolStart = line.mid(checkIndex); assert( symbolStart.startsWith(lastFuncNameCaps, Qt::CaseInsensitive) ); { int i = 8; // start on the g //extract the function name while ( i < line.size() && line.at(i) != QChar(' ') ) { signature.funcName.push_back( line.at(i) ); ++i; } } signatures.push_back(signature); } // if (foundFuncDef != -1 && foundPNFToken != -1) { prevLine = line; } writeHeader(ots_header); writePODs(ots_header); ots_header << definesStr << "\n" "\n"; ots_header << functionTypedefsStr << "\n" "\n"; writeStartClass(namespaceName, ots_header); // Define the singleton ots_header << " static OSGLFunctions<USEOPENGL>& getInstance()\n" " {\n" " static OSGLFunctions<USEOPENGL> instance;\n" "\n" " return instance;\n" " }\n" "\n" " // load function, implemented in _gl.h and _mesa.h\n" " void load_functions();\n" "\n" " // private constructor\n" " OSGLFunctions() { load_functions(); }\n" "\n"; // Declare member functions for (std::list<FunctionSignature>::iterator it = signatures.begin(); it != signatures.end(); ++it) { ots_header << " " << it->funcPNType << " _" << it->funcName << ";\n"; } ots_header << "\n"; ots_header << "public:\n" "\n"; ots_header << " // static non MT-safe load function that must be called once to initialize functions\n" " static void load()\n" " {\n" " (void)getInstance();\n" " }\n" "\n" " static bool isGPU()\n" " {\n" " return USEOPENGL;\n" " }\n"; for (std::list<FunctionSignature>::iterator it = signatures.begin(); it != signatures.end(); ++it) { QString lineStart = " static " + it->returnType + " " + it->funcName; QString indentedSig = it->signature; indentedSig.replace( ", ", ",\n" + QString(lineStart.size() + 1, ' ') ); ots_header << "\n" << lineStart << indentedSig << "\n" " {\n"; if (it->returnType == "void") { ots_header << " "; } else { ots_header << " return "; } ots_header << "getInstance()._" << it->funcName << "("; QStringList::const_iterator next = it->parameters.begin(); if ( !it->parameters.isEmpty() ) { ++next; } for (QStringList::const_iterator it2 = it->parameters.begin(); it2 != it->parameters.end(); ++it2) { ots_header << *it2; if ( next != it->parameters.end() ) { ots_header << ", "; ++next; } } ots_header << ");\n" " }\n"; } writeEndClass(namespaceName, ots_header); writeFooter(ots_header); writeImplementationCppFile(namespaceName, baseFilename, signatures, absoluteDirPath, "gl", true, supportGladDebug); writeImplementationCppFile(namespaceName, baseFilename, signatures, absoluteDirPath, "mesa", false, supportGladDebug); return 0; } // main
extern langType getFileLanguage (const char *const fileName) { langType language = Option.language; if (language == LANG_AUTO) { vString* spec; FILE* input; language = LANG_IGNORE; verbose ("Get file language for %s\n", fileName); input = fopen (fileName, "rb"); { const char* baseName = baseFilename (fileName); verbose (" pattern: %s\n", baseName); language = getPatternLanguage (baseName, input); if (input) rewind (input); else goto template_file; } if (language == LANG_IGNORE && (spec = extracEmacsModeAtFirstLine (input))) { verbose (" emacs mode at the first line: %s\n", vStringValue (spec)); language = getSpecLanguage (vStringValue (spec), input); vStringDelete (spec); } rewind(input); if (language == LANG_IGNORE && (spec = extractInterpreter (input))) { verbose (" interpreter: %s\n", vStringValue (spec)); language = getSpecLanguage (vStringValue (spec), input); vStringDelete (spec); } rewind(input); if (language == LANG_IGNORE && (spec = extractEmacsModeLanguageAtEOF (input))) { verbose (" emacs mode at the EOF: %s\n", vStringValue (spec)); language = getSpecLanguage (vStringValue (spec), input); vStringDelete (spec); } rewind(input); if (language == LANG_IGNORE && (spec = extractVimFileType (input))) { verbose (" vim modeline: %s\n", vStringValue (spec)); language = getSpecLanguage (vStringValue (spec), input); vStringDelete (spec); } rewind(input); template_file: if (language == LANG_IGNORE) { const char* const tExt = ".in"; char* baseName = baseFilenameSansExtensionNew (fileName, tExt); if (baseName) { verbose (" pattern + template(%s): %s\n", tExt, baseName); language = getPatternLanguage(baseName, input); eFree (baseName); } } if (input) fclose (input); } return language; }