1 /*---------------------------------------------------------------------------*\
2 Attributed Grammar for Coco/R (-*- C++ -*- version)
4 coco-cpp wmkdependParser.atg
5 \*---------------------------------------------------------------------------*/
7 /*---------------------------------*- C++ -*---------------------------------*\
9 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
11 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
13 -------------------------------------------------------------------------------
15 This file is part of OpenFOAM.
17 OpenFOAM is free software: you can redistribute it and/or modify it
18 under the terms of the GNU General Public License as published by
19 the Free Software Foundation, either version 3 of the License, or
20 (at your option) any later version.
22 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
23 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 You should have received a copy of the GNU General Public License
28 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
30 @file wmkdependParser.atg
33 An attributed Coco/R grammar to parse C/C++, Fortran and Java files
34 for include and import statements.
39 \*---------------------------------------------------------------------------*/
46 /*---------------------------------------------------------------------------*/
54 /*---------------------------------------------------------------------------*/
57 //! Set of (java) directories already visited
58 static std::set<std::string> visitedDirs_;
60 //! Replace all '.' with '/'
61 static void dotToSlash(std::string& name);
63 //! Import (java) directories
64 static void importDir(const std::string& dirName);
66 //! Import (java) file
67 static void importFile(const std::string& name);
70 //! Set of files already visited
71 static std::set<std::string> visitedFiles;
73 //! Include directories to search
74 static std::list<std::string> includeDirs;
76 //! The name of the top-level source file
77 static std::string sourceFile;
79 //! The name of the top-level dep file
80 static std::string depFile;
82 //! Add directory to list of visited dirs, thus effectively ignoring it
83 static void ignoreDir(const std::string& name);
86 static void includeFile(const std::string& name);
88 /*---------------------------------------------------------------------------*/
90 #include <sys/types.h>
93 std::set<std::string> Parser::visitedDirs_;
95 std::set<std::string> Parser::visitedFiles;
96 std::list<std::string> Parser::includeDirs;
97 std::string Parser::sourceFile;
98 std::string Parser::depFile;
101 void Parser::dotToSlash(std::string& name)
103 std::string::size_type start = 0;
105 while ((start = name.find('.', start)) != std::string::npos)
107 name.replace(start, 1, 1, '/');
113 void Parser::ignoreDir(const std::string& name)
115 visitedDirs_.insert(name);
119 void Parser::includeFile(const std::string& name)
121 if (!visitedFiles.insert(name).second)
123 return; // already existed (did not insert)
126 // use stdio and buffering within Coco/R -- (faster)
127 FILE *fh = fopen(name.c_str(), "r");
130 std::cout << depFile << ": " << name << "\n";
136 std::list<std::string>::const_iterator iter = includeDirs.begin();
137 iter != includeDirs.end();
141 const std::string pathName = *iter + name;
143 fh = fopen(pathName.c_str(), "r");
146 std::cout << depFile << ": " << pathName << "\n";
155 Parser parser(&scanner);
165 L"could not open file %s for source file %s\n",
166 name.c_str(), sourceFile.c_str()
169 // only report the first occurance
170 visitedFiles.insert(name);
175 void Parser::importFile(const std::string& name)
177 // check if a globbed form was already visited
178 std::string::size_type dotPos = name.find('.');
179 if (dotPos != std::string::npos)
181 std::string dirGlob = name.substr(0, dotPos);
184 if (visitedDirs_.find(dirGlob) != visitedDirs_.end())
190 std::string javaFileName = name;
192 dotToSlash(javaFileName);
193 javaFileName += ".java";
195 includeFile(javaFileName);
199 void Parser::importDir(const std::string& name)
201 if (!visitedDirs_.insert(name).second)
203 return; // already existed (did not insert)
206 std::string dirName = name;
209 DIR *source = opendir(dirName.c_str());
215 // Read and parse all the entries in the directory
216 while ((list = readdir(source)) != NULL)
218 const char* ext = strstr(list->d_name, ".java");
220 // avoid matching on something like '.java~'
221 if (ext && strlen(ext) == 5)
223 std::string pathName = dirName + list->d_name;
224 includeFile(pathName);
235 L"could not open directory %s\n",
245 /*---------------------------------------------------------------------------*/
248 letter = 'A'..'Z' + 'a'..'z' + '_'.
249 digit = "0123456789".
253 stringCh = ANY - '"' - '\\' - cr - lf.
254 printable = '\u0020' .. '\u007e'.
255 java_letter = letter + '$'.
257 // * * * * * * * * * * * * * * * * TOKENS * * * * * * * * * * * * * * * * * //
263 '"' { stringCh | '\\' printable } '"'.
265 // single-quoted string (eg, Fortran)
267 '\'' { stringCh | '\\' printable } '\''.
271 java_letter { java_letter | digit }
272 { '.' java_letter { java_letter | digit } } .
276 java_letter { java_letter | digit }
277 { '.' java_letter { java_letter | digit } } ".*" .
280 // * * * * * * * * * * * PRAGMAS / COMMENTS / IGNORE * * * * * * * * * * * //
282 COMMENTS FROM "/*" TO "*/" NESTED
283 COMMENTS FROM "//" TO lf
287 // * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * //
294 // C/C++-style includes
302 includeFile(t->toStringUTF8(1, t->length()-2));
306 includeFile(t->toString(1, t->length()-2));
311 [ ANY { ANY } ] '\n' // skip trailing junk
313 // Fortran-style includes
319 includeFile(t->toStringUTF8(1, t->length()-2));
323 includeFile(t->toString(1, t->length()-2));
327 [ ANY { ANY } ] '\n' // skip trailing junk
335 importDir(t->toStringUTF8());
339 importDir(t->toString());
345 importFile(t->toStringUTF8());
349 importFile(t->toString());
354 [ ANY { ANY } ] '\n' // skip trailing junk
356 | [ ANY { ANY } ] '\n' // skip any other lines
362 /*---------------------------------------------------------------------------*/
366 // ************************************************************************* //