/** * reflect/files main-file * * Strategies for including and requiring files as in * PHP. It adds the ATerms of the files to the environment. * * @author Eric Bouwers */ module php/reflect/inclusion/main imports php/reflect/inclusion/path php/reflect/inclusion/currentdir php/reflect/inclusion/workingdir php/reflect/inclusion/inclusionid strategies //main strategy include-and-require-files = procedural-topdown(try(process-include-and-require-files(include-and-require-files))) rules /** * Process and inclusion of files. This rule finds the statements * that should be processed. * Note that this is a simple strategy. It includes all files * that are directly accessiable to the environment. For a more * enhanced version see the analysis for constant propogation. */ process-include-and-require-files(s): t@InternalFunction(Include(expr)) -> t' where includeid := <process-include(s)> expr ; t' := <add-inclusion-id(|includeid)> t process-include-and-require-files(s): t@InternalFunction(Require(expr)) -> t' where requireid := <process-include(s)> expr ; t' := <add-inclusion-id(|requireid)> t process-include-and-require-files(s): t@InternalFunction(IncludeOnce(expr)) -> t' where includeid := <process-include(s)> expr ; t' := <add-inclusion-id(|includeid)> t process-include-and-require-files(s): t@InternalFunction(RequireOnce(expr)) -> t' where requireid := <process-include(s)> expr ; t' := <add-inclusion-id(|requireid)> t rules /** * Two special functions that we need to handle. * - chdir: changes working directory * - ini-set: sets the include path if first argument is 'include_path' */ process-include-and-require-files(s): t@FunctionCall(name,params) -> t where <php-handle-function-call> (name,<map(main-analyse-const-prop)> params) rules /** * The real inclusion. The first two rules only work on direct single- or doublequoted * strings with nothing fancy. Other rules can be added that take care of other * scenario's. */ process-include(s): ConstantEncapsedString(SingleQuoted([Literal(filename)])) -> includeid where includeid := <process-inclusion(s)> filename process-include(s): ConstantEncapsedString(DoubleQuoted([Literal(filename)])) -> includeid where includeid := <process-inclusion(s)> filename strategies /** * Processes the inclusion of a filename. The strategy has * the same semantics as within PHP. The file is looked-up within * the current directory. When this fails and the filename is not relative * the file is looked up within the current directory. * * The strategy 's' is applied to the newly parsed AST after which the * new AST is added to the current environment. * * precondition: There must be an environment * * @param s: AST -> AST * @type filename::String -> Inclusionid */ process-inclusion(s) = ?arg; file := <find-php-file> arg ; where( file' := <get-current-php-file> ; <set-current-php-file> file ) ; <include-php-file(s)> file ; where( <set-current-php-file> file' ) /** * Real inclusion of a filename and a strategy that must be applied to * the included and parsed file. * * @param s: AST -> AST * @type filename::String -> Inclusionid */ include-php-file(s) = ?file ; newcurdir := <?FILE(curdirpath); !curdirpath; dirname > file ; log(|Debug(), "Start including new file: ", curdirpath) ; includeid := <new-inclusion-id> curdirpath ; get-php-environment ; add-inclusion-filename(|curdirpath,includeid) ; set-php-current-directory(|newcurdir) ; ast := <parse-php> file ; ast' := <s> ast ; prev-php-current-directory ; get-php-environment ; add-inclusion-file(|ast',includeid) ; !includeid ; log(|Debug(), "Finish including new file: ", curdirpath) /** * Takes a filename and searches for this filename in the same way that * PHP looks for the files to include. * * @type filename::String -> absolutepath::String */ find-php-file = ?filename ; ( file := <find-file-in-working-directory(|filename)> <+ if <is-php-relative> filename then fail else file := <find-file-in-current-directory(|filename)> end ) ; !file /** * Section to store current file being processed */ /** * Returnes the name of the file currently being processed */ get-current-php-file = <get-config> "current-php-file" <+ get-input-path /** * Sets the name of the file currently being processed */ set-current-php-file = <set-config> ("current-php-file", <id>)