Example #1
0
int cpp_main(int argc, char* argv[])
{
   //
   // get the boost path to begin with:
   //
   if(argc > 1)
   {
      fs::path p(argv[1], fs::native);
      config_path = p / "libs" / "config" / "test" ;
   }
   else
   {
      // try __FILE__:
      fs::path p(__FILE__, fs::native);
      config_path = p.branch_path().branch_path() / "test";
   }
   std::cout << "Info: Boost.Config test path set as: " << config_path.native_directory_string() << std::endl;

   // enumerate *.ipp files:
   boost::regex ipp_mask("boost_(?:(has)|no).*\\.ipp");
   boost::smatch ipp_match;
   fs::directory_iterator i(config_path), j;
   while(i != j)
   {
      if(boost::regex_match(i->path().leaf(), ipp_match, ipp_mask))
      {
         process_ipp_file(*i, ipp_match[1].matched);
      }
      ++i;
   }
   write_config_test();
   write_jamfile_v2();
   write_config_info();
   return 0;
}
Example #2
0
/**
 * Non-Windows shared library constructor. This ensures that the environment
 * variable \c TWEEK_BASE_DIR is set as soon as this shared library is loaded.
 * If it is not set, then it sets it based on an assumption about the
 * structure of a Tweek installation. More specifically, an assumption is made
 * that this shared library lives in the \c lib subdirectory of the Tweek
 * installation. Therefore, the root of the Tweek installation is the parent
 * of the directory containing this shared library.
 */
extern "C" void __attribute ((constructor)) tweekLibraryInit()
{
   fs::path base_dir;
   const char* env_dir = std::getenv("TWEEK_BASE_DIR");

   // If TWEEK_BASE_DIR is not set, look up the path to this shared library
   // and use it to provide a default setting for that environment variable.
   if ( NULL == env_dir )
   {
      Dl_info info;
      info.dli_fname = 0;
      const int result =
#if defined(__GNUC__) && __GNUC_MAJOR__ < 4
         dladdr((void*) &tweekLibraryInit, &info);
#else
         dladdr(reinterpret_cast<void*>(&tweekLibraryInit), &info);
#endif

      // NOTE: dladdr(3) really does return a non-zero value on success.
      if ( 0 != result )
      {
         try
         {
            fs::path lib_file(info.dli_fname, fs::native);
            lib_file = fs::system_complete(lib_file);

#if defined(VPR_OS_IRIX) && defined(_ABIN32)
            const std::string bit_suffix("32");
#elif defined(VPR_OS_IRIX) && defined(_ABI64) || \
      defined(VPR_OS_Linux) && defined(__x86_64__)
            const std::string bit_suffix("64");
#else
            const std::string bit_suffix("");
#endif

            // Get the directory containing this shared library.
            const fs::path lib_path = lib_file.branch_path();

            // Start the search for the root of the Tweek installation in the
            // parent of the directory containing this shared library.
            base_dir = lib_path.branch_path();

            // Use the lib subdirectory to figure out when we have found the
            // root of the Tweek installation tree.
            const fs::path lib_subdir(std::string("lib") + bit_suffix);

            bool found(false);
            while ( ! found && ! base_dir.empty() )
            {
               try
               {
                  if ( ! fs::exists(base_dir / lib_subdir) )
                  {
                     base_dir = base_dir.branch_path();
                  }
                  else
                  {
                     found = true;
                  }
               }
               catch (fs::filesystem_error&)
               {
                  base_dir = base_dir.branch_path();
               }
            }

            if ( found )
            {
               setenv("TWEEK_BASE_DIR",
                      base_dir.native_directory_string().c_str(), 1);
            }
         }
         catch (fs::filesystem_error& ex)
         {
            std::cerr << "Automatic assignment of TWEEK_BASE_DIR failed:\n"
                      << ex.what() << std::endl;
         }
      }
   }
   else
   {
      try
      {
         base_dir = fs::path(env_dir, fs::native);
      }
      catch (fs::filesystem_error& ex)
      {
         std::cerr << "Invalid path set in TWEEK_BASE_DIR environment "
                   << "variable:\n" << ex.what() << std::endl;
      }
   }

   if ( ! base_dir.empty() )
   {
      // If base_dir were empty, this would result in data_dir being relative
      // to the current working directory.
      const fs::path data_dir = base_dir / TWEEK_SHARE_DIR;

      // We use the overwrite value of 0 as a way around testing whether the
      // environment variable is already set.
      setenv("TWEEK_DATA_DIR", data_dir.native_directory_string().c_str(), 0);
   }
}
Example #3
0
/**
 * Non-Windows shared library constructor. This ensures that the environment
 * variable \c GADGET_BASE_DIR is set as soon as this shared library is loaded.
 * If it is not set, then it sets it based on an assumption about the
 * structure of a Gadgeteer installation. More specifically, an assumption is
 * made that this shared library lives in the \c lib subdirectory of the
 * Gadgeteer installation. Therefore, the root of the Gadgeteer installation
 * is the parent of the directory containing this shared library.
 */
extern "C" void __attribute ((constructor)) gadgetLibraryInit()
{
   fs::path base_dir;
   const char* env_dir = std::getenv("GADGET_BASE_DIR");

   // If GADGET_BASE_DIR is not set, look up the path to this shared library
   // and use it to provide a default setting for that environment variable.
   if ( NULL == env_dir )
   {
      Dl_info info;
      info.dli_fname = 0;
      const int result =
#if defined(__GNUC__) && __GNUC_MAJOR__ < 4
         dladdr((void*) &gadgetLibraryInit, &info);
#else
         dladdr(reinterpret_cast<void*>(&gadgetLibraryInit), &info);
#endif

      // NOTE: dladdr(3) really does return a non-zero value on success.
      if ( 0 != result )
      {
         try
         {
            fs::path lib_file(
#if BOOST_VERSION >= 104600 && BOOST_FILESYSTEM_VERSION == 3
               info.dli_fname
#else
               info.dli_fname, fs::native
#endif
            );
            lib_file = fs::system_complete(lib_file);

#if defined(GADGET_LIBDIR_NAME)
            const std::string lib_dir_name(GADGET_LIBDIR_NAME);
#else
            const std::string lib_dir_name("lib");
#endif

            // Get the directory containing this shared library.
            const fs::path lib_path = lib_file.branch_path();

            // Start the search for the root of the Gadgeteer installation in
            // the parent of the directory containing this shared library.
            base_dir = lib_path.branch_path();

            // Use the lib subdirectory to figure out when we have found the
            // root of the Gadgeteer installation tree.
            const fs::path lib_subdir(lib_dir_name);

            bool found(false);
            while ( ! found && ! base_dir.empty() )
            {
               try
               {
                  if ( ! fs::exists(base_dir / lib_subdir) )
                  {
                     base_dir = base_dir.branch_path();
                  }
                  else
                  {
                     found = true;
                  }
               }
               catch (fs::filesystem_error&)
               {
                  base_dir = base_dir.branch_path();
               }
            }

            if ( found )
            {
               setenv("GADGET_BASE_DIR",
#if BOOST_VERSION >= 104600 && BOOST_FILESYSTEM_VERSION == 3
                      base_dir.native().c_str(),
#else
                      base_dir.native_directory_string().c_str(),
#endif
                      1);
            }
         }
         catch (fs::filesystem_error& ex)
         {
            std::cerr << "Automatic assignment of GADGET_BASE_DIR failed:\n"
                      << ex.what() << std::endl;
         }
      }
   }
   else
   {
      try
      {
         base_dir =
#if BOOST_VERSION >= 104600 && BOOST_FILESYSTEM_VERSION == 3
            fs::path(env_dir);
#else
            fs::path(env_dir, fs::native);
#endif
      }
      catch (fs::filesystem_error& ex)
      {
         std::cerr << "Invalid path set in GADGET_BASE_DIR environment "
                   << "variable:\n" << ex.what() << std::endl;
      }
   }

   if ( ! base_dir.empty() )
   {
      // If base_dir were empty, this would result in data_dir being relative
      // to the current working directory.
      const fs::path data_dir = base_dir / GADGET_SHARE_DIR;

      // We use the overwrite value of 0 as a way around testing whether the
      // environment variable is already set.
      setenv("GADGET_DATA_DIR",
#if BOOST_VERSION >= 104600 && BOOST_FILESYSTEM_VERSION == 3
             data_dir.native().c_str(),
#else
             data_dir.native_directory_string().c_str(),
#endif
             0);
   }
}
Example #4
0
void process_ipp_file(const fs::path& file, bool positive_test)
{
   std::cout << "Info: Scanning file: " << file.native_directory_string() << std::endl;

   // our variables:
   std::string file_text;
   std::string macro_name;
   std::string namespace_name;
   fs::path positive_file;
   fs::path negative_file;

   // load the file into memory so we can scan it:
   fs::ifstream ifs(file);
   std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(), std::back_inserter(file_text));
   ifs.close();
   // scan for the macro name:
   boost::regex macro_regex("//\\s*MACRO\\s*:\\s*(\\w+)");
   boost::smatch macro_match;
   if(boost::regex_search(file_text, macro_match, macro_regex))
   {
      macro_name = macro_match[1];
      macro_list.insert(macro_name);
      namespace_name = boost::regex_replace(file_text, macro_regex, "\\L$1", boost::format_first_only | boost::format_no_copy);
   }
   if(macro_name.empty())
   {
      std::cout << "Error: no macro definition found in " << file.native_directory_string();
   }
   else
   {
      std::cout << "Info: Macroname: " << macro_name << std::endl;
   }

   // get the output filesnames:
   boost::regex file_regex("boost_([^.]+)\\.ipp");
   positive_file = file.branch_path() / boost::regex_replace(file.leaf(), file_regex, "$1_pass.cpp");
   negative_file = file.branch_path() / boost::regex_replace(file.leaf(), file_regex, "$1_fail.cpp");
   write_test_file(positive_file, macro_name, namespace_name, file.leaf(), positive_test, true);
   write_test_file(negative_file, macro_name, namespace_name, file.leaf(), positive_test, false);
   
   // always create config_test data,
   // positive and negative tests go to separate streams, because for some
   // reason some compilers choke unless we put them in a particular order...
   std::ostream* pout = positive_test ? &config_test1a : &config_test1;
   *pout << "#if";
   if(!positive_test)
      *pout << "n";
   *pout << "def " << macro_name 
      << "\n#include \"" << file.leaf() << "\"\n#else\nnamespace "
      << namespace_name << " = empty_boost;\n#endif\n";

   config_test2 << "   if(0 != " << namespace_name << "::test())\n"
      "   {\n"
      "      std::cerr << \"Failed test for " << macro_name << " at: \" << __FILE__ << \":\" << __LINE__ << std::endl;\n"
      "      ++error_count;\n"
      "   }\n";

   // always generate the jamfile data:
   jamfile << "test-suite \"" << macro_name << "\" : \n"
      "[ run " << positive_file.leaf() << " <template>config_options ]\n"
      "[ compile-fail " << negative_file.leaf() << " <template>config_options ] ;\n";

   jamfile_v2 << "test-suite \"" << macro_name << "\" : \n"
      "[ run ../" << positive_file.leaf() << " ]\n"
      "[ compile-fail ../" << negative_file.leaf() << " ] ;\n";

}
Example #5
0
void write_test_file(const fs::path& file, 
                     const std::string& macro_name, 
                     const std::string& namespace_name, 
                     const std::string& header_file,
                     bool positive_test, 
                     bool expect_success)
{
   if(!fs::exists(file))
   {
      std::cout << "Writing test file " << file.native_directory_string() << std::endl;

      fs::ofstream ofs(file);
      std::time_t t = std::time(0);
      ofs << "//  This file was automatically generated on " << std::ctime(&t);
      ofs << "//  by libs/config/tools/generate.cpp\n" << copyright << std::endl;
      ofs << "\n// Test file for macro " << macro_name << std::endl;

      if(expect_success)
      {
         ofs << "// This file should compile, if it does not then\n"
            "// " << macro_name << " should ";
         if(positive_test)
            ofs << "not ";
         ofs << "be defined.\n";
      }
      else
      {
         ofs << "// This file should not compile, if it does then\n"
            "// " << macro_name << " should ";
         if(!positive_test)
            ofs << "not ";
         ofs << "be defined.\n";
      }
      ofs << "// See file " << header_file << " for details\n\n";

      ofs << "// Must not have BOOST_ASSERT_CONFIG set; it defeats\n"
         "// the objective of this file:\n"
         "#ifdef BOOST_ASSERT_CONFIG\n"
         "#  undef BOOST_ASSERT_CONFIG\n"
         "#endif\n\n";

      static const boost::regex tr1_exp("BOOST_HAS_TR1.*");

      ofs << "#include <boost/config.hpp>\n";

      if(regex_match(macro_name, tr1_exp))
         ofs << "#include <boost/tr1/detail/config.hpp>\n";

      ofs << "#include \"test.hpp\"\n\n"
         "#if";
      if(positive_test != expect_success)
         ofs << "n";
      ofs << "def " << macro_name << 
         "\n#include \"" << header_file << 
         "\"\n#else\n";
      if(expect_success)
         ofs << "namespace " << namespace_name << " = empty_boost;\n";
      else
         ofs << "#error \"this file should not compile\"\n";
      ofs << "#endif\n\n";

      ofs << "int main( int, char *[] )\n{\n   return " << namespace_name << "::test();\n}\n\n";  
   }
   else
   {
      std::cout << "Skipping existing test file " << file.native_directory_string() << std::endl;
   }
}
bool InputManager::configureInputManager(jccl::ConfigElementPtr element)
{
   bool have_bad_elt = (element->getID() != std::string("input_manager"));
   vprASSERT(!have_bad_elt);
   if(have_bad_elt)
   {
      return false;
   }

   bool ret_val = false;

   vpr::DebugOutputGuard dbg_output(gadgetDBG_INPUT_MGR, vprDBG_STATE_LVL,
                                    std::string("Handling input_manager element:\n"),
                                    std::string("-- end state -- \n"));

   // Keep this up to date with the version of the element definition we're
   // expecting to handle.
   const unsigned int cur_version(2);

   // If the element version is less than cur_version, we will not try to
   // proceed.  Instead, we'll print an error message and return false so
   // that the Config Manager knows this element wasn't consumed.
   if ( element->getVersion() < cur_version )
   {
      vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
         << clrOutBOLD(clrRED, "ERROR")
         << ": [gadget::InputManager::configureInputManager()] Element named '"
         << element->getName() << "'" << std::endl << vprDEBUG_FLUSH;
      vprDEBUG_NEXT(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
         << "is version " << element->getVersion()
         << ", but we require at least version " << cur_version
         << std::endl << vprDEBUG_FLUSH;
      vprDEBUG_NEXT(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
         << "Ignoring this element and moving on." << std::endl
         << vprDEBUG_FLUSH;
      ret_val = false;
   }
   // We got the right version of the config element and can proceed.
   else
   {
      const std::string driver_path_prop_name("driver_path");
      const int path_count(element->getNum(driver_path_prop_name));
      std::vector<fs::path> search_path(path_count);

      for ( unsigned int i = 0; i < search_path.size(); ++i )
      {
         std::string temp_str =
            vpr::replaceEnvVars(element->getProperty<std::string>(driver_path_prop_name, i));

         try
         {
            search_path[i] = fs::path(temp_str, fs::native);
         }
         catch(fs::filesystem_error& fsEx)
         {
            vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
               << clrOutNORM(clrRED, "ERROR")
               << ": [gadget::InputManager::configureInputManager()] File "
               << "system exception caught while converting\n"
               << vprDEBUG_FLUSH;
            vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
               << "'" << temp_str << "'\n" << vprDEBUG_FLUSH;
            vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
               << "to a Boost.Filesystem path.\n" << vprDEBUG_FLUSH;
            vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
               << fsEx.what() << std::endl << vprDEBUG_FLUSH;
         }
      }

      // Append a default driver search path to search_path.
      const fs::path default_search_dir =
         gadget::getDefaultPluginRoot() / std::string("drivers");

      vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_VERB_LVL)
         << "[gadget::InputManager::configureInputManager()] Appending "
         << "default search path '"
         << default_search_dir.native_directory_string() << "'\n"
         << vprDEBUG_FLUSH;

#if defined(GADGET_DEBUG)
      // For a debug build, search in the debug subdirectory of
      // default_search_dir before looking in default_search_dir.
      search_path.push_back(default_search_dir / std::string("debug"));
#endif

      search_path.push_back(default_search_dir);

      // --- Load device driver dsos -- //
      // - Load individual drivers
      const std::string driver_prop_name("driver");
      const std::string get_version_func("getGadgeteerVersion");
      const std::string driver_init_func("initDevice");

      int driver_count = element->getNum(driver_prop_name);
      std::string driver_dso_name;

      for ( int i = 0; i < driver_count; ++i )
      {
         driver_dso_name =
            element->getProperty<std::string>(driver_prop_name, i);

         if ( ! driver_dso_name.empty() )
         {
            vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_STATE_LVL)
               << "[gadget::InputManager::configureInputManager()] Loading "
               << "driver DSO '" << driver_dso_name << "'\n" << vprDEBUG_FLUSH;

            vpr::LibraryPtr dso = vpr::LibraryLoader::findDSO(driver_dso_name,
                                                              search_path);

            if ( dso.get() != NULL )
            {
               try
               {
                  VersionCheckCallable version_functor;
                  vpr::LibraryLoader::callEntryPoint(dso, get_version_func,
                                                     version_functor);

                  DriverInitCallable init_functor(this);
                  vpr::LibraryLoader::callEntryPoint(dso, driver_init_func,
                                                     init_functor);

                  mLoadedDrivers.push_back(dso);
               }
               catch (gadget::PluginVersionException& ex)
               {
                  vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                     << clrOutBOLD(clrRED, "ERROR")
                     << ": Version mismatch while loading driver DSO '"
                     << driver_dso_name << "'\n" << vprDEBUG_FLUSH;
                  vprDEBUG_NEXT(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                     << "This driver will not be usable.\n"
                     << vprDEBUG_FLUSH;
                  vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                     << ex.getExtendedDescription() << std::endl
                     << vprDEBUG_FLUSH;
               }
               catch (vpr::Exception& ex)
               {
                  vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                     << clrOutBOLD(clrRED, "ERROR")
                     << ": Failed to load driver DSO '"
                     << driver_dso_name << "'\n" << vprDEBUG_FLUSH;
                  vprDEBUG_NEXT(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                     << "This driver will not be usable.\n" << vprDEBUG_FLUSH;
                  vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                     << ex.what() << std::endl << vprDEBUG_FLUSH;
               }
            }
            else
            {
               vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                  << clrOutBOLD(clrRED, "ERROR")
                  << ": Failed to find driver DSO '" << driver_dso_name
                  << "'\n" << vprDEBUG_FLUSH;
            }
         }
      }

      // - Load driver directory
      const std::string dir_prop_name("driver_scan_path");
      int dir_count = element->getNum(dir_prop_name);
      std::string driver_dir;

#if defined(VPR_OS_Windows)
      const std::string driver_ext("dll");
#elif defined(VPR_OS_Darwin)
      const std::string driver_ext("dylib");
#else
      const std::string driver_ext("so");
#endif

      for ( int i = 0; i < dir_count; ++i )
      {
         driver_dir = vpr::replaceEnvVars(element->getProperty<std::string>(dir_prop_name, i));

         // The vpr::LibraryFinder will throw an exception if driver_dir is
         // (somehow) an invalid path.
         try
         {
            fs::path drv_path(driver_dir, fs::native);

            if ( fs::exists(drv_path) )
            {
               vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                  << "[gadget::InputManager::configureInputManager()] "
                  << "Searching for driver DSOs in '" << driver_dir << "'\n"
                  << vprDEBUG_FLUSH;

               vpr::LibraryFinder finder(driver_dir, driver_ext);
               vpr::LibraryFinder::LibraryList libs = finder.getLibraries();
               VersionCheckCallable version_functor;
               DriverInitCallable init_functor(this);

               for ( vpr::LibraryFinder::LibraryList::iterator lib = libs.begin();
                     lib != libs.end();
                     ++lib )
               {
                  try
                  {
                     vpr::LibraryLoader::callEntryPoint(*lib, get_version_func,
                                                        version_functor);
                     vpr::LibraryLoader::callEntryPoint(*lib, driver_init_func,
                                                        init_functor);
                     mLoadedDrivers.push_back(*lib);
                  }
                  catch (vpr::Exception& ex)
                  {
                     vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                        << clrOutBOLD(clrRED, "ERROR")
                        << ": Failed to load driver DSO '"
                        << (*lib)->getName() << "'\n" << vprDEBUG_FLUSH;
                     vprDEBUG_NEXT(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                        << "This driver will not be usable.\n"
                        << vprDEBUG_FLUSH;
                     vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                        << ex.what() << std::endl << vprDEBUG_FLUSH;
                  }
               }
            }
            else
            {
               vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
                  << clrOutBOLD(clrYELLOW, "WARNING")
                  << ": [gadget::InputManager::configureInputManager()] "
                  << "Invalid directory for driver DSOs: " << driver_dir
                  << std::endl << vprDEBUG_FLUSH;
            }
         }
         catch(fs::filesystem_error& fsEx)
         {
            vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
               << clrOutNORM(clrRED, "ERROR")
               << ": [gadget::InputManager::configureInputManager()] File "
               << "system exception caught!\n" << vprDEBUG_FLUSH;
            vprDEBUG_NEXT(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL)
               << fsEx.what() << std::endl << vprDEBUG_FLUSH;
         }
      }

      ret_val = true;
   }

   return ret_val;
}