<commit_before>#ifdef _MSC_VER
#ifdef GEOS_DEBUG_MSVC_USE_VLD
#include <vld.h>
#endif
#endif

// tut
#include <tut.hpp>
#include <tut_reporter.hpp>
// geos
#include <geos/unload.h>
// std
#include <cstdlib>
#include <iomanip>
#include <iostream>

namespace tut
{
    test_runner_singleton runner;
}

void usage()
{
    using std::cout;
    using std::endl;

    const std::string module("geos_unit");

    //[list] | [ group] [test]
    cout << "Usage: " << module << " [OPTION] [TARGET]\n"
        << endl
        << "Targets:\n"
        << "  <none>                          run all tests in all groups\n"
        << "  <group name>                    run all tests from given group\n"
        << "  <group name> <test nr>          run single test with given number from given group\n"
        << endl
        << "Options:\n"
        << "  --list                          list all registered test groups\n"
        << "  --verbose                       run unit tests verbosely; displays non-error information\n"
        << "  --version                       print version information and exit\n"
        << "  --help                          print this message and exit\n"
        << endl
        << "Examples:\n"
        << "  " << module << " -v\n"
        << "  " << module << " list\n"
        << "  " << module << " geos::geom::Envelope\n"
        << "  " << module << " geos::geom::Envelope 2\n"
        << endl
        << "GEOS homepage: http://geos.refractions.net" << endl;
}

int main(int argc, const char* argv[])
{
    tut::reporter visi;

    if ( (argc == 2 && std::string(argv[1]) == "--help") || argc > 3 )
    {
        usage();
        return 0;
    }

    std::cout << "===============================\n"
              << "  GEOS Test Suite Application\n"
              << "===============================\n";

    tut::runner.get().set_callback(&visi);

    try
    {
        if ( argc == 1 )
        {
            tut::runner.get().run_tests();
        }
        else if ( argc == 2 && std::string(argv[1]) == "--list" )
        {
            tut::groupnames gl = tut::runner.get().list_groups();
            tut::groupnames::const_iterator b = gl.begin();
            tut::groupnames::const_iterator e = gl.end();

            tut::groupnames::difference_type d = std::distance(b, e);

            std::cout << "Registered " << d << " test groups:\n" << std::endl;

            while ( b != e )
            {
                std::cout << "  " << *b << std::endl;
                ++b;
            }
        }
        else if ( argc == 2 && std::string(argv[1]) != "--list" )
        {
            tut::runner.get().run_tests(argv[1]);
        }
        else if( argc == 3 )
        {
            // TODO - mloskot - check if test group with given name exists
            // TODO - mloskot - check if test case with given number exists
            std::string grpname(argv[1]);
            if (grpname.empty())
                throw std::runtime_error("missing test group name");

            tut::test_result result;
            tut::runner.get().run_test(grpname, std::atoi(argv[2]), result);
        }
    }
    catch( const std::exception& ex )
    {
        std::cerr << "!!! GEOS Test Suite raised exception: " << ex.what() << std::endl;
    }

    // XXX - mloskot - this should be removed in future!
    geos::io::Unload::Release();

    return (visi.all_ok() ? EXIT_SUCCESS : EXIT_FAILURE);
}
<commit_msg>Missing svn keywords<commit_after>// $Id$
//
// Test Suite Runner
//
#ifdef _MSC_VER
#ifdef GEOS_DEBUG_MSVC_USE_VLD
#include <vld.h>
#endif
#endif

// tut
#include <tut.hpp>
#include <tut_reporter.hpp>
// geos
#include <geos/unload.h>
// std
#include <cstdlib>
#include <iomanip>
#include <iostream>

namespace tut
{
    test_runner_singleton runner;
}

void usage()
{
    using std::cout;
    using std::endl;

    const std::string module("geos_unit");

    //[list] | [ group] [test]
    cout << "Usage: " << module << " [OPTION] [TARGET]\n"
        << endl
        << "Targets:\n"
        << "  <none>                          run all tests in all groups\n"
        << "  <group name>                    run all tests from given group\n"
        << "  <group name> <test nr>          run single test with given number from given group\n"
        << endl
        << "Options:\n"
        << "  --list                          list all registered test groups\n"
        << "  --verbose                       run unit tests verbosely; displays non-error information\n"
        << "  --version                       print version information and exit\n"
        << "  --help                          print this message and exit\n"
        << endl
        << "Examples:\n"
        << "  " << module << " -v\n"
        << "  " << module << " list\n"
        << "  " << module << " geos::geom::Envelope\n"
        << "  " << module << " geos::geom::Envelope 2\n"
        << endl
        << "GEOS homepage: http://geos.refractions.net" << endl;
}

int main(int argc, const char* argv[])
{
    tut::reporter visi;

    if ( (argc == 2 && std::string(argv[1]) == "--help") || argc > 3 )
    {
        usage();
        return 0;
    }

    std::cout << "===============================\n"
              << "  GEOS Test Suite Application\n"
              << "===============================\n";

    tut::runner.get().set_callback(&visi);

    try
    {
        if ( argc == 1 )
        {
            tut::runner.get().run_tests();
        }
        else if ( argc == 2 && std::string(argv[1]) == "--list" )
        {
            tut::groupnames gl = tut::runner.get().list_groups();
            tut::groupnames::const_iterator b = gl.begin();
            tut::groupnames::const_iterator e = gl.end();

            tut::groupnames::difference_type d = std::distance(b, e);

            std::cout << "Registered " << d << " test groups:\n" << std::endl;

            while ( b != e )
            {
                std::cout << "  " << *b << std::endl;
                ++b;
            }
        }
        else if ( argc == 2 && std::string(argv[1]) != "--list" )
        {
            tut::runner.get().run_tests(argv[1]);
        }
        else if( argc == 3 )
        {
            // TODO - mloskot - check if test group with given name exists
            // TODO - mloskot - check if test case with given number exists
            std::string grpname(argv[1]);
            if (grpname.empty())
                throw std::runtime_error("missing test group name");

            tut::test_result result;
            tut::runner.get().run_test(grpname, std::atoi(argv[2]), result);
        }
    }
    catch( const std::exception& ex )
    {
        std::cerr << "!!! GEOS Test Suite raised exception: " << ex.what() << std::endl;
    }

    // XXX - mloskot - this should be removed in future!
    geos::io::Unload::Release();

    return (visi.all_ok() ? EXIT_SUCCESS : EXIT_FAILURE);
}
<|endoftext|>


<commit_before>/*
 * CrashHandlerProxyMain.cpp
 *
 * Copyright (C) 2019 by RStudio, Inc.
 *
 */

#include <core/CrashHandler.hpp>
#include <core/system/Environment.hpp>
#include <core/system/PosixSystem.hpp>

using namespace rstudio::core;
using namespace rstudio::core::system;

void runCrashHandler(const char* argv[])
{
   FilePath exePath;
   Error error = executablePath(nullptr, &exePath);
   if (error)
      LOG_ERROR(error);

   FilePath handlerPath;
   std::string crashpadHandlerPath = rstudio::core::system::getenv(kCrashpadHandlerEnvVar);
   if (!crashpadHandlerPath.empty())
      handlerPath = FilePath(crashpadHandlerPath);
   else
      handlerPath = exePath.getParent().completeChildPath("crashpad_handler");

   std::string handlerPathStr = handlerPath.getAbsolutePath();
   const char* handlerExe = handlerPathStr.c_str();
   argv[0] = handlerExe;

   ::execvp(handlerExe, const_cast<char* const*>(argv));

   // if we get here, we failed to run the crash handler
   // log an error indicating why
   LOG_ERROR(systemError(errno, ERROR_LOCATION));
}

int main(int argc, const char* argv[])
{
   // note: we log all errors and attempt to launch the crashpad handler
   // regardless, as this is a best effort proxy attempt
   log::setProgramId("crash-handler-proxy");
   initializeStderrLog("crash-handler-proxy", log::LogLevel::WARN);

   Error error = ignoreSignal(SigPipe);
   if (error)
      LOG_ERROR(error);

   if (realUserIsRoot() && !effectiveUserIsRoot())
   {
      error = restoreRoot();
      if (error)
         LOG_ERROR(error);
   }

   runCrashHandler(argv);

   // if we get here, we failed to run the crash handler
   return EXIT_FAILURE;
}
<commit_msg>exit failure if root cannot be restored<commit_after>/*
 * CrashHandlerProxyMain.cpp
 *
 * Copyright (C) 2019 by RStudio, Inc.
 *
 */

#include <core/CrashHandler.hpp>
#include <core/system/Environment.hpp>
#include <core/system/PosixSystem.hpp>

using namespace rstudio::core;
using namespace rstudio::core::system;

void runCrashHandler(const char* argv[])
{
   FilePath exePath;
   Error error = executablePath(nullptr, &exePath);
   if (error)
      LOG_ERROR(error);

   FilePath handlerPath;
   std::string crashpadHandlerPath = rstudio::core::system::getenv(kCrashpadHandlerEnvVar);
   if (!crashpadHandlerPath.empty())
      handlerPath = FilePath(crashpadHandlerPath);
   else
      handlerPath = exePath.getParent().completeChildPath("crashpad_handler");

   std::string handlerPathStr = handlerPath.getAbsolutePath();
   const char* handlerExe = handlerPathStr.c_str();
   argv[0] = handlerExe;

   ::execvp(handlerExe, const_cast<char* const*>(argv));

   // if we get here, we failed to run the crash handler
   // log an error indicating why
   LOG_ERROR(systemError(errno, ERROR_LOCATION));
}

int main(int argc, const char* argv[])
{
   // note: we log all errors and attempt to launch the crashpad handler
   // regardless, as this is a best effort proxy attempt
   log::setProgramId("crash-handler-proxy");
   initializeStderrLog("crash-handler-proxy", log::LogLevel::WARN);

   Error error = ignoreSignal(SigPipe);
   if (error)
      LOG_ERROR(error);

   if (realUserIsRoot() && !effectiveUserIsRoot())
   {
      error = restoreRoot();
      if (error)
      {
         LOG_ERROR(error);
         return EXIT_FAILURE;
      }
   }

   runCrashHandler(argv);

   // if we get here, we failed to run the crash handler
   return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>/*
 * SessionPresentation.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

// TODO: transition's don't work
// TODO: italic's don't work

// TODO: more generous default width
// TODO: align scaling with default width

// TODO: stable path for view in browser
// TODO: external css
// TODO: presentation Depends when possible

// TODO: keyword highlight only after ===
// TODO: custom code navigator for presentations
// TODO: run all chunks doesn't work for Rpres

#include "SessionPresentation.hpp"

#include <boost/bind.hpp>

#include <core/Exec.hpp>
#include <core/http/Util.hpp>
#include <core/FileSerializer.hpp>
#include <core/text/TemplateFilter.hpp>

#include <r/RSexp.hpp>
#include <r/RExec.hpp>
#include <r/RRoutines.hpp>

#include <session/SessionModuleContext.hpp>
#include <session/projects/SessionProjects.hpp>

#include "../SessionRPubs.hpp"

#include "PresentationLog.hpp"
#include "PresentationState.hpp"
#include "SlideRequestHandler.hpp"

using namespace core;

namespace session {
namespace modules {
namespace presentation {

namespace {

void showPresentation(const FilePath& filePath)
{
   // initialize state
   presentation::state::init(filePath);

   // notify the client
   ClientEvent event(client_events::kShowPresentationPane,
                     presentation::state::asJson());
   module_context::enqueClientEvent(event);
}

SEXP rs_showPresentation(SEXP fileSEXP)
{
   try
   {
      // validate path
      FilePath filePath(r::sexp::asString(fileSEXP));
      if (!filePath.exists())
         throw r::exec::RErrorException("File path " + filePath.absolutePath() +
                                        " does not exist.");

      showPresentation(filePath);
   }
   catch(const r::exec::RErrorException& e)
   {
      r::exec::error(e.message());
   }

   return R_NilValue;
}

SEXP rs_showPresentationHelpDoc(SEXP helpDocSEXP)
{
   try
   {
      // verify a presentation is active
      if (!presentation::state::isActive())
      {
         throw r::exec::RErrorException(
                                 "No presentation is currently active");
      }

      // resolve against presentation directory
      std::string helpDoc = r::sexp::asString(helpDocSEXP);
      FilePath helpDocPath = presentation::state::directory().childPath(
                                                                  helpDoc);
      if (!helpDocPath.exists())
      {
         throw r::exec::RErrorException("Path " + helpDocPath.absolutePath()
                                        + " not found.");
      }

      // build url and fire event
      std::string url = "help/presentation/?file=";
      std::string file = module_context::createAliasedPath(helpDocPath);
      url += http::util::urlEncode(file, true);

      ClientEvent event(client_events::kShowHelp, url);
      module_context::enqueClientEvent(event);
   }
   catch(const r::exec::RErrorException& e)
   {
      r::exec::error(e.message());
   }

   return R_NilValue;
}

Error setPresentationSlideIndex(const json::JsonRpcRequest& request,
                                json::JsonRpcResponse*)
{
   int index = 0;
   Error error = json::readParam(request.params, 0, &index);
   if (error)
      return error;

   presentation::state::setSlideIndex(index);

   presentation::log().onSlideIndexChanged(index);

   return Success();
}

Error createNewPresentation(const json::JsonRpcRequest& request,
                            json::JsonRpcResponse* pResponse)
{
   // get file path
   std::string file;
   Error error = json::readParam(request.params, 0, &file);
   if (error)
      return error;
   FilePath filePath = module_context::resolveAliasedPath(file);

   // process template
   std::map<std::string,std::string> vars;
   vars["name"] = filePath.stem();
   core::text::TemplateFilter filter(vars);

   // read file with template filter
   FilePath templatePath = session::options().rResourcesPath().complete(
                                             "templates/r_presentation.Rpres");
   std::string presContents;
   error = core::readStringFromFile(templatePath, filter, &presContents);
   if (error)
      return error;

   // write file
   return core::writeStringToFile(filePath,
                                  presContents,
                                  string_utils::LineEndingNative);
}

Error showPresentationPane(const json::JsonRpcRequest& request,
                            json::JsonRpcResponse* pResponse)
{
   std::string file;
   Error error = json::readParam(request.params, 0, &file);
   if (error)
      return error;

   FilePath filePath = module_context::resolveAliasedPath(file);
   if (!filePath.exists())
      return core::fileNotFoundError(filePath, ERROR_LOCATION);

   showPresentation(filePath);

   return Success();
}

Error closePresentationPane(const json::JsonRpcRequest&,
                            json::JsonRpcResponse*)
{
   presentation::state::clear();

   return Success();
}

Error presentationExecuteCode(const json::JsonRpcRequest& request,
                              json::JsonRpcResponse* pResponse)
{
   // get the code
   std::string code;
   Error error = json::readParam(request.params, 0, &code);
   if (error)
      return error;

   // confirm we are active
   if (!presentation::state::isActive())
   {
      pResponse->setError(json::errc::MethodUnexpected);
      return Success();
   }

   // execute within the context of either the tutorial project directory
   // or presentation directory
   RestoreCurrentPathScope restorePathScope(
                                          module_context::safeCurrentPath());
   if (presentation::state::isTutorial() &&
       projects::projectContext().hasProject())
   {
      error = projects::projectContext().directory().makeCurrentPath();
   }
   else
   {
      error = presentation::state::directory().makeCurrentPath();
   }
   if (error)
      return error;

   // actually execute the code (show error in the console)
   error = r::exec::executeString(code);
   if (error)
   {
      std::string errMsg = "Error executing code: " + code + "\n";
      errMsg += r::endUserErrorMessage(error);
      module_context::consoleWriteError(errMsg + "\n");
   }

   return Success();
}

Error setWorkingDirectory(const json::JsonRpcRequest& request,
                            json::JsonRpcResponse*)
{
   // get the path
   std::string path;
   Error error = json::readParam(request.params, 0, &path);
   if (error)
      return error;

   // set current path
   FilePath filePath = module_context::resolveAliasedPath(path);
   return filePath.makeCurrentPath();
}

Error tutorialFeedback(const json::JsonRpcRequest& request,
                       json::JsonRpcResponse* pResponse)
{
   // get the feedback
   std::string feedback;
   Error error = json::readParam(request.params, 0, &feedback);
   if (error)
      return error;

   // confirm we are active
   if (!presentation::state::isActive())
   {
      pResponse->setError(json::errc::MethodUnexpected);
      return Success();
   }

   // record the feedback
   presentation::log().recordFeedback(feedback);

   return Success();
}

Error tutorialQuizResponse(const json::JsonRpcRequest& request,
                           json::JsonRpcResponse* pResponse)
{
   // get the params
   int slideIndex, answer;
   bool correct;
   Error error = json::readParams(request.params,
                                  &slideIndex,
                                  &answer,
                                  &correct);
   if (error)
      return error;

   // confirm we are active
   if (!presentation::state::isActive())
   {
      pResponse->setError(json::errc::MethodUnexpected);
      return Success();
   }

   // record the feedback
   presentation::log().recordQuizResponse(slideIndex, answer, correct);

   return Success();
}

Error createStandalonePresentation(const json::JsonRpcRequest& request,
                                   json::JsonRpcResponse* pResponse)
{
   std::string pathParam;
   Error error = json::readParam(request.params, 0, &pathParam);
   if (error)
      return error;

   FilePath targetPath;
   if (!pathParam.empty())
      targetPath = module_context::resolveAliasedPath(pathParam);

   std::string errMsg;
   if (savePresentationAsStandalone(&targetPath, &errMsg))
   {
      pResponse->setResult(module_context::createAliasedPath(targetPath));
   }
   else
   {
      pResponse->setError(systemError(boost::system::errc::io_error,
                                      ERROR_LOCATION),
                          json::toJsonString(errMsg));
   }

   return Success();
}

Error createPresentationRpubsSource(const json::JsonRpcRequest& request,
                                    json::JsonRpcResponse* pResponse)
{
   // use a stable location in the presentation directory for the Rpubs
   // source file so that update works across sessions
   std::string stem = presentation::state::filePath().stem();
   FilePath filePath = presentation::state::directory().childPath(
                                                      stem + "-rpubs.html");

   std::string errMsg;
   if (savePresentationAsRpubsSource(filePath, &errMsg))
   {
      json::Object resultJson;
      resultJson["published"] = !rpubs::previousUploadId(filePath).empty();
      resultJson["source_file_path"] = module_context::createAliasedPath(
                                                                     filePath);
      pResponse->setResult(resultJson);
   }
   else
   {
      pResponse->setError(systemError(boost::system::errc::io_error,
                                      ERROR_LOCATION),
                          json::toJsonString(errMsg));
   }

   return Success();
}

} // anonymous namespace

json::Value presentationStateAsJson()
{
   return presentation::state::asJson();
}

Error initialize()
{
   // register rs_showPresentation
   R_CallMethodDef methodDefShowPresentation;
   methodDefShowPresentation.name = "rs_showPresentation" ;
   methodDefShowPresentation.fun = (DL_FUNC) rs_showPresentation;
   methodDefShowPresentation.numArgs = 1;
   r::routines::addCallMethod(methodDefShowPresentation);

   // register rs_showPresentationHelpDoc
   R_CallMethodDef methodDefShowHelpDoc;
   methodDefShowHelpDoc.name = "rs_showPresentationHelpDoc" ;
   methodDefShowHelpDoc.fun = (DL_FUNC) rs_showPresentationHelpDoc;
   methodDefShowHelpDoc.numArgs = 1;
   r::routines::addCallMethod(methodDefShowHelpDoc);

   // initialize presentation log
   Error error = log().initialize();
   if (error)
      return error;

   using boost::bind;
   using namespace session::module_context;
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(registerUriHandler, "/presentation", handlePresentationPaneRequest))
      (bind(registerRpcMethod, "create_standalone_presentation", createStandalonePresentation))
      (bind(registerRpcMethod, "create_presentation_rpubs_source", createPresentationRpubsSource))
      (bind(registerRpcMethod, "set_presentation_slide_index", setPresentationSlideIndex))
      (bind(registerRpcMethod, "create_new_presentation", createNewPresentation))
      (bind(registerRpcMethod, "show_presentation_pane", showPresentationPane))
      (bind(registerRpcMethod, "close_presentation_pane", closePresentationPane))
      (bind(registerRpcMethod, "presentation_execute_code", presentationExecuteCode))
      (bind(registerRpcMethod, "set_working_directory", setWorkingDirectory))
      (bind(registerRpcMethod, "tutorial_feedback", tutorialFeedback))
      (bind(registerRpcMethod, "tutorial_quiz_response", tutorialQuizResponse))
      (bind(presentation::state::initialize))
      (bind(sourceModuleRFile, "SessionPresentation.R"));

   return initBlock.execute();
}

} // namespace presentation
} // namespace modules
} // namesapce session

<commit_msg>add todos<commit_after>/*
 * SessionPresentation.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

// TODO: transition's don't work
// TODO: italic's don't work

// TODO: more generous default width
// TODO: align scaling with default width

// TODO: stable path for view in browser
// TODO: external css
// TODO: presentation Depends when possible

// TODO: keyword highlight only after ===
// TODO: custom code navigator for presentations
// TODO: run all chunks doesn't work for Rpres

// TODO: depends should be a feature of presentations
// TODO: auto-prompt for installation of pres packages

#include "SessionPresentation.hpp"

#include <boost/bind.hpp>

#include <core/Exec.hpp>
#include <core/http/Util.hpp>
#include <core/FileSerializer.hpp>
#include <core/text/TemplateFilter.hpp>

#include <r/RSexp.hpp>
#include <r/RExec.hpp>
#include <r/RRoutines.hpp>

#include <session/SessionModuleContext.hpp>
#include <session/projects/SessionProjects.hpp>

#include "../SessionRPubs.hpp"

#include "PresentationLog.hpp"
#include "PresentationState.hpp"
#include "SlideRequestHandler.hpp"

using namespace core;

namespace session {
namespace modules {
namespace presentation {

namespace {

void showPresentation(const FilePath& filePath)
{
   // initialize state
   presentation::state::init(filePath);

   // notify the client
   ClientEvent event(client_events::kShowPresentationPane,
                     presentation::state::asJson());
   module_context::enqueClientEvent(event);
}

SEXP rs_showPresentation(SEXP fileSEXP)
{
   try
   {
      // validate path
      FilePath filePath(r::sexp::asString(fileSEXP));
      if (!filePath.exists())
         throw r::exec::RErrorException("File path " + filePath.absolutePath() +
                                        " does not exist.");

      showPresentation(filePath);
   }
   catch(const r::exec::RErrorException& e)
   {
      r::exec::error(e.message());
   }

   return R_NilValue;
}

SEXP rs_showPresentationHelpDoc(SEXP helpDocSEXP)
{
   try
   {
      // verify a presentation is active
      if (!presentation::state::isActive())
      {
         throw r::exec::RErrorException(
                                 "No presentation is currently active");
      }

      // resolve against presentation directory
      std::string helpDoc = r::sexp::asString(helpDocSEXP);
      FilePath helpDocPath = presentation::state::directory().childPath(
                                                                  helpDoc);
      if (!helpDocPath.exists())
      {
         throw r::exec::RErrorException("Path " + helpDocPath.absolutePath()
                                        + " not found.");
      }

      // build url and fire event
      std::string url = "help/presentation/?file=";
      std::string file = module_context::createAliasedPath(helpDocPath);
      url += http::util::urlEncode(file, true);

      ClientEvent event(client_events::kShowHelp, url);
      module_context::enqueClientEvent(event);
   }
   catch(const r::exec::RErrorException& e)
   {
      r::exec::error(e.message());
   }

   return R_NilValue;
}

Error setPresentationSlideIndex(const json::JsonRpcRequest& request,
                                json::JsonRpcResponse*)
{
   int index = 0;
   Error error = json::readParam(request.params, 0, &index);
   if (error)
      return error;

   presentation::state::setSlideIndex(index);

   presentation::log().onSlideIndexChanged(index);

   return Success();
}

Error createNewPresentation(const json::JsonRpcRequest& request,
                            json::JsonRpcResponse* pResponse)
{
   // get file path
   std::string file;
   Error error = json::readParam(request.params, 0, &file);
   if (error)
      return error;
   FilePath filePath = module_context::resolveAliasedPath(file);

   // process template
   std::map<std::string,std::string> vars;
   vars["name"] = filePath.stem();
   core::text::TemplateFilter filter(vars);

   // read file with template filter
   FilePath templatePath = session::options().rResourcesPath().complete(
                                             "templates/r_presentation.Rpres");
   std::string presContents;
   error = core::readStringFromFile(templatePath, filter, &presContents);
   if (error)
      return error;

   // write file
   return core::writeStringToFile(filePath,
                                  presContents,
                                  string_utils::LineEndingNative);
}

Error showPresentationPane(const json::JsonRpcRequest& request,
                            json::JsonRpcResponse* pResponse)
{
   std::string file;
   Error error = json::readParam(request.params, 0, &file);
   if (error)
      return error;

   FilePath filePath = module_context::resolveAliasedPath(file);
   if (!filePath.exists())
      return core::fileNotFoundError(filePath, ERROR_LOCATION);

   showPresentation(filePath);

   return Success();
}

Error closePresentationPane(const json::JsonRpcRequest&,
                            json::JsonRpcResponse*)
{
   presentation::state::clear();

   return Success();
}

Error presentationExecuteCode(const json::JsonRpcRequest& request,
                              json::JsonRpcResponse* pResponse)
{
   // get the code
   std::string code;
   Error error = json::readParam(request.params, 0, &code);
   if (error)
      return error;

   // confirm we are active
   if (!presentation::state::isActive())
   {
      pResponse->setError(json::errc::MethodUnexpected);
      return Success();
   }

   // execute within the context of either the tutorial project directory
   // or presentation directory
   RestoreCurrentPathScope restorePathScope(
                                          module_context::safeCurrentPath());
   if (presentation::state::isTutorial() &&
       projects::projectContext().hasProject())
   {
      error = projects::projectContext().directory().makeCurrentPath();
   }
   else
   {
      error = presentation::state::directory().makeCurrentPath();
   }
   if (error)
      return error;

   // actually execute the code (show error in the console)
   error = r::exec::executeString(code);
   if (error)
   {
      std::string errMsg = "Error executing code: " + code + "\n";
      errMsg += r::endUserErrorMessage(error);
      module_context::consoleWriteError(errMsg + "\n");
   }

   return Success();
}

Error setWorkingDirectory(const json::JsonRpcRequest& request,
                            json::JsonRpcResponse*)
{
   // get the path
   std::string path;
   Error error = json::readParam(request.params, 0, &path);
   if (error)
      return error;

   // set current path
   FilePath filePath = module_context::resolveAliasedPath(path);
   return filePath.makeCurrentPath();
}

Error tutorialFeedback(const json::JsonRpcRequest& request,
                       json::JsonRpcResponse* pResponse)
{
   // get the feedback
   std::string feedback;
   Error error = json::readParam(request.params, 0, &feedback);
   if (error)
      return error;

   // confirm we are active
   if (!presentation::state::isActive())
   {
      pResponse->setError(json::errc::MethodUnexpected);
      return Success();
   }

   // record the feedback
   presentation::log().recordFeedback(feedback);

   return Success();
}

Error tutorialQuizResponse(const json::JsonRpcRequest& request,
                           json::JsonRpcResponse* pResponse)
{
   // get the params
   int slideIndex, answer;
   bool correct;
   Error error = json::readParams(request.params,
                                  &slideIndex,
                                  &answer,
                                  &correct);
   if (error)
      return error;

   // confirm we are active
   if (!presentation::state::isActive())
   {
      pResponse->setError(json::errc::MethodUnexpected);
      return Success();
   }

   // record the feedback
   presentation::log().recordQuizResponse(slideIndex, answer, correct);

   return Success();
}

Error createStandalonePresentation(const json::JsonRpcRequest& request,
                                   json::JsonRpcResponse* pResponse)
{
   std::string pathParam;
   Error error = json::readParam(request.params, 0, &pathParam);
   if (error)
      return error;

   FilePath targetPath;
   if (!pathParam.empty())
      targetPath = module_context::resolveAliasedPath(pathParam);

   std::string errMsg;
   if (savePresentationAsStandalone(&targetPath, &errMsg))
   {
      pResponse->setResult(module_context::createAliasedPath(targetPath));
   }
   else
   {
      pResponse->setError(systemError(boost::system::errc::io_error,
                                      ERROR_LOCATION),
                          json::toJsonString(errMsg));
   }

   return Success();
}

Error createPresentationRpubsSource(const json::JsonRpcRequest& request,
                                    json::JsonRpcResponse* pResponse)
{
   // use a stable location in the presentation directory for the Rpubs
   // source file so that update works across sessions
   std::string stem = presentation::state::filePath().stem();
   FilePath filePath = presentation::state::directory().childPath(
                                                      stem + "-rpubs.html");

   std::string errMsg;
   if (savePresentationAsRpubsSource(filePath, &errMsg))
   {
      json::Object resultJson;
      resultJson["published"] = !rpubs::previousUploadId(filePath).empty();
      resultJson["source_file_path"] = module_context::createAliasedPath(
                                                                     filePath);
      pResponse->setResult(resultJson);
   }
   else
   {
      pResponse->setError(systemError(boost::system::errc::io_error,
                                      ERROR_LOCATION),
                          json::toJsonString(errMsg));
   }

   return Success();
}

} // anonymous namespace

json::Value presentationStateAsJson()
{
   return presentation::state::asJson();
}

Error initialize()
{
   // register rs_showPresentation
   R_CallMethodDef methodDefShowPresentation;
   methodDefShowPresentation.name = "rs_showPresentation" ;
   methodDefShowPresentation.fun = (DL_FUNC) rs_showPresentation;
   methodDefShowPresentation.numArgs = 1;
   r::routines::addCallMethod(methodDefShowPresentation);

   // register rs_showPresentationHelpDoc
   R_CallMethodDef methodDefShowHelpDoc;
   methodDefShowHelpDoc.name = "rs_showPresentationHelpDoc" ;
   methodDefShowHelpDoc.fun = (DL_FUNC) rs_showPresentationHelpDoc;
   methodDefShowHelpDoc.numArgs = 1;
   r::routines::addCallMethod(methodDefShowHelpDoc);

   // initialize presentation log
   Error error = log().initialize();
   if (error)
      return error;

   using boost::bind;
   using namespace session::module_context;
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(registerUriHandler, "/presentation", handlePresentationPaneRequest))
      (bind(registerRpcMethod, "create_standalone_presentation", createStandalonePresentation))
      (bind(registerRpcMethod, "create_presentation_rpubs_source", createPresentationRpubsSource))
      (bind(registerRpcMethod, "set_presentation_slide_index", setPresentationSlideIndex))
      (bind(registerRpcMethod, "create_new_presentation", createNewPresentation))
      (bind(registerRpcMethod, "show_presentation_pane", showPresentationPane))
      (bind(registerRpcMethod, "close_presentation_pane", closePresentationPane))
      (bind(registerRpcMethod, "presentation_execute_code", presentationExecuteCode))
      (bind(registerRpcMethod, "set_working_directory", setWorkingDirectory))
      (bind(registerRpcMethod, "tutorial_feedback", tutorialFeedback))
      (bind(registerRpcMethod, "tutorial_quiz_response", tutorialQuizResponse))
      (bind(presentation::state::initialize))
      (bind(sourceModuleRFile, "SessionPresentation.R"));

   return initBlock.execute();
}

} // namespace presentation
} // namespace modules
} // namesapce session

<|endoftext|>


<commit_before>//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include <cstdlib>
using namespace llvm;

MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
}

MCStreamer::~MCStreamer() {
}

raw_ostream &MCStreamer::GetCommentOS() {
  // By default, discard comments.
  return nulls();
}

/// EmitIntValue - Special case of EmitValue that avoids the client having to
/// pass in a MCExpr for constant integers.
void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
                              unsigned AddrSpace) {
  EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
}

void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
                                 unsigned AddrSpace) {
  EmitValue(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace);
}

/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue.  This implements directives such as '.space'.
void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
                          unsigned AddrSpace) {
  const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
    EmitValue(E, 1, AddrSpace);
}

/// EmitRawText - If this file is backed by a assembly streamer, this dumps
/// the specified string in the output .s file.  This capability is
/// indicated by the hasRawTextSupport() predicate.
void MCStreamer::EmitRawText(StringRef String) {
  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
  " something must not be fully mc'ized\n";
  abort();
}

void MCStreamer::EmitRawText(const Twine &T) {
  SmallString<128> Str;
  T.toVector(Str);
  EmitRawText(Str.str());
}
<commit_msg>Grammar fix. This is a test commit.<commit_after>//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include <cstdlib>
using namespace llvm;

MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
}

MCStreamer::~MCStreamer() {
}

raw_ostream &MCStreamer::GetCommentOS() {
  // By default, discard comments.
  return nulls();
}

/// EmitIntValue - Special case of EmitValue that avoids the client having to
/// pass in a MCExpr for constant integers.
void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
                              unsigned AddrSpace) {
  EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
}

void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
                                 unsigned AddrSpace) {
  EmitValue(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace);
}

/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue.  This implements directives such as '.space'.
void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
                          unsigned AddrSpace) {
  const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
    EmitValue(E, 1, AddrSpace);
}

/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file.  This capability is
/// indicated by the hasRawTextSupport() predicate.
void MCStreamer::EmitRawText(StringRef String) {
  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
  " something must not be fully mc'ized\n";
  abort();
}

void MCStreamer::EmitRawText(const Twine &T) {
  SmallString<128> Str;
  T.toVector(Str);
  EmitRawText(Str.str());
}
<|endoftext|>


<commit_before>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/isolate.h"

#include "include/dart_api.h"

#include "vm/assert.h"
#include "vm/bigint_store.h"
#include "vm/code_index_table.h"
#include "vm/compiler_stats.h"
#include "vm/dart_api_state.h"
#include "vm/debuginfo.h"
#include "vm/heap.h"
#include "vm/message_queue.h"
#include "vm/object_store.h"
#include "vm/parser.h"
#include "vm/port.h"
#include "vm/random.h"
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/thread.h"
#include "vm/timer.h"
#include "vm/visitor.h"

namespace dart {

DEFINE_FLAG(bool, report_invocation_count, false,
    "Count function invocations and report.");
DECLARE_FLAG(bool, generate_gdb_symbols);

Isolate::Isolate()
    : store_buffer_(),
      message_queue_(NULL),
      post_message_callback_(NULL),
      close_port_callback_(NULL),
      active_ports_(0),
      heap_(NULL),
      object_store_(NULL),
      top_resource_(NULL),
      top_context_(Context::null()),
      current_zone_(NULL),
#if defined(DEBUG)
      no_gc_scope_depth_(0),
      no_handle_scope_depth_(0),
      top_handle_scope_(NULL),
#endif
      random_seed_(Random::kDefaultRandomSeed),
      bigint_store_(NULL),
      top_exit_frame_info_(0),
      init_callback_data_(NULL),
      library_tag_handler_(NULL),
      api_state_(NULL),
      stub_code_(NULL),
      code_index_table_(NULL),
      long_jump_base_(NULL),
      timer_list_(),
      stack_limit_(0),
      stack_limit_on_overflow_exception_(0),
      ast_node_id_(AstNode::kNoId) {
}

Isolate::~Isolate() {
  delete message_queue_;
  delete heap_;
  delete object_store_;
  // Do not delete stack resources: top_resource_ and current_zone_.
  delete bigint_store_;
  delete api_state_;
  delete stub_code_;
  delete code_index_table_;
}

static bool StandardPostMessageCallback(Dart_Isolate dart_isolate,
                                        Dart_Port dest_port,
                                        Dart_Port reply_port,
                                        Dart_Message dart_message) {
  Isolate* isolate = reinterpret_cast<Isolate*>(dart_isolate);
  ASSERT(isolate != NULL);
  PortMessage* message = new PortMessage(dest_port, reply_port, dart_message);
  isolate->message_queue()->Enqueue(message);
  return true;
}

static void StandardClosePortCallback(Dart_Isolate dart_isolate,
                                      Dart_Port port) {
  // Remove the pending messages for this port.
  Isolate* isolate = reinterpret_cast<Isolate*>(dart_isolate);
  ASSERT(isolate != NULL);
  if (port == kCloseAllPorts) {
    isolate->message_queue()->FlushAll();
  } else {
    isolate->message_queue()->Flush(port);
  }
}

Isolate* Isolate::Init() {
  Isolate* result = new Isolate();
  ASSERT(result != NULL);

  // TODO(5411455): For now just set the recently created isolate as
  // the current isolate.
  SetCurrent(result);

  // Set up the isolate message queue.
  MessageQueue* queue = new MessageQueue();
  ASSERT(queue != NULL);
  result->set_message_queue(queue);
  result->set_post_message_callback(&StandardPostMessageCallback);
  result->set_close_port_callback(&StandardClosePortCallback);

  // Setup the Dart API state.
  ApiState* state = new ApiState();
  ASSERT(state != NULL);
  result->set_api_state(state);

  // Initialize stack top and limit in case we are running the isolate in the
  // main thread.
  // TODO(5411455): Need to figure out how to set the stack limit for the
  // main thread.
  result->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&result));

  return result;
}

// TODO(5411455): Use flag to override default value and Validate the
// stack size by querying OS.
uword Isolate::GetSpecifiedStackSize() {
  uword stack_size = Isolate::kDefaultStackSize - Isolate::kStackSizeBuffer;
  return stack_size;
}

void Isolate::SetStackLimitFromCurrentTOS(uword stack_top_value) {
  SetStackLimit(stack_top_value - GetSpecifiedStackSize());
}

void Isolate::SetStackLimit(uword limit) {
  stack_limit_ = limit;
  stack_limit_on_overflow_exception_ = limit - kStackSizeBuffer;
}

static int MostCalledFunctionFirst(const Function* const* a,
                                   const Function* const* b) {
  if ((*a)->invocation_counter() > (*b)->invocation_counter()) {
    return -1;
  } else if ((*a)->invocation_counter() < (*b)->invocation_counter()) {
    return 1;
  } else {
    return 0;
  }
}

void Isolate::PrintInvokedFunctions() {
  Zone zone;
  HandleScope handle_scope;
  Library& library = Library::Handle();
  library = object_store()->registered_libraries();
  GrowableArray<const Function*> invoked_functions;
  while (!library.IsNull()) {
    Class& cls = Class::Handle();
    ClassDictionaryIterator iter(library);
    while (iter.HasNext()) {
      cls = iter.GetNextClass();
      const Array& functions = Array::Handle(cls.functions());
      for (int j = 0; j < functions.Length(); j++) {
        Function& function = Function::Handle();
        function ^= functions.At(j);
        if (function.invocation_counter() > 0) {
          invoked_functions.Add(&function);
        }
      }
    }
    library = library.next_registered();
  }
  invoked_functions.Sort(MostCalledFunctionFirst);
  for (int i = 0; i < invoked_functions.length(); i++) {
    OS::Print("%10d x %s\n",
        invoked_functions[i]->invocation_counter(),
        invoked_functions[i]->ToFullyQualifiedCString());
  }
}

void Isolate::Shutdown() {
  ASSERT(this == Isolate::Current());
  ASSERT(top_resource_ == NULL);
  ASSERT((heap_ == NULL) || heap_->Verify());

  // Close all the ports owned by this isolate.
  PortMap::ClosePorts();

  delete message_queue();
  set_message_queue(NULL);

  // Dump all accumalated timer data for the isolate.
  timer_list_.ReportTimers();
  if (FLAG_report_invocation_count) {
    PrintInvokedFunctions();
  }
  CompilerStats::Print();
  if (FLAG_generate_gdb_symbols) {
    DebugInfo::UnregisterAllSections();
  }

  // TODO(5411455): For now just make sure there are no current isolates
  // as we are shutting down the isolate.
  SetCurrent(NULL);
}

Dart_IsolateInitCallback Isolate::init_callback_ = NULL;

void Isolate::SetInitCallback(Dart_IsolateInitCallback callback) {
  init_callback_ = callback;
}

Dart_IsolateInitCallback Isolate::InitCallback() {
  return init_callback_;
}

void Isolate::StandardRunLoop() {
  ASSERT(long_jump_base() != NULL);
  ASSERT(post_message_callback() == &StandardPostMessageCallback);
  ASSERT(close_port_callback() == &StandardClosePortCallback);

  while (active_ports() > 0) {
    Zone zone;
    HandleScope handle_scope;

    PortMessage* message = message_queue()->Dequeue(0);
    if (message != NULL) {
      Dart_HandleMessage(
          message->dest_port(), message->reply_port(), message->data());
      delete message;
    }
  }
}

void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                  bool validate_frames) {
  ASSERT(visitor != NULL);

  // Visit objects in the object store.
  object_store()->VisitObjectPointers(visitor);

  // Visit objects in per isolate stubs.
  StubCode::VisitObjectPointers(visitor);

  // Visit objects in zones.
  current_zone()->VisitObjectPointers(visitor);

  // Iterate over all the stack frames and visit objects on the stack.
  StackFrameIterator frames_iterator(validate_frames);
  StackFrame* frame = frames_iterator.NextFrame();
  while (frame != NULL) {
    frame->VisitObjectPointers(visitor);
    frame = frames_iterator.NextFrame();
  }

  // Visit the dart api state for all local and persistent handles.
  if (api_state() != NULL) {
    api_state()->VisitObjectPointers(visitor);
  }

  // Visit all objects in the code index table.
  if (code_index_table() != NULL) {
    code_index_table()->VisitObjectPointers(visitor);
  }

  // Visit the top context which is stored in the isolate.
  visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_context_));
}

}  // namespace dart
<commit_msg>Fix crash when running with --report_invocation_count. Review URL: http://codereview.chromium.org//8497032<commit_after>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/isolate.h"

#include "include/dart_api.h"

#include "vm/assert.h"
#include "vm/bigint_store.h"
#include "vm/code_index_table.h"
#include "vm/compiler_stats.h"
#include "vm/dart_api_state.h"
#include "vm/debuginfo.h"
#include "vm/heap.h"
#include "vm/message_queue.h"
#include "vm/object_store.h"
#include "vm/parser.h"
#include "vm/port.h"
#include "vm/random.h"
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/thread.h"
#include "vm/timer.h"
#include "vm/visitor.h"

namespace dart {

DEFINE_FLAG(bool, report_invocation_count, false,
    "Count function invocations and report.");
DECLARE_FLAG(bool, generate_gdb_symbols);

Isolate::Isolate()
    : store_buffer_(),
      message_queue_(NULL),
      post_message_callback_(NULL),
      close_port_callback_(NULL),
      active_ports_(0),
      heap_(NULL),
      object_store_(NULL),
      top_resource_(NULL),
      top_context_(Context::null()),
      current_zone_(NULL),
#if defined(DEBUG)
      no_gc_scope_depth_(0),
      no_handle_scope_depth_(0),
      top_handle_scope_(NULL),
#endif
      random_seed_(Random::kDefaultRandomSeed),
      bigint_store_(NULL),
      top_exit_frame_info_(0),
      init_callback_data_(NULL),
      library_tag_handler_(NULL),
      api_state_(NULL),
      stub_code_(NULL),
      code_index_table_(NULL),
      long_jump_base_(NULL),
      timer_list_(),
      stack_limit_(0),
      stack_limit_on_overflow_exception_(0),
      ast_node_id_(AstNode::kNoId) {
}

Isolate::~Isolate() {
  delete message_queue_;
  delete heap_;
  delete object_store_;
  // Do not delete stack resources: top_resource_ and current_zone_.
  delete bigint_store_;
  delete api_state_;
  delete stub_code_;
  delete code_index_table_;
}

static bool StandardPostMessageCallback(Dart_Isolate dart_isolate,
                                        Dart_Port dest_port,
                                        Dart_Port reply_port,
                                        Dart_Message dart_message) {
  Isolate* isolate = reinterpret_cast<Isolate*>(dart_isolate);
  ASSERT(isolate != NULL);
  PortMessage* message = new PortMessage(dest_port, reply_port, dart_message);
  isolate->message_queue()->Enqueue(message);
  return true;
}

static void StandardClosePortCallback(Dart_Isolate dart_isolate,
                                      Dart_Port port) {
  // Remove the pending messages for this port.
  Isolate* isolate = reinterpret_cast<Isolate*>(dart_isolate);
  ASSERT(isolate != NULL);
  if (port == kCloseAllPorts) {
    isolate->message_queue()->FlushAll();
  } else {
    isolate->message_queue()->Flush(port);
  }
}

Isolate* Isolate::Init() {
  Isolate* result = new Isolate();
  ASSERT(result != NULL);

  // TODO(5411455): For now just set the recently created isolate as
  // the current isolate.
  SetCurrent(result);

  // Set up the isolate message queue.
  MessageQueue* queue = new MessageQueue();
  ASSERT(queue != NULL);
  result->set_message_queue(queue);
  result->set_post_message_callback(&StandardPostMessageCallback);
  result->set_close_port_callback(&StandardClosePortCallback);

  // Setup the Dart API state.
  ApiState* state = new ApiState();
  ASSERT(state != NULL);
  result->set_api_state(state);

  // Initialize stack top and limit in case we are running the isolate in the
  // main thread.
  // TODO(5411455): Need to figure out how to set the stack limit for the
  // main thread.
  result->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&result));

  return result;
}

// TODO(5411455): Use flag to override default value and Validate the
// stack size by querying OS.
uword Isolate::GetSpecifiedStackSize() {
  uword stack_size = Isolate::kDefaultStackSize - Isolate::kStackSizeBuffer;
  return stack_size;
}

void Isolate::SetStackLimitFromCurrentTOS(uword stack_top_value) {
  SetStackLimit(stack_top_value - GetSpecifiedStackSize());
}

void Isolate::SetStackLimit(uword limit) {
  stack_limit_ = limit;
  stack_limit_on_overflow_exception_ = limit - kStackSizeBuffer;
}

static int MostCalledFunctionFirst(const Function* const* a,
                                   const Function* const* b) {
  if ((*a)->invocation_counter() > (*b)->invocation_counter()) {
    return -1;
  } else if ((*a)->invocation_counter() < (*b)->invocation_counter()) {
    return 1;
  } else {
    return 0;
  }
}

void Isolate::PrintInvokedFunctions() {
  Zone zone;
  HandleScope handle_scope;
  Library& library = Library::Handle();
  library = object_store()->registered_libraries();
  GrowableArray<const Function*> invoked_functions;
  while (!library.IsNull()) {
    Class& cls = Class::Handle();
    ClassDictionaryIterator iter(library);
    while (iter.HasNext()) {
      cls = iter.GetNextClass();
      const Array& functions = Array::Handle(cls.functions());
      // Class 'Dynamic' is allocated/initialized in a special way, leaving
      // the functions field NULL instead of empty.
      const int func_len = functions.IsNull() ? 0 : functions.Length();
      for (int j = 0; j < func_len; j++) {
        Function& function = Function::Handle();
        function ^= functions.At(j);
        if (function.invocation_counter() > 0) {
          invoked_functions.Add(&function);
        }
      }
    }
    library = library.next_registered();
  }
  invoked_functions.Sort(MostCalledFunctionFirst);
  for (int i = 0; i < invoked_functions.length(); i++) {
    OS::Print("%10d x %s\n",
        invoked_functions[i]->invocation_counter(),
        invoked_functions[i]->ToFullyQualifiedCString());
  }
}

void Isolate::Shutdown() {
  ASSERT(this == Isolate::Current());
  ASSERT(top_resource_ == NULL);
  ASSERT((heap_ == NULL) || heap_->Verify());

  // Close all the ports owned by this isolate.
  PortMap::ClosePorts();

  delete message_queue();
  set_message_queue(NULL);

  // Dump all accumalated timer data for the isolate.
  timer_list_.ReportTimers();
  if (FLAG_report_invocation_count) {
    PrintInvokedFunctions();
  }
  CompilerStats::Print();
  if (FLAG_generate_gdb_symbols) {
    DebugInfo::UnregisterAllSections();
  }

  // TODO(5411455): For now just make sure there are no current isolates
  // as we are shutting down the isolate.
  SetCurrent(NULL);
}

Dart_IsolateInitCallback Isolate::init_callback_ = NULL;

void Isolate::SetInitCallback(Dart_IsolateInitCallback callback) {
  init_callback_ = callback;
}

Dart_IsolateInitCallback Isolate::InitCallback() {
  return init_callback_;
}

void Isolate::StandardRunLoop() {
  ASSERT(long_jump_base() != NULL);
  ASSERT(post_message_callback() == &StandardPostMessageCallback);
  ASSERT(close_port_callback() == &StandardClosePortCallback);

  while (active_ports() > 0) {
    Zone zone;
    HandleScope handle_scope;

    PortMessage* message = message_queue()->Dequeue(0);
    if (message != NULL) {
      Dart_HandleMessage(
          message->dest_port(), message->reply_port(), message->data());
      delete message;
    }
  }
}

void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                  bool validate_frames) {
  ASSERT(visitor != NULL);

  // Visit objects in the object store.
  object_store()->VisitObjectPointers(visitor);

  // Visit objects in per isolate stubs.
  StubCode::VisitObjectPointers(visitor);

  // Visit objects in zones.
  current_zone()->VisitObjectPointers(visitor);

  // Iterate over all the stack frames and visit objects on the stack.
  StackFrameIterator frames_iterator(validate_frames);
  StackFrame* frame = frames_iterator.NextFrame();
  while (frame != NULL) {
    frame->VisitObjectPointers(visitor);
    frame = frames_iterator.NextFrame();
  }

  // Visit the dart api state for all local and persistent handles.
  if (api_state() != NULL) {
    api_state()->VisitObjectPointers(visitor);
  }

  // Visit all objects in the code index table.
  if (code_index_table() != NULL) {
    code_index_table()->VisitObjectPointers(visitor);
  }

  // Visit the top context which is stored in the isolate.
  visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_context_));
}

}  // namespace dart
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2010 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*! \file gather.inl
 *  \brief Inline file for gather.h.
 */

#include <thrust/iterator/iterator_traits.h>
#include <thrust/iterator/permutation_iterator.h>

#include <thrust/copy.h>

namespace thrust
{

template<typename InputIterator,
         typename RandomAccessIterator,
         typename OutputIterator>
  OutputIterator gather(InputIterator        map_first,
                        InputIterator        map_last,
                        RandomAccessIterator input_first,
                        OutputIterator       result)
{
  return thrust::copy(thrust::make_permutation_iterator(input_first, map_first),
                      thrust::make_permutation_iterator(input_first, map_last),
                      result);
} // end gather()

template<typename InputIterator1,
         typename InputIterator2,
         typename RandomAccessIterator,
         typename OutputIterator>
  OutputIterator gather_if(InputIterator1       map_first,
                           InputIterator1       map_last,
                           InputIterator2       stencil,
                           RandomAccessIterator input_first,
                           OutputIterator       result)
{
  typedef typename thrust::iterator_value<InputIterator2>::type StencilType;
  return thrust::gather_if(map_first,
                           map_last,
                           stencil,
                           input_first,
                           result,
                           thrust::identity<StencilType>());
} // end gather_if()

template<typename InputIterator1,
         typename InputIterator2,
         typename RandomAccessIterator,
         typename OutputIterator,
         typename Predicate>
  OutputIterator gather_if(InputIterator1       map_first,
                           InputIterator1       map_last,
                           InputIterator2       stencil,
                           RandomAccessIterator input_first,
                           OutputIterator       result,
                           Predicate            pred)
{
  return thrust::copy_when(thrust::make_permutation_iterator(input_first, map_first),
                           thrust::make_permutation_iterator(input_first, map_last),
                           stencil,
                           result,
                           pred);
} // end gather_if()

} // end namespace thrust

<commit_msg>Implement gather_if with transform_if + identity instead of copy_when<commit_after>/*
 *  Copyright 2008-2010 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*! \file gather.inl
 *  \brief Inline file for gather.h.
 */

#include <thrust/iterator/iterator_traits.h>
#include <thrust/iterator/permutation_iterator.h>

#include <thrust/copy.h>
#include <thrust/transform.h>
#include <thrust/functional.h>

namespace thrust
{

template<typename InputIterator,
         typename RandomAccessIterator,
         typename OutputIterator>
  OutputIterator gather(InputIterator        map_first,
                        InputIterator        map_last,
                        RandomAccessIterator input_first,
                        OutputIterator       result)
{
  return thrust::copy(thrust::make_permutation_iterator(input_first, map_first),
                      thrust::make_permutation_iterator(input_first, map_last),
                      result);
} // end gather()

template<typename InputIterator1,
         typename InputIterator2,
         typename RandomAccessIterator,
         typename OutputIterator>
  OutputIterator gather_if(InputIterator1       map_first,
                           InputIterator1       map_last,
                           InputIterator2       stencil,
                           RandomAccessIterator input_first,
                           OutputIterator       result)
{
  typedef typename thrust::iterator_value<InputIterator2>::type StencilType;
  return thrust::gather_if(map_first,
                           map_last,
                           stencil,
                           input_first,
                           result,
                           thrust::identity<StencilType>());
} // end gather_if()

template<typename InputIterator1,
         typename InputIterator2,
         typename RandomAccessIterator,
         typename OutputIterator,
         typename Predicate>
  OutputIterator gather_if(InputIterator1       map_first,
                           InputIterator1       map_last,
                           InputIterator2       stencil,
                           RandomAccessIterator input_first,
                           OutputIterator       result,
                           Predicate            pred)
{
  typedef typename thrust::iterator_value<RandomAccessIterator>::type InputType;
  return thrust::transform_if(thrust::make_permutation_iterator(input_first, map_first),
                              thrust::make_permutation_iterator(input_first, map_last),
                              stencil,
                              result,
                              thrust::identity<InputType>(),
                              pred);
} // end gather_if()

} // end namespace thrust

<|endoftext|>


<commit_before>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <sstream>

#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>

#include <google/protobuf/compiler/csharp/csharp_enum.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message.h>
#include <google/protobuf/compiler/csharp/csharp_names.h>
#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {

UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file)
    : SourceGeneratorBase(file),
      file_(file) {
  namespace_ = GetFileNamespace(file);
  umbrellaClassname_ = GetUmbrellaClassUnqualifiedName(file);
  umbrellaNamespace_ = GetUmbrellaClassNestedNamespace(file);
}

UmbrellaClassGenerator::~UmbrellaClassGenerator() {
}

void UmbrellaClassGenerator::Generate(io::Printer* printer) {
  WriteIntroduction(printer);

  WriteDescriptor(printer);
  // Close the class declaration.
  printer->Outdent();
  printer->Print("}\n");

  // Close the namespace around the umbrella class if defined
  if (!umbrellaNamespace_.empty()) {
    printer->Outdent();
    printer->Print("}\n");
  }

  // write children: Enums
  if (file_->enum_type_count() > 0) {
    printer->Print("#region Enums\n");
    for (int i = 0; i < file_->enum_type_count(); i++) {
      EnumGenerator enumGenerator(file_->enum_type(i));
      enumGenerator.Generate(printer);
    }
    printer->Print("#endregion\n");
    printer->Print("\n");
  }

  // write children: Messages
  if (file_->message_type_count() > 0) {
    printer->Print("#region Messages\n");
    for (int i = 0; i < file_->message_type_count(); i++) {
      MessageGenerator messageGenerator(file_->message_type(i));
      messageGenerator.Generate(printer);
    }
    printer->Print("#endregion\n");
    printer->Print("\n");
  }

  // TODO(jtattermusch): add insertion point for services.

  if (!namespace_.empty()) {
    printer->Outdent();
    printer->Print("}\n");
  }
  printer->Print("\n");
  printer->Print("#endregion Designer generated code\n");
}

void UmbrellaClassGenerator::WriteIntroduction(io::Printer* printer) {
  printer->Print(
    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
    "// source: $file_name$\n"
    "#pragma warning disable 1591, 0612, 3021\n"
    "#region Designer generated code\n"
    "\n"
    "using pb = global::Google.Protobuf;\n"
    "using pbc = global::Google.Protobuf.Collections;\n"
    "using pbr = global::Google.Protobuf.Reflection;\n"
    "using scg = global::System.Collections.Generic;\n",
    "file_name", file_->name());

  if (!namespace_.empty()) {
    printer->Print("namespace $namespace$ {\n", "namespace", namespace_);
    printer->Indent();
    printer->Print("\n");
  }

  // Add the namespace around the umbrella class if defined
  if (!umbrellaNamespace_.empty()) {
    printer->Print("namespace $umbrella_namespace$ {\n",
                   "umbrella_namespace", umbrellaNamespace_);
    printer->Indent();
    printer->Print("\n");
  }

  printer->Print(
    "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
  WriteGeneratedCodeAttributes(printer);
  printer->Print(
    "$access_level$ static partial class $umbrella_class_name$ {\n"
    "\n",
    "access_level", class_access_level(),
    "umbrella_class_name", umbrellaClassname_);
  printer->Indent();
}

void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
  printer->Print(
    "#region Descriptor\n"
    "public static pbr::FileDescriptor Descriptor {\n"
    "  get { return descriptor; }\n"
    "}\n"
    "private static pbr::FileDescriptor descriptor;\n"
    "\n"
    "static $umbrella_class_name$() {\n",
    "umbrella_class_name", umbrellaClassname_);
  printer->Indent();
  printer->Print(
    "byte[] descriptorData = global::System.Convert.FromBase64String(\n");
  printer->Indent();
  printer->Indent();
  printer->Print("string.Concat(\n");
  printer->Indent();

  // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
  std::string base64 = FileDescriptorToBase64(file_);
  while (base64.size() > 60) {
    printer->Print("\"$base64$\", \n", "base64", base64.substr(0, 60));
    base64 = base64.substr(60);
  }
  printer->Print("\"$base64$\"));\n", "base64", base64);
  printer->Outdent();
  printer->Outdent();
  printer->Outdent();

  // -----------------------------------------------------------------
  // Invoke InternalBuildGeneratedFileFrom() to build the file.
  printer->Print(
      "descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n");
  printer->Print("    new pbr::FileDescriptor[] { ");
  for (int i = 0; i < file_->dependency_count(); i++) {
    // descriptor.proto is special: we don't allow access to the generated code, but there's
    // a separately-exposed property to get at the file descriptor, specifically to allow this
    // kind of dependency.
    if (IsDescriptorProto(file_->dependency(i))) {
      printer->Print("pbr::FileDescriptor.DescriptorProtoFileDescriptor, ");
    } else {
      printer->Print(
      "$full_umbrella_class_name$.Descriptor, ",
      "full_umbrella_class_name",
      GetUmbrellaClassName(file_->dependency(i)));
    }
  }
  printer->Print("},\n"
      "    new pbr::GeneratedCodeInfo(");
  // Specify all the generated code information, recursively.
  if (file_->enum_type_count() > 0) {
      printer->Print("new[] {");
      for (int i = 0; i < file_->enum_type_count(); i++) {
          printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i)));
      }
      printer->Print("}, ");
  }
  else {
      printer->Print("null, ");
  }
  if (file_->message_type_count() > 0) {
      printer->Print("new pbr::GeneratedCodeInfo[] {\n");
      printer->Indent();
      printer->Indent();
      printer->Indent();
      for (int i = 0; i < file_->message_type_count(); i++) {
          WriteGeneratedCodeInfo(file_->message_type(i), printer, i == file_->message_type_count() - 1);
      }
      printer->Outdent();
      printer->Print("\n}));\n");
      printer->Outdent();
      printer->Outdent();
  }
  else {
      printer->Print("null));\n");
  }

  printer->Outdent();
  printer->Print("}\n");
  printer->Print("#endregion\n\n");
}

// Write out the generated code for a particular message. This consists of the CLR type, property names
// corresponding to fields, names corresponding to oneofs, nested enums, and nested types. Each array part
// can be specified as null if it would be empty, to make the generated code somewhat simpler to read.
// We write a line break at the end of each generated code info, so that in the final file we'll see all
// the types, pre-ordered depth first, one per line. The indentation will be slightly unusual,
// in that it will look like a single array when it's actually constructing a tree, but it'll be easy to
// read even with multiple levels of nesting.
// The "last" parameter indicates whether this message descriptor is the last one being printed in this immediate
// context. It governs whether or not a trailing comma and newline is written after the constructor, effectively
// just controlling the formatting in the generated code.
void UmbrellaClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last) {
  if (IsMapEntryMessage(descriptor)) {
    printer->Print("null, ");
    return;
  }
  // Generated message type
  printer->Print("new pbr::GeneratedCodeInfo(typeof($type_name$), ", "type_name", GetClassName(descriptor));

  // Fields
  if (descriptor->field_count() > 0) {
      std::vector<std::string> fields;
      for (int i = 0; i < descriptor->field_count(); i++) {
          fields.push_back(GetPropertyName(descriptor->field(i)));
      }
      printer->Print("new[]{ \"$fields$\" }, ", "fields", JoinStrings(fields, "\", \""));
  }
  else {
      printer->Print("null, ");
  }

  // Oneofs
  if (descriptor->oneof_decl_count() > 0) {
      std::vector<std::string> oneofs;
      for (int i = 0; i < descriptor->oneof_decl_count(); i++) {
          oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true));
      }
      printer->Print("new[]{ \"$oneofs$\" }, ", "oneofs", JoinStrings(oneofs, "\", \""));
  }
  else {
      printer->Print("null, ");
  }

  // Nested enums
  if (descriptor->enum_type_count() > 0) {
      std::vector<std::string> enums;
      for (int i = 0; i < descriptor->enum_type_count(); i++) {
          enums.push_back(GetClassName(descriptor->enum_type(i)));
      }
      printer->Print("new[]{ typeof($enums$) }, ", "enums", JoinStrings(enums, "), typeof("));
  }
  else {
      printer->Print("null, ");
  }

  // Nested types
  if (descriptor->nested_type_count() > 0) {
      // Need to specify array type explicitly here, as all elements may be null.
      printer->Print("new pbr::GeneratedCodeInfo[] { ");
      for (int i = 0; i < descriptor->nested_type_count(); i++) {
          WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
      }
      printer->Print("}");
  }
  else {
      printer->Print("null");
  }
  printer->Print(last ? ")" : "),\n");
}

}  // namespace csharp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
<commit_msg>Stop adding a space to the end of lines for descriptor binary data.<commit_after>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <sstream>

#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>

#include <google/protobuf/compiler/csharp/csharp_enum.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message.h>
#include <google/protobuf/compiler/csharp/csharp_names.h>
#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {

UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file)
    : SourceGeneratorBase(file),
      file_(file) {
  namespace_ = GetFileNamespace(file);
  umbrellaClassname_ = GetUmbrellaClassUnqualifiedName(file);
  umbrellaNamespace_ = GetUmbrellaClassNestedNamespace(file);
}

UmbrellaClassGenerator::~UmbrellaClassGenerator() {
}

void UmbrellaClassGenerator::Generate(io::Printer* printer) {
  WriteIntroduction(printer);

  WriteDescriptor(printer);
  // Close the class declaration.
  printer->Outdent();
  printer->Print("}\n");

  // Close the namespace around the umbrella class if defined
  if (!umbrellaNamespace_.empty()) {
    printer->Outdent();
    printer->Print("}\n");
  }

  // write children: Enums
  if (file_->enum_type_count() > 0) {
    printer->Print("#region Enums\n");
    for (int i = 0; i < file_->enum_type_count(); i++) {
      EnumGenerator enumGenerator(file_->enum_type(i));
      enumGenerator.Generate(printer);
    }
    printer->Print("#endregion\n");
    printer->Print("\n");
  }

  // write children: Messages
  if (file_->message_type_count() > 0) {
    printer->Print("#region Messages\n");
    for (int i = 0; i < file_->message_type_count(); i++) {
      MessageGenerator messageGenerator(file_->message_type(i));
      messageGenerator.Generate(printer);
    }
    printer->Print("#endregion\n");
    printer->Print("\n");
  }

  // TODO(jtattermusch): add insertion point for services.

  if (!namespace_.empty()) {
    printer->Outdent();
    printer->Print("}\n");
  }
  printer->Print("\n");
  printer->Print("#endregion Designer generated code\n");
}

void UmbrellaClassGenerator::WriteIntroduction(io::Printer* printer) {
  printer->Print(
    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
    "// source: $file_name$\n"
    "#pragma warning disable 1591, 0612, 3021\n"
    "#region Designer generated code\n"
    "\n"
    "using pb = global::Google.Protobuf;\n"
    "using pbc = global::Google.Protobuf.Collections;\n"
    "using pbr = global::Google.Protobuf.Reflection;\n"
    "using scg = global::System.Collections.Generic;\n",
    "file_name", file_->name());

  if (!namespace_.empty()) {
    printer->Print("namespace $namespace$ {\n", "namespace", namespace_);
    printer->Indent();
    printer->Print("\n");
  }

  // Add the namespace around the umbrella class if defined
  if (!umbrellaNamespace_.empty()) {
    printer->Print("namespace $umbrella_namespace$ {\n",
                   "umbrella_namespace", umbrellaNamespace_);
    printer->Indent();
    printer->Print("\n");
  }

  printer->Print(
    "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
  WriteGeneratedCodeAttributes(printer);
  printer->Print(
    "$access_level$ static partial class $umbrella_class_name$ {\n"
    "\n",
    "access_level", class_access_level(),
    "umbrella_class_name", umbrellaClassname_);
  printer->Indent();
}

void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
  printer->Print(
    "#region Descriptor\n"
    "public static pbr::FileDescriptor Descriptor {\n"
    "  get { return descriptor; }\n"
    "}\n"
    "private static pbr::FileDescriptor descriptor;\n"
    "\n"
    "static $umbrella_class_name$() {\n",
    "umbrella_class_name", umbrellaClassname_);
  printer->Indent();
  printer->Print(
    "byte[] descriptorData = global::System.Convert.FromBase64String(\n");
  printer->Indent();
  printer->Indent();
  printer->Print("string.Concat(\n");
  printer->Indent();

  // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
  std::string base64 = FileDescriptorToBase64(file_);
  while (base64.size() > 60) {
    printer->Print("\"$base64$\",\n", "base64", base64.substr(0, 60));
    base64 = base64.substr(60);
  }
  printer->Print("\"$base64$\"));\n", "base64", base64);
  printer->Outdent();
  printer->Outdent();
  printer->Outdent();

  // -----------------------------------------------------------------
  // Invoke InternalBuildGeneratedFileFrom() to build the file.
  printer->Print(
      "descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n");
  printer->Print("    new pbr::FileDescriptor[] { ");
  for (int i = 0; i < file_->dependency_count(); i++) {
    // descriptor.proto is special: we don't allow access to the generated code, but there's
    // a separately-exposed property to get at the file descriptor, specifically to allow this
    // kind of dependency.
    if (IsDescriptorProto(file_->dependency(i))) {
      printer->Print("pbr::FileDescriptor.DescriptorProtoFileDescriptor, ");
    } else {
      printer->Print(
      "$full_umbrella_class_name$.Descriptor, ",
      "full_umbrella_class_name",
      GetUmbrellaClassName(file_->dependency(i)));
    }
  }
  printer->Print("},\n"
      "    new pbr::GeneratedCodeInfo(");
  // Specify all the generated code information, recursively.
  if (file_->enum_type_count() > 0) {
      printer->Print("new[] {");
      for (int i = 0; i < file_->enum_type_count(); i++) {
          printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i)));
      }
      printer->Print("}, ");
  }
  else {
      printer->Print("null, ");
  }
  if (file_->message_type_count() > 0) {
      printer->Print("new pbr::GeneratedCodeInfo[] {\n");
      printer->Indent();
      printer->Indent();
      printer->Indent();
      for (int i = 0; i < file_->message_type_count(); i++) {
          WriteGeneratedCodeInfo(file_->message_type(i), printer, i == file_->message_type_count() - 1);
      }
      printer->Outdent();
      printer->Print("\n}));\n");
      printer->Outdent();
      printer->Outdent();
  }
  else {
      printer->Print("null));\n");
  }

  printer->Outdent();
  printer->Print("}\n");
  printer->Print("#endregion\n\n");
}

// Write out the generated code for a particular message. This consists of the CLR type, property names
// corresponding to fields, names corresponding to oneofs, nested enums, and nested types. Each array part
// can be specified as null if it would be empty, to make the generated code somewhat simpler to read.
// We write a line break at the end of each generated code info, so that in the final file we'll see all
// the types, pre-ordered depth first, one per line. The indentation will be slightly unusual,
// in that it will look like a single array when it's actually constructing a tree, but it'll be easy to
// read even with multiple levels of nesting.
// The "last" parameter indicates whether this message descriptor is the last one being printed in this immediate
// context. It governs whether or not a trailing comma and newline is written after the constructor, effectively
// just controlling the formatting in the generated code.
void UmbrellaClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last) {
  if (IsMapEntryMessage(descriptor)) {
    printer->Print("null, ");
    return;
  }
  // Generated message type
  printer->Print("new pbr::GeneratedCodeInfo(typeof($type_name$), ", "type_name", GetClassName(descriptor));

  // Fields
  if (descriptor->field_count() > 0) {
      std::vector<std::string> fields;
      for (int i = 0; i < descriptor->field_count(); i++) {
          fields.push_back(GetPropertyName(descriptor->field(i)));
      }
      printer->Print("new[]{ \"$fields$\" }, ", "fields", JoinStrings(fields, "\", \""));
  }
  else {
      printer->Print("null, ");
  }

  // Oneofs
  if (descriptor->oneof_decl_count() > 0) {
      std::vector<std::string> oneofs;
      for (int i = 0; i < descriptor->oneof_decl_count(); i++) {
          oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true));
      }
      printer->Print("new[]{ \"$oneofs$\" }, ", "oneofs", JoinStrings(oneofs, "\", \""));
  }
  else {
      printer->Print("null, ");
  }

  // Nested enums
  if (descriptor->enum_type_count() > 0) {
      std::vector<std::string> enums;
      for (int i = 0; i < descriptor->enum_type_count(); i++) {
          enums.push_back(GetClassName(descriptor->enum_type(i)));
      }
      printer->Print("new[]{ typeof($enums$) }, ", "enums", JoinStrings(enums, "), typeof("));
  }
  else {
      printer->Print("null, ");
  }

  // Nested types
  if (descriptor->nested_type_count() > 0) {
      // Need to specify array type explicitly here, as all elements may be null.
      printer->Print("new pbr::GeneratedCodeInfo[] { ");
      for (int i = 0; i < descriptor->nested_type_count(); i++) {
          WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
      }
      printer->Print("}");
  }
  else {
      printer->Print("null");
  }
  printer->Print(last ? ")" : "),\n");
}

}  // namespace csharp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
<|endoftext|>