| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 | 
							- /*============================================================================
 
-   CMake - Cross Platform Makefile Generator
 
-   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
 
-   Distributed under the OSI-approved BSD License (the "License");
 
-   see accompanying file Copyright.txt for details.
 
-   This software is distributed WITHOUT ANY WARRANTY; without even the
 
-   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
-   See the License for more information.
 
- ============================================================================*/
 
- #include "cmFunctionCommand.h"
 
- #include "cmake.h"
 
- // define the class for function commands
 
- class cmFunctionHelperCommand : public cmCommand
 
- {
 
- public:
 
-   cmFunctionHelperCommand() {}
 
-   ///! clean up any memory allocated by the function
 
-   ~cmFunctionHelperCommand() {}
 
-   /**
 
-    * This is used to avoid including this command
 
-    * in documentation. This is mainly used by
 
-    * cmMacroHelperCommand and cmFunctionHelperCommand
 
-    * which cannot provide appropriate documentation.
 
-    */
 
-   virtual bool ShouldAppearInDocumentation() const
 
-     {
 
-     return false;
 
-     }
 
-   /**
 
-    * This is a virtual constructor for the command.
 
-    */
 
-   virtual cmCommand* Clone()
 
-   {
 
-     cmFunctionHelperCommand *newC = new cmFunctionHelperCommand;
 
-     // we must copy when we clone
 
-     newC->Args = this->Args;
 
-     newC->Functions = this->Functions;
 
-     newC->Policies = this->Policies;
 
-     return newC;
 
-   }
 
-   /**
 
-    * This determines if the command is invoked when in script mode.
 
-    */
 
-   virtual bool IsScriptable() const { return true; }
 
-   /**
 
-    * This is called when the command is first encountered in
 
-    * the CMakeLists.txt file.
 
-    */
 
-   virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
 
-                                  cmExecutionStatus &);
 
-   virtual bool InitialPass(std::vector<std::string> const&,
 
-                            cmExecutionStatus &) { return false; }
 
-   /**
 
-    * The name of the command as specified in CMakeList.txt.
 
-    */
 
-   virtual std::string GetName() const { return this->Args[0]; }
 
-   cmTypeMacro(cmFunctionHelperCommand, cmCommand);
 
-   std::vector<std::string> Args;
 
-   std::vector<cmListFileFunction> Functions;
 
-   cmPolicies::PolicyMap Policies;
 
- };
 
- bool cmFunctionHelperCommand::InvokeInitialPass
 
- (const std::vector<cmListFileArgument>& args,
 
-  cmExecutionStatus & inStatus)
 
- {
 
-   // Expand the argument list to the function.
 
-   std::vector<std::string> expandedArgs;
 
-   this->Makefile->ExpandArguments(args, expandedArgs);
 
-   // make sure the number of arguments passed is at least the number
 
-   // required by the signature
 
-   if (expandedArgs.size() < this->Args.size() - 1)
 
-     {
 
-     std::string errorMsg =
 
-       "Function invoked with incorrect arguments for function named: ";
 
-     errorMsg += this->Args[0];
 
-     this->SetError(errorMsg);
 
-     return false;
 
-     }
 
-   // we push a scope on the makefile
 
-   cmMakefile::LexicalPushPop lexScope(this->Makefile);
 
-   cmMakefile::ScopePushPop varScope(this->Makefile);
 
-   static_cast<void>(varScope);
 
-   // Push a weak policy scope which restores the policies recorded at
 
-   // function creation.
 
-   cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
 
-   // set the value of argc
 
-   std::ostringstream strStream;
 
-   strStream << expandedArgs.size();
 
-   this->Makefile->AddDefinition("ARGC",strStream.str().c_str());
 
-   this->Makefile->MarkVariableAsUsed("ARGC");
 
-   // set the values for ARGV0 ARGV1 ...
 
-   for (unsigned int t = 0; t < expandedArgs.size(); ++t)
 
-     {
 
-     std::ostringstream tmpStream;
 
-     tmpStream << "ARGV" << t;
 
-     this->Makefile->AddDefinition(tmpStream.str(),
 
-                                   expandedArgs[t].c_str());
 
-     this->Makefile->MarkVariableAsUsed(tmpStream.str());
 
-     }
 
-   // define the formal arguments
 
-   for (unsigned int j = 1; j < this->Args.size(); ++j)
 
-     {
 
-     this->Makefile->AddDefinition(this->Args[j],
 
-                                   expandedArgs[j-1].c_str());
 
-     }
 
-   // define ARGV and ARGN
 
-   std::vector<std::string>::const_iterator eit;
 
-   std::string argvDef;
 
-   for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit )
 
-     {
 
-     if (!argvDef.empty())
 
-       {
 
-       argvDef += ";";
 
-       }
 
-     argvDef += *eit;
 
-     }
 
-   std::string argnDef;
 
-   eit = expandedArgs.begin() + (this->Args.size()-1);
 
-   for ( ; eit != expandedArgs.end(); ++eit)
 
-     if (!argnDef.empty())
 
-       {
 
-       argnDef += ";";
 
-       }
 
-     argnDef += *eit;
 
-     }
 
-   this->Makefile->AddDefinition("ARGV", argvDef.c_str());
 
-   this->Makefile->MarkVariableAsUsed("ARGV");
 
-   this->Makefile->AddDefinition("ARGN", argnDef.c_str());
 
-   this->Makefile->MarkVariableAsUsed("ARGN");
 
-   // Invoke all the functions that were collected in the block.
 
-   // for each function
 
-   for(unsigned int c = 0; c < this->Functions.size(); ++c)
 
-     {
 
-     cmExecutionStatus status;
 
-     if (!this->Makefile->ExecuteCommand(this->Functions[c],status) ||
 
-         status.GetNestedError())
 
-       {
 
-       // The error message should have already included the call stack
 
-       // so we do not need to report an error here.
 
-       lexScope.Quiet();
 
-       polScope.Quiet();
 
-       inStatus.SetNestedError(true);
 
-       return false;
 
-       }
 
-     if (status.GetReturnInvoked())
 
-       {
 
-       return true;
 
-       }
 
-     }
 
-   // pop scope on the makefile
 
-   return true;
 
- }
 
- bool cmFunctionFunctionBlocker::
 
- IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
 
-                   cmExecutionStatus &)
 
- {
 
-   // record commands until we hit the ENDFUNCTION
 
-   // at the ENDFUNCTION call we shift gears and start looking for invocations
 
-   if(!cmSystemTools::Strucmp(lff.Name.c_str(),"function"))
 
-     {
 
-     this->Depth++;
 
-     }
 
-   else if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
 
-     {
 
-     // if this is the endfunction for this function then execute
 
-     if (!this->Depth)
 
-       {
 
-       std::string name = this->Args[0];
 
-       name += "( ";
 
-       name += cmJoin(this->Args, " ");
 
-       name += " )";
 
-       // create a new command and add it to cmake
 
-       cmFunctionHelperCommand *f = new cmFunctionHelperCommand();
 
-       f->Args = this->Args;
 
-       f->Functions = this->Functions;
 
-       mf.RecordPolicies(f->Policies);
 
-       // Set the FilePath on the arguments to match the function since it is
 
-       // not stored and the original values may be freed
 
-       for (unsigned int i = 0; i < f->Functions.size(); ++i)
 
-         {
 
-         for (unsigned int j = 0; j < f->Functions[i].Arguments.size(); ++j)
 
-           {
 
-           f->Functions[i].Arguments[j].FilePath =
 
-             f->Functions[i].FilePath.c_str();
 
-           }
 
-         }
 
-       std::string newName = "_" + this->Args[0];
 
-       mf.GetCMakeInstance()->RenameCommand(this->Args[0],
 
-                                            newName);
 
-       mf.AddCommand(f);
 
-       // remove the function blocker now that the function is defined
 
-       mf.RemoveFunctionBlocker(this, lff);
 
-       return true;
 
-       }
 
-     else
 
-       {
 
-       // decrement for each nested function that ends
 
-       this->Depth--;
 
-       }
 
-     }
 
-   // if it wasn't an endfunction and we are not executing then we must be
 
-   // recording
 
-   this->Functions.push_back(lff);
 
-   return true;
 
- }
 
- bool cmFunctionFunctionBlocker::
 
- ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
 
- {
 
-   if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
 
-     {
 
-     std::vector<std::string> expandedArguments;
 
-     mf.ExpandArguments(lff.Arguments, expandedArguments);
 
-     // if the endfunction has arguments then make sure
 
-     // they match the ones in the opening function command
 
-     if ((expandedArguments.empty() ||
 
-          (expandedArguments[0] == this->Args[0])))
 
-       {
 
-       return true;
 
-       }
 
-     }
 
-   return false;
 
- }
 
- bool cmFunctionCommand
 
- ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
 
- {
 
-   if(args.size() < 1)
 
-     {
 
-     this->SetError("called with incorrect number of arguments");
 
-     return false;
 
-     }
 
-   // create a function blocker
 
-   cmFunctionFunctionBlocker *f = new cmFunctionFunctionBlocker();
 
-   f->Args.insert(f->Args.end(), args.begin(), args.end());
 
-   this->Makefile->AddFunctionBlocker(f);
 
-   return true;
 
- }
 
 
  |