<commit_before>//
//
// Copyright (C) 2005 Jason Fischl, Dan Petrie
//
// Copyright (C) 2005 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2005 Pingtel Corp.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

// APPLICATION INCLUDES
#include <os/OsFS.h>
#include <os/OsSysLog.h>
#include <os/OsConfigDb.h>
#include <net/NameValueTokenizer.h>
#include "resip/stack/NameAddr.hxx"
#include "ConferenceUserAgent.h"

// DEFINES
#ifndef SIPX_VERSION
#  define SIPXCHANGE_VERSION          SipXpbxVersion
#  define SIPXCHANGE_VERSION_COMMENT  SipXpbxBuildStamp
#else
#  define SIPXCHANGE_VERSION          SIPX_VERSION
#  define SIPXCHANGE_VERSION_COMMENT  ""
#endif

#define CONFIG_SETTINGS_FILE          "bbridge.conf"
#define CONFIG_ETC_DIR                SIPX_CONFDIR

#define CONFIG_LOG_FILE               "bbridge.log"
#define CONFIG_LOG_DIR                SIPX_LOGDIR

#define LOG_FACILITY                  FAC_CONFERENCE

#define CONFIG_SETTING_LOG_DIR        "BOSTON_BRIDGE_LOG_DIR"
#define CONFIG_SETTING_LOG_LEVEL      "BOSTON_BRIDGE_LOG_LEVEL"
#define CONFIG_SETTING_LOG_CONSOLE    "BOSTON_BRIDGE_LOG_CONSOLE"
#define CONFIG_SETTING_UDP_PORT       "BOSTON_BRIDGE_UDP_PORT"
#define CONFIG_SETTING_TCP_PORT       "BOSTON_BRIDGE_TCP_PORT"
#define CONFIG_SETTING_RTP_START      "BOSTON_BRIDGE_RTP_START"
#define CONFIG_SETTING_RTP_END        "BOSTON_BRIDGE_RTP_END"

#define DEFAULT_UDP_PORT              5060       // Default UDP port
#define DEFAULT_TCP_PORT              5060       // Default TCP port
#define DEFAULT_TLS_PORT              5061       // Default TLS port
#define DEFAULT_RTP_START             15000
#define DEFAULT_RTP_END               20000

// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTSCONFIG_SETTING_RTP_START
// TYPEDEFS
typedef void (*sighandler_t)(int);

// FUNCTIONS
extern "C" {
    void  sigHandler( int sig_num );
    sighandler_t pt_signal( int sig_num, sighandler_t handler );
}

// FORWARD DECLARATIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
// GLOBAL VARIABLE INITIALIZATIONS
UtlBoolean    gShutdownFlag = FALSE;

/* ============================ FUNCTIONS ================================= */

/**
 * Description:
 * This is a replacement for signal() which registers a signal handler but sets
 * a flag causing system calls ( namely read() or getchar() ) not to bail out
 * upon recepit of that signal. We need this behavior, so we must call
 * sigaction() manually.
 */
sighandler_t pt_signal( int sig_num, sighandler_t handler)
{
#if defined(__pingtel_on_posix__)
    struct sigaction action[2];
    action[0].sa_handler = handler;
    sigemptyset(&action[0].sa_mask);
    action[0].sa_flags = 0;
    sigaction ( sig_num, &action[0], &action[1] );
    return action[1].sa_handler;
#else
    return signal( sig_num, handler );
#endif
}

/**
 * Description:
 * This is the signal handler, When called this sets the
 * global gShutdownFlag allowing the main processing
 * loop to exit cleanly.
 */
void sigHandler( int sig_num )
{
    // set a global shutdown flag
    gShutdownFlag = TRUE;

    // Unregister interest in the signal to prevent recursive callbacks
    pt_signal( sig_num, SIG_DFL );

    // Minimize the chance that we loose log data   configDb.loadFromFile(fileName);

    OsSysLog::flush();
    OsSysLog::add(LOG_FACILITY, PRI_CRIT, "sigHandler: caught signal: %d", sig_num);
    OsSysLog::flush();
}

// Initialize the OsSysLog
void initSysLog(OsConfigDb* pConfig)
{
   UtlString logLevel;               // Controls Log Verbosity
   UtlString consoleLogging;         // Enable console logging by default?
   UtlString fileTarget;             // Path to store log file.
   UtlBoolean bSpecifiedDirError ;   // Set if the specified log dir does not
                                    // exist
   struct tagPrioriotyLookupTable
   {
      const char*      pIdentity;
      OsSysLogPriority ePriority;
   };

   struct tagPrioriotyLookupTable lkupTable[] =
   {
      { "DEBUG",   PRI_DEBUG},
      { "INFO",    PRI_INFO},
      { "NOTICE",  PRI_NOTICE},
      { "WARNING", PRI_WARNING},
      { "ERR",     PRI_ERR},
      { "CRIT",    PRI_CRIT},
      { "ALERT",   PRI_ALERT},
      { "EMERG",   PRI_EMERG},
   };

   OsSysLog::initialize(0, "bbridge");

   //
   // Get/Apply Log Filename
   //
   fileTarget.remove(0);
   if ((pConfig->get(CONFIG_SETTING_LOG_DIR, fileTarget) != OS_SUCCESS) ||
      fileTarget.isNull() || !OsFileSystem::exists(fileTarget))
   {
      bSpecifiedDirError = !fileTarget.isNull();

      // If the log file directory exists use that, otherwise place the log
      // in the current directory
      OsPath workingDirectory;
      if (OsFileSystem::exists(CONFIG_LOG_DIR))
      {
         fileTarget = CONFIG_LOG_DIR;
         OsPath path(fileTarget);
         path.getNativePath(workingDirectory);

         osPrintf("%s : %s\n", CONFIG_SETTING_LOG_DIR, workingDirectory.data());
         OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s"DEFAULT_UDP_PORT, CONFIG_SETTING_LOG_DIR, workingDirectory.data());
      }
      else
      {
         OsPath path;
         OsFileSystem::getWorkingDirectory(path);
         path.getNativePath(workingDirectory);

         osPrintf("%s : %s\n", CONFIG_SETTING_LOG_DIR, workingDirectory.data());
         OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_DIR, workingDirectory.data());
      }

      fileTarget = workingDirectory +
         OsPathBase::separator +
         CONFIG_LOG_FILE;
   }
   else
   {
      bSpecifiedDirError = false;
      osPrintf("%s : %s\n", CONFIG_SETTING_LOG_DIR, fileTarget.data());
      OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_DIR, fileTarget.data());

      fileTarget = fileTarget +
         OsPathBase::separator +
         CONFIG_LOG_FILE;
   }
   OsSysLog::setOutputFile(0, fileTarget);

   //
   // Get/Apply Log Level
   //
   if ((pConfig->get(CONFIG_SETTING_LOG_LEVEL, logLevel) != OS_SUCCESS) ||
         logLevel.isNull())
   {
      logLevel = "ERR";
   }
   logLevel.toUpper();
   OsSysLogPriority priority = PRI_ERR;
   int iEntries = sizeof(lkupTable) / sizeof(struct tagPrioriotyLookupTable);
   for (int i = 0; i < iEntries; i++)
   {
      if (logLevel == lkupTable[i].pIdentity)
      {
         priority = lkupTable[i].ePriority;
         osPrintf("%s : %s\n", CONFIG_SETTING_LOG_LEVEL, lkupTable[i].pIdentity);
         OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_LEVEL, lkupTable[i].pIdentity);
         break;
      }
   }
   OsSysLog::setLoggingPriority(priority);

   //
   // Get/Apply console logging
   //
   UtlBoolean bConsoleLoggingEnabled = false;
   if ((pConfig->get(CONFIG_SETTING_LOG_CONSOLE, consoleLogging) == OS_SUCCESS))
   {
      consoleLogging.toUpper();
      if (consoleLogging == "ENABLE")
      {
         OsSysLog::enableConsoleOutput(true);
         bConsoleLoggingEnabled = true;5140
      }
   }

   osPrintf("%s : %s\n", CONFIG_SETTING_LOG_CONSOLE, bConsoleLoggingEnabled ? "ENABLE" : "DISABLE") ;
   OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_CONSOLE, bConsoleLoggingEnabled ? "ENABLE" : "DISABLE") ;

   if (bSpecifiedDirError)
   {
      OsSysLog::add(FAC_LOG, PRI_CRIT, "Cannot access %s directory; please check configuration.", CONFIG_SETTING_LOG_DIR);
   }
}

//
// The main entry point to the sipXpark
//
int main(int argc, char* argv[])
{
   // Configuration Database (used for OsSysLog)
   OsConfigDb configDb;

   // Register Signal handlers so we can perform graceful shutdown
   pt_signal(SIGINT,   sigHandler);    // Trap Ctrl-C on NT
   pt_signal(SIGILL,   sigHandler);
   pt_signal(SIGABRT,  sigHandler);    // Abort signal 6
   pt_signal(SIGFPE,   sigHandler);    // Floading Point Exception
   pt_signal(SIGSEGV,  sigHandler);    // Address access violations signal 11
   pt_signal(SIGTERM,  sigHandler);    // Trap kill -15 on UNIX
#if defined(__pingtel_on_posix__)
   pt_signal(SIGHUP,   sigHandler);    // Hangup
   pt_signal(SIGQUIT,  sigHandler);
   pt_signal(SIGPIPE,  sigHandler);    // Handle TCP Failure
   pt_signal(SIGBUS,   sigHandler);
   pt_signal(SIGSYS,   sigHandler);
   pt_signal(SIGXCPU,  sigHandler);
   pt_signal(SIGXFSZ,  sigHandler);
   pt_signal(SIGUSR1,  sigHandler);
   pt_signal(SIGUSR2,  sigHandler);
#endif

   UtlString argString;5140
   for(int argIndex = 1; argIndex < argc; argIndex++)
   {
      osPrintf("arg[%d]: %s\n", argIndex, argv[argIndex]);
      argString = argv[argIndex];
      NameValueTokenizer::frontBackTrim(&argString, "\t ");
      if(argString.compareTo("-v") == 0)
      {
         osPrintf("Version: %s (%s)\n", SIPXCHANGE_VERSION, SIPXCHANGE_VERSION_COMMENT);
         return(1);
      }
      else
      {
         osPrintf("usage: %s [-v]\nwhere:\n -v provides the software version\n",
         argv[0]);
         return(1);
      }
   }

   // Load configuration file file
   OsPath workingDirectory;
   if (OsFileSystem::exists(CONFIG_ETC_DIR))
   {
      workingDirectory = CONFIG_ETC_DIR;
      OsPath path(workingDirectory);
      path.getNativePath(workingDirectory);
   }
   else
   {
      OsPath path;
      OsFileSystem::getWorkingDirectory(path);
      path.getNativePath(workingDirectory);
   }

   UtlString fileName =  workingDirectory +
                         OsPathBase::separator +
                         CONFIG_SETTINGS_FILE;

   if (configDb.loadFromFile(fileName) != SUCCESS)
   {
      configDb.set(CONFIG_SETTING_LOG_DIR, "");
      configDb.set(CONFIG_SETTING_LOG_LEVEL, "INFO");
      configDb.set(CONFIG_SETTING_LOG_CONSOLE, "");
      configDb.set(CONFIG_SETTING_UDP_PORT, DEFAULT_UDP_PORT);
      configDb.set(CONFIG_SETTING_TCP_PORT, DEFAULT_TCP_PORT);
      configDb.set(CONFIG_SETTING_TLS_PORT, DEFAULT_TLS_PORT);
      configDb.set(CONFIG_SETTING_RTP_START, DEFAULT_RTP_START);
      configDb.set(CONFIG_SETTING_RTP_END, DEFAULT_RTP_END);
      configDb.storeToFile(filename);
   }

   // Initialize log file
   initSysLog(&configDb);

   // Read the user agent parameters from the config file.
   int UdpPort;
   if (configDb.get(CONFIG_SETTING_UDP_PORT, UdpPort) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_UDP_PORT, DEFAULT_UDP_PORT);;
   }

   int TcpPort;
   if (configDb.get(CONFIG_SETTING_TCP_PORT, TcpPort) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_TCP_PORT, DEFAULT_TCP_PORT);;
   }

   int TlsPort;
   if (configDb.get(CONFIG_SETTING_TLS_PORT, TlsPort) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_TLS_PORT, DEFAULT_TLS_PORT);;
   }

   int RtpStart;
   if (configDb.get(CONFIG_SETTING_RTP_START, RtpStart) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_RTP_START, DEFAULT_RTP_START);;
   }

   int RtpEnd;
   if (configDb.get(CONFIG_SETTING_RTP_END, RtpEnd) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_RTP_END, DEFAULT_RTP_END);;
   }

   NameAddr myAor;
   ConferenceUserAgent ua(configDb, myAor);

   while (!gShutdownFlag)
   {
      OsTask::delay(1000);
   }

   // Flush the log file
   OsSysLog::flush();

   // Say goodnight Gracie...
   return 0;
}

<commit_msg>resip namespace<commit_after>//
//
// Copyright (C) 2005 Jason Fischl, Dan Petrie
//
// Copyright (C) 2005 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2005 Pingtel Corp.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

// APPLICATION INCLUDES
#include <os/OsFS.h>
#include <os/OsSysLog.h>
#include <os/OsConfigDb.h>
#include <net/NameValueTokenizer.h>
#include "resip/stack/NameAddr.hxx"
#include "ConferenceUserAgent.h"

// DEFINES
#ifndef SIPX_VERSION
#  define SIPXCHANGE_VERSION          SipXpbxVersion
#  define SIPXCHANGE_VERSION_COMMENT  SipXpbxBuildStamp
#else
#  define SIPXCHANGE_VERSION          SIPX_VERSION
#  define SIPXCHANGE_VERSION_COMMENT  ""
#endif

#define CONFIG_SETTINGS_FILE          "bbridge.conf"
#define CONFIG_ETC_DIR                SIPX_CONFDIR

#define CONFIG_LOG_FILE               "bbridge.log"
#define CONFIG_LOG_DIR                SIPX_LOGDIR

#define LOG_FACILITY                  FAC_CONFERENCE

#define CONFIG_SETTING_LOG_DIR        "BOSTON_BRIDGE_LOG_DIR"
#define CONFIG_SETTING_LOG_LEVEL      "BOSTON_BRIDGE_LOG_LEVEL"
#define CONFIG_SETTING_LOG_CONSOLE    "BOSTON_BRIDGE_LOG_CONSOLE"
#define CONFIG_SETTING_UDP_PORT       "BOSTON_BRIDGE_UDP_PORT"
#define CONFIG_SETTING_TCP_PORT       "BOSTON_BRIDGE_TCP_PORT"
#define CONFIG_SETTING_RTP_START      "BOSTON_BRIDGE_RTP_START"
#define CONFIG_SETTING_RTP_END        "BOSTON_BRIDGE_RTP_END"

#define DEFAULT_UDP_PORT              5060       // Default UDP port
#define DEFAULT_TCP_PORT              5060       // Default TCP port
#define DEFAULT_TLS_PORT              5061       // Default TLS port
#define DEFAULT_RTP_START             15000
#define DEFAULT_RTP_END               20000

// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTSCONFIG_SETTING_RTP_START
// TYPEDEFS
typedef void (*sighandler_t)(int);

// FUNCTIONS
extern "C" {
    void  sigHandler( int sig_num );
    sighandler_t pt_signal( int sig_num, sighandler_t handler );
}

// FORWARD DECLARATIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
// GLOBAL VARIABLE INITIALIZATIONS
UtlBoolean    gShutdownFlag = FALSE;

/* ============================ FUNCTIONS ================================= */

/**
 * Description:
 * This is a replacement for signal() which registers a signal handler but sets
 * a flag causing system calls ( namely read() or getchar() ) not to bail out
 * upon recepit of that signal. We need this behavior, so we must call
 * sigaction() manually.
 */
sighandler_t pt_signal( int sig_num, sighandler_t handler)
{
#if defined(__pingtel_on_posix__)
    struct sigaction action[2];
    action[0].sa_handler = handler;
    sigemptyset(&action[0].sa_mask);
    action[0].sa_flags = 0;
    sigaction ( sig_num, &action[0], &action[1] );
    return action[1].sa_handler;
#else
    return signal( sig_num, handler );
#endif
}

/**
 * Description:
 * This is the signal handler, When called this sets the
 * global gShutdownFlag allowing the main processing
 * loop to exit cleanly.
 */
void sigHandler( int sig_num )
{
    // set a global shutdown flag
    gShutdownFlag = TRUE;

    // Unregister interest in the signal to prevent recursive callbacks
    pt_signal( sig_num, SIG_DFL );

    // Minimize the chance that we loose log data   configDb.loadFromFile(fileName);

    OsSysLog::flush();
    OsSysLog::add(LOG_FACILITY, PRI_CRIT, "sigHandler: caught signal: %d", sig_num);
    OsSysLog::flush();
}

// Initialize the OsSysLog
void initSysLog(OsConfigDb* pConfig)
{
   UtlString logLevel;               // Controls Log Verbosity
   UtlString consoleLogging;         // Enable console logging by default?
   UtlString fileTarget;             // Path to store log file.
   UtlBoolean bSpecifiedDirError ;   // Set if the specified log dir does not
                                    // exist
   struct tagPrioriotyLookupTable
   {
      const char*      pIdentity;
      OsSysLogPriority ePriority;
   };

   struct tagPrioriotyLookupTable lkupTable[] =
   {
      { "DEBUG",   PRI_DEBUG},
      { "INFO",    PRI_INFO},
      { "NOTICE",  PRI_NOTICE},
      { "WARNING", PRI_WARNING},
      { "ERR",     PRI_ERR},
      { "CRIT",    PRI_CRIT},
      { "ALERT",   PRI_ALERT},
      { "EMERG",   PRI_EMERG},
   };

   OsSysLog::initialize(0, "bbridge");

   //
   // Get/Apply Log Filename
   //
   fileTarget.remove(0);
   if ((pConfig->get(CONFIG_SETTING_LOG_DIR, fileTarget) != OS_SUCCESS) ||
      fileTarget.isNull() || !OsFileSystem::exists(fileTarget))
   {
      bSpecifiedDirError = !fileTarget.isNull();

      // If the log file directory exists use that, otherwise place the log
      // in the current directory
      OsPath workingDirectory;
      if (OsFileSystem::exists(CONFIG_LOG_DIR))
      {
         fileTarget = CONFIG_LOG_DIR;
         OsPath path(fileTarget);
         path.getNativePath(workingDirectory);

         osPrintf("%s : %s\n", CONFIG_SETTING_LOG_DIR, workingDirectory.data());
         OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s"DEFAULT_UDP_PORT, CONFIG_SETTING_LOG_DIR, workingDirectory.data());
      }
      else
      {
         OsPath path;
         OsFileSystem::getWorkingDirectory(path);
         path.getNativePath(workingDirectory);

         osPrintf("%s : %s\n", CONFIG_SETTING_LOG_DIR, workingDirectory.data());
         OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_DIR, workingDirectory.data());
      }

      fileTarget = workingDirectory +
         OsPathBase::separator +
         CONFIG_LOG_FILE;
   }
   else
   {
      bSpecifiedDirError = false;
      osPrintf("%s : %s\n", CONFIG_SETTING_LOG_DIR, fileTarget.data());
      OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_DIR, fileTarget.data());

      fileTarget = fileTarget +
         OsPathBase::separator +
         CONFIG_LOG_FILE;
   }
   OsSysLog::setOutputFile(0, fileTarget);

   //
   // Get/Apply Log Level
   //
   if ((pConfig->get(CONFIG_SETTING_LOG_LEVEL, logLevel) != OS_SUCCESS) ||
         logLevel.isNull())
   {
      logLevel = "ERR";
   }
   logLevel.toUpper();
   OsSysLogPriority priority = PRI_ERR;
   int iEntries = sizeof(lkupTable) / sizeof(struct tagPrioriotyLookupTable);
   for (int i = 0; i < iEntries; i++)
   {
      if (logLevel == lkupTable[i].pIdentity)
      {
         priority = lkupTable[i].ePriority;
         osPrintf("%s : %s\n", CONFIG_SETTING_LOG_LEVEL, lkupTable[i].pIdentity);
         OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_LEVEL, lkupTable[i].pIdentity);
         break;
      }
   }
   OsSysLog::setLoggingPriority(priority);

   //
   // Get/Apply console logging
   //
   UtlBoolean bConsoleLoggingEnabled = false;
   if ((pConfig->get(CONFIG_SETTING_LOG_CONSOLE, consoleLogging) == OS_SUCCESS))
   {
      consoleLogging.toUpper();
      if (consoleLogging == "ENABLE")
      {
         OsSysLog::enableConsoleOutput(true);
         bConsoleLoggingEnabled = true;5140
      }
   }

   osPrintf("%s : %s\n", CONFIG_SETTING_LOG_CONSOLE, bConsoleLoggingEnabled ? "ENABLE" : "DISABLE") ;
   OsSysLog::add(LOG_FACILITY, PRI_INFO, "%s : %s", CONFIG_SETTING_LOG_CONSOLE, bConsoleLoggingEnabled ? "ENABLE" : "DISABLE") ;

   if (bSpecifiedDirError)
   {
      OsSysLog::add(FAC_LOG, PRI_CRIT, "Cannot access %s directory; please check configuration.", CONFIG_SETTING_LOG_DIR);
   }
}

//
// The main entry point to the sipXpark
//
int main(int argc, char* argv[])
{
   // Configuration Database (used for OsSysLog)
   OsConfigDb configDb;

   // Register Signal handlers so we can perform graceful shutdown
   pt_signal(SIGINT,   sigHandler);    // Trap Ctrl-C on NT
   pt_signal(SIGILL,   sigHandler);
   pt_signal(SIGABRT,  sigHandler);    // Abort signal 6
   pt_signal(SIGFPE,   sigHandler);    // Floading Point Exception
   pt_signal(SIGSEGV,  sigHandler);    // Address access violations signal 11
   pt_signal(SIGTERM,  sigHandler);    // Trap kill -15 on UNIX
#if defined(__pingtel_on_posix__)
   pt_signal(SIGHUP,   sigHandler);    // Hangup
   pt_signal(SIGQUIT,  sigHandler);
   pt_signal(SIGPIPE,  sigHandler);    // Handle TCP Failure
   pt_signal(SIGBUS,   sigHandler);
   pt_signal(SIGSYS,   sigHandler);
   pt_signal(SIGXCPU,  sigHandler);
   pt_signal(SIGXFSZ,  sigHandler);
   pt_signal(SIGUSR1,  sigHandler);
   pt_signal(SIGUSR2,  sigHandler);
#endif

   UtlString argString;5140
   for(int argIndex = 1; argIndex < argc; argIndex++)
   {
      osPrintf("arg[%d]: %s\n", argIndex, argv[argIndex]);
      argString = argv[argIndex];
      NameValueTokenizer::frontBackTrim(&argString, "\t ");
      if(argString.compareTo("-v") == 0)
      {
         osPrintf("Version: %s (%s)\n", SIPXCHANGE_VERSION, SIPXCHANGE_VERSION_COMMENT);
         return(1);
      }
      else
      {
         osPrintf("usage: %s [-v]\nwhere:\n -v provides the software version\n",
         argv[0]);
         return(1);
      }
   }

   // Load configuration file file
   OsPath workingDirectory;
   if (OsFileSystem::exists(CONFIG_ETC_DIR))
   {
      workingDirectory = CONFIG_ETC_DIR;
      OsPath path(workingDirectory);
      path.getNativePath(workingDirectory);
   }
   else
   {
      OsPath path;
      OsFileSystem::getWorkingDirectory(path);
      path.getNativePath(workingDirectory);
   }

   UtlString fileName =  workingDirectory +
                         OsPathBase::separator +
                         CONFIG_SETTINGS_FILE;

   if (configDb.loadFromFile(fileName) != SUCCESS)
   {
      configDb.set(CONFIG_SETTING_LOG_DIR, "");
      configDb.set(CONFIG_SETTING_LOG_LEVEL, "INFO");
      configDb.set(CONFIG_SETTING_LOG_CONSOLE, "");
      configDb.set(CONFIG_SETTING_UDP_PORT, DEFAULT_UDP_PORT);
      configDb.set(CONFIG_SETTING_TCP_PORT, DEFAULT_TCP_PORT);
      configDb.set(CONFIG_SETTING_TLS_PORT, DEFAULT_TLS_PORT);
      configDb.set(CONFIG_SETTING_RTP_START, DEFAULT_RTP_START);
      configDb.set(CONFIG_SETTING_RTP_END, DEFAULT_RTP_END);
      configDb.storeToFile(filename);
   }

   // Initialize log file
   initSysLog(&configDb);

   // Read the user agent parameters from the config file.
   int UdpPort;
   if (configDb.get(CONFIG_SETTING_UDP_PORT, UdpPort) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_UDP_PORT, DEFAULT_UDP_PORT);;
   }

   int TcpPort;
   if (configDb.get(CONFIG_SETTING_TCP_PORT, TcpPort) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_TCP_PORT, DEFAULT_TCP_PORT);;
   }

   int TlsPort;
   if (configDb.get(CONFIG_SETTING_TLS_PORT, TlsPort) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_TLS_PORT, DEFAULT_TLS_PORT);;
   }

   int RtpStart;
   if (configDb.get(CONFIG_SETTING_RTP_START, RtpStart) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_RTP_START, DEFAULT_RTP_START);;
   }

   int RtpEnd;
   if (configDb.get(CONFIG_SETTING_RTP_END, RtpEnd) != OS_SUCCESS)
   {
      configDb.set(CONFIG_SETTING_RTP_END, DEFAULT_RTP_END);;
   }

   resip::NameAddr myAor;
   ConferenceUserAgent ua(configDb, myAor);

   while (!gShutdownFlag)
   {
      OsTask::delay(1000);
   }

   // Flush the log file
   OsSysLog::flush();

   // Say goodnight Gracie...
   return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

#define SMALL   SkIntToScalar(2)
#define REAL    SkFloatToScalar(1.5f)
#define BIG     SkIntToScalar(10)
#define REALBIG SkFloatToScalar(30.5f)

class BlurRectBench: public SkBenchmark {
    SkScalar    fRadius;
    SkString    fName;

public:
    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
        fRadius = rad;
    }

protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    SkScalar radius() const {
        return fRadius;
    }

    void setName(const SkString& name) {
        fName = name;
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        paint.setAntiAlias(true);

        SkScalar pad = fRadius*3/2 + SK_Scalar1;
        SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);

        int loop_count;

        if (fRadius > SkIntToScalar(50)) {
          loop_count = 10;
        } else if (fRadius > SkIntToScalar(5)) {
          loop_count = 1000;
        } else {
          loop_count = 10000;
        }

        preBenchSetup(r);

        for (int i = 0; i < SkBENCHLOOP(loop_count); i++) {
            makeBlurryRect(r);
        }
    }

    virtual void makeBlurryRect(const SkRect&) = 0;
    virtual void preBenchSetup(const SkRect&) {}
private:
    typedef SkBenchmark INHERITED;
};

class BlurRectDirectBench: public BlurRectBench {
 public:
    BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRound(rad));
        }

        setName(name);
    }
protected:
    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style,
                             SkBlurMask::kHigh_Quality);
    }
};

class BlurRectSeparableBench: public BlurRectBench {
    SkMask fSrcMask;
public:
    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;
        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_separable_%d", SkScalarRound(rad));
        }

        setName(name);
    }

protected:
    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
        r.roundOut(&fSrcMask.fBounds);
        fSrcMask.fFormat = SkMask::kA8_Format;
        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());

        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
    }

    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
                                  SkBlurMask::kNormal_Style,
                                  SkBlurMask::kHigh_Quality);
    }
};

DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
<commit_msg>speculative change to speedup blurrect bench for large radius, to see if the bots are timing out<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

#define SMALL   SkIntToScalar(2)
#define REAL    SkFloatToScalar(1.5f)
#define BIG     SkIntToScalar(10)
#define REALBIG SkFloatToScalar(30.5f)

class BlurRectBench: public SkBenchmark {
    SkScalar    fRadius;
    SkString    fName;

public:
    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
        fRadius = rad;
    }

protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    SkScalar radius() const {
        return fRadius;
    }

    void setName(const SkString& name) {
        fName = name;
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        paint.setAntiAlias(true);

        SkScalar pad = fRadius*3/2 + SK_Scalar1;
        SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);

        int loop_count;

        if (fRadius > SkIntToScalar(25)) {
          loop_count = 100;
        } else if (fRadius > SkIntToScalar(5)) {
          loop_count = 1000;
        } else {
          loop_count = 10000;
        }

        preBenchSetup(r);

        for (int i = 0; i < SkBENCHLOOP(loop_count); i++) {
            makeBlurryRect(r);
        }
    }

    virtual void makeBlurryRect(const SkRect&) = 0;
    virtual void preBenchSetup(const SkRect&) {}
private:
    typedef SkBenchmark INHERITED;
};

class BlurRectDirectBench: public BlurRectBench {
 public:
    BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRound(rad));
        }

        setName(name);
    }
protected:
    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style,
                             SkBlurMask::kHigh_Quality);
    }
};

class BlurRectSeparableBench: public BlurRectBench {
    SkMask fSrcMask;
public:
    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;
        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_separable_%d", SkScalarRound(rad));
        }

        setName(name);
    }

protected:
    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
        r.roundOut(&fSrcMask.fBounds);
        fSrcMask.fFormat = SkMask::kA8_Format;
        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());

        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
    }

    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
                                  SkBlurMask::kNormal_Style,
                                  SkBlurMask::kHigh_Quality);
    }
};

DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "IncrementalExecutor.h"
#include "IncrementalJIT.h"
#include "Threading.h"

#include "cling/Interpreter/Value.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/AST.h"
#include "cling/Utils/Output.h"
#include "cling/Utils/Platform.h"

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/CompilerInstance.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

namespace cling {

namespace {

static std::unique_ptr<TargetMachine>
CreateHostTargetMachine(const clang::CompilerInstance& CI) {
  const clang::TargetOptions& TargetOpts = CI.getTargetOpts();
  const clang::CodeGenOptions& CGOpt = CI.getCodeGenOpts();
  const std::string& Triple = TargetOpts.Triple;

  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
  if (!TheTarget) {
    cling::errs() << "cling::IncrementalExecutor: unable to find target:\n"
                  << Error;
    return std::unique_ptr<TargetMachine>();
  }

// We have to use large code model for PowerPC64 because TOC and text sections
// can be more than 2GB apart.
#if defined(__powerpc64__) || defined(__PPC64__)
  CodeModel::Model CMModel = CodeModel::Large;
#else
  CodeModel::Model CMModel = CodeModel::JITDefault;
#endif
  CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
  switch (CGOpt.OptimizationLevel) {
    case 0: OptLevel = CodeGenOpt::None; break;
    case 1: OptLevel = CodeGenOpt::Less; break;
    case 2: OptLevel = CodeGenOpt::Default; break;
    case 3: OptLevel = CodeGenOpt::Aggressive; break;
    default: OptLevel = CodeGenOpt::Default;
  }

  std::string MCPU;
  std::string FeaturesStr;

  return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(Triple,
                                        MCPU, FeaturesStr,
                                        llvm::TargetOptions(),
                                        Optional<Reloc::Model>(), CMModel,
                                        OptLevel));
}

} // anonymous namespace

IncrementalExecutor::IncrementalExecutor(clang::DiagnosticsEngine& diags,
                                         const clang::CompilerInstance& CI):
  m_Callbacks(nullptr), m_externalIncrementalExecutor(nullptr)
#if 0
  : m_Diags(diags)
#endif
{

  // MSVC doesn't support m_AtExitFuncsSpinLock=ATOMIC_FLAG_INIT; in the class definition
  std::atomic_flag_clear( &m_AtExitFuncsSpinLock );

  std::unique_ptr<TargetMachine> TM(CreateHostTargetMachine(CI));
  m_BackendPasses.reset(new BackendPasses(CI.getCodeGenOpts(),
                                          CI.getTargetOpts(),
                                          CI.getLangOpts(),
                                          *TM));
  m_JIT.reset(new IncrementalJIT(*this, std::move(TM)));
}

// Keep in source: ~unique_ptr<ClingJIT> needs ClingJIT
IncrementalExecutor::~IncrementalExecutor() {}

void IncrementalExecutor::shuttingDown() {
  // It is legal to register an atexit handler from within another atexit
  // handler and furthor-more the standard says they need to run in reverse
  // order, so this function must be recursion safe.
  AtExitFunctions Local;
  {
    cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
    // Check this case first, to avoid the swap all-together.
    if (m_AtExitFuncs.empty())
      return;
    Local.swap(m_AtExitFuncs);
  }
  for (auto&& Ordered : llvm::reverse(Local.ordered())) {
    for (auto&& AtExit : llvm::reverse(Ordered->second))
      AtExit();
    // The standard says that they need to run in reverse order, which means
    // anything added from 'AtExit()' must now be run!
    shuttingDown();
  }
}

void IncrementalExecutor::AddAtExitFunc(void (*func)(void*), void* arg,
                                       const std::shared_ptr<llvm::Module>& M) {
  // Register a CXAAtExit function
  cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
  m_AtExitFuncs[M].emplace_back(func, arg);
}

void unresolvedSymbol()
{
  // This might get called recursively, or a billion of times. Do not generate
  // useless output; unresolvedSymbol() is always handed out with an error
  // message - that's enough.
  //cling::errs() << "IncrementalExecutor: calling unresolved symbol, "
  //  "see previous error message!\n";

  // throw exception instead?
}

void* IncrementalExecutor::HandleMissingFunction(const std::string& mangled_name)
{
  // Not found in the map, add the symbol in the list of unresolved symbols
  if (m_unresolvedSymbols.insert(mangled_name).second) {
    //cling::errs() << "IncrementalExecutor: use of undefined symbol '"
    //             << mangled_name << "'!\n";
  }

  return utils::FunctionToVoidPtr(&unresolvedSymbol);
}

void* IncrementalExecutor::NotifyLazyFunctionCreators(const std::string& mangled_name)
{
  for (std::vector<LazyFunctionCreatorFunc_t>::iterator it
         = m_lazyFuncCreator.begin(), et = m_lazyFuncCreator.end();
       it != et; ++it) {
    void* ret = (void*)((LazyFunctionCreatorFunc_t)*it)(mangled_name);
    if (ret)
      return ret;
  }
  void *address = nullptr;
  if (m_externalIncrementalExecutor)
   address = m_externalIncrementalExecutor->getAddressOfGlobal(mangled_name);

  return (address ? address : HandleMissingFunction(mangled_name));
}

#if 0
// FIXME: employ to empty module dependencies *within* the *current* module.
static void
freeCallersOfUnresolvedSymbols(llvm::SmallVectorImpl<llvm::Function*>&
                               funcsToFree, llvm::ExecutionEngine* engine) {
  llvm::SmallPtrSet<llvm::Function*, 40> funcsToFreeUnique;
  for (size_t i = 0; i < funcsToFree.size(); ++i) {
    llvm::Function* func = funcsToFree[i];
    assert(func && "Cannot free NULL function");
    if (funcsToFreeUnique.insert(func).second) {
      for (llvm::Value::use_iterator IU = func->use_begin(),
             EU = func->use_end(); IU != EU; ++IU) {
        llvm::Instruction* instUser = llvm::dyn_cast<llvm::Instruction>(*IU);
        if (!instUser) continue;
        if (!instUser->getParent()) continue;
        if (llvm::Function* userFunc = instUser->getParent()->getParent())
          funcsToFree.push_back(userFunc);
      }
    }
  }
  for (llvm::SmallPtrSet<llvm::Function*, 40>::iterator
         I = funcsToFreeUnique.begin(), E = funcsToFreeUnique.end();
       I != E; ++I) {
    // This should force the JIT to recompile the function. But the stubs stay,
    // and the JIT reuses the stubs now pointing nowhere, i.e. without updating
    // the machine code address. Fix the JIT, or hope that MCJIT helps.
    //engine->freeMachineCodeForFunction(*I);
    engine->updateGlobalMapping(*I, 0);
  }
}
#endif

IncrementalExecutor::ExecutionResult
IncrementalExecutor::runStaticInitializersOnce(const Transaction& T) {
  auto m = T.getModule();
  assert(m.get() && "Module must not be null");

  // We don't care whether something was unresolved before.
  m_unresolvedSymbols.clear();

  // check if there is any unresolved symbol in the list
  if (diagnoseUnresolvedSymbols("static initializers"))
    return kExeUnresolvedSymbols;

  llvm::GlobalVariable* GV
     = m->getGlobalVariable("llvm.global_ctors", true);
  // Nothing to do is good, too.
  if (!GV) return kExeSuccess;

  // Close similarity to
  // m_engine->runStaticConstructorsDestructors(false) aka
  // llvm::ExecutionEngine::runStaticConstructorsDestructors()
  // is intentional; we do an extra pass to check whether the JIT
  // managed to collect all the symbols needed by the niitializers.
  // Should be an array of '{ i32, void ()* }' structs.  The first value is
  // the init priority, which we ignore.
  llvm::ConstantArray *InitList
    = llvm::dyn_cast<llvm::ConstantArray>(GV->getInitializer());

  // We need to delete it here just in case we have recursive inits, otherwise
  // it will call inits multiple times.
  GV->eraseFromParent();

  if (InitList == 0)
    return kExeSuccess;

  //SmallVector<Function*, 2> initFuncs;

  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
    llvm::ConstantStruct *CS
      = llvm::dyn_cast<llvm::ConstantStruct>(InitList->getOperand(i));
    if (CS == 0) continue;

    llvm::Constant *FP = CS->getOperand(1);
    if (FP->isNullValue())
      continue;  // Found a sentinal value, ignore.

    // Strip off constant expression casts.
    if (llvm::ConstantExpr *CE = llvm::dyn_cast<llvm::ConstantExpr>(FP))
      if (CE->isCast())
        FP = CE->getOperand(0);

    // Execute the ctor/dtor function!
    if (llvm::Function *F = llvm::dyn_cast<llvm::Function>(FP)) {
      const llvm::StringRef fName = F->getName();
      executeInit(fName);
/*
      initFuncs.push_back(F);
      if (fName.startswith("_GLOBAL__sub_I_")) {
        BasicBlock& BB = F->getEntryBlock();
        for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
          if (CallInst* call = dyn_cast<CallInst>(I))
            initFuncs.push_back(call->getCalledFunction());
      }
*/
    }
  }

/*
  for (SmallVector<Function*,2>::iterator I = initFuncs.begin(),
         E = initFuncs.end(); I != E; ++I) {
    // Cleanup also the dangling init functions. They are in the form:
    // define internal void @_GLOBAL__I_aN() section "..."{
    // entry:
    //   call void @__cxx_global_var_init(N-1)()
    //   call void @__cxx_global_var_initM()
    //   ret void
    // }
    //
    // define internal void @__cxx_global_var_init(N-1)() section "..." {
    // entry:
    //   call void @_ZN7MyClassC1Ev(%struct.MyClass* @n)
    //   ret void
    // }

    // Erase __cxx_global_var_init(N-1)() first.
    (*I)->removeDeadConstantUsers();
    (*I)->eraseFromParent();
  }
*/

  return kExeSuccess;
}

void IncrementalExecutor::runAndRemoveStaticDestructors(Transaction* T) {
  assert(T && "Must be set");
  // Collect all the dtors bound to this transaction.
  AtExitFunctions::mapped_type Local;
  {
    cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
    auto Itr = m_AtExitFuncs.find(T->getModule());
    if (Itr == m_AtExitFuncs.end()) return;
    m_AtExitFuncs.erase(Itr, &Local);
  } // end of spin lock lifetime block.

  // 'Unload' the cxa_atexit, atexit entities.
  for (auto&& AtExit : llvm::reverse(Local)) {
    AtExit();
    // Run anything that was just registered in 'AtExit()'
    runAndRemoveStaticDestructors(T);
  }
}

void
IncrementalExecutor::installLazyFunctionCreator(LazyFunctionCreatorFunc_t fp)
{
  m_lazyFuncCreator.push_back(fp);
}

bool
IncrementalExecutor::addSymbol(const char* Name,  void* Addr,
                               bool Jit) {
  return m_JIT->lookupSymbol(Name, Addr, Jit).second;
}

void* IncrementalExecutor::getAddressOfGlobal(llvm::StringRef symbolName,
                                              bool* fromJIT /*=0*/) {
  // Return a symbol's address, and whether it was jitted.
  void* address = m_JIT->lookupSymbol(symbolName).first;

  // It's not from the JIT if it's in a dylib.
  if (fromJIT)
    *fromJIT = !address;

  if (!address)
    return (void*)m_JIT->getSymbolAddress(symbolName, false /*no dlsym*/);

  return address;
}

void*
IncrementalExecutor::getPointerToGlobalFromJIT(const llvm::GlobalValue& GV) {
  // Get the function / variable pointer referenced by GV.

  // We don't care whether something was unresolved before.
  m_unresolvedSymbols.clear();

  void* addr = (void*)m_JIT->getSymbolAddress(GV.getName(),
                                              false /*no dlsym*/);

  if (diagnoseUnresolvedSymbols(GV.getName(), "symbol"))
    return 0;
  return addr;
}

bool IncrementalExecutor::diagnoseUnresolvedSymbols(llvm::StringRef trigger,
                                                    llvm::StringRef title) {
  if (m_unresolvedSymbols.empty())
    return false;

  llvm::SmallVector<llvm::Function*, 128> funcsToFree;
  for (const std::string& sym : m_unresolvedSymbols) {
#if 0
    // FIXME: This causes a lot of test failures, for some reason it causes
    // the call to HandleMissingFunction to be elided.
    unsigned diagID = m_Diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
                                              "%0 unresolved while jitting %1");
    (void)diagID;
    //m_Diags.Report(diagID) << sym << funcname; // TODO: demangle the names.
#endif

    cling::errs() << "IncrementalExecutor::executeFunction: symbol '" << sym
                  << "' unresolved while linking ";
    if (trigger.find(utils::Synthesize::UniquePrefix) != llvm::StringRef::npos)
      cling::errs() << "[cling interface function]";
    else {
      if (!title.empty())
        cling::errs() << title << " '";
      cling::errs() << trigger;
      if (!title.empty())
        cling::errs() << "'";
    }
    cling::errs() << "!\n";

    // Be helpful, demangle!
    std::string demangledName = platform::Demangle(sym);
    if (!demangledName.empty()) {
       cling::errs()
          << "You are probably missing the definition of "
          << demangledName << "\n"
          << "Maybe you need to load the corresponding shared library?\n";
    }

    //llvm::Function *ff = m_engine->FindFunctionNamed(i->c_str());
    // i could also reference a global variable, in which case ff == 0.
    //if (ff)
    //  funcsToFree.push_back(ff);
  }
  //freeCallersOfUnresolvedSymbols(funcsToFree, m_engine.get());
  m_unresolvedSymbols.clear();
  return true;
}

}// end namespace cling
<commit_msg>[cling] Fix thread local storage in the cling JIT<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "IncrementalExecutor.h"
#include "IncrementalJIT.h"
#include "Threading.h"

#include "cling/Interpreter/Value.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/AST.h"
#include "cling/Utils/Output.h"
#include "cling/Utils/Platform.h"

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/CompilerInstance.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

namespace cling {

namespace {

static std::unique_ptr<TargetMachine>
CreateHostTargetMachine(const clang::CompilerInstance& CI) {
  const clang::TargetOptions& TargetOpts = CI.getTargetOpts();
  const clang::CodeGenOptions& CGOpt = CI.getCodeGenOpts();
  const std::string& Triple = TargetOpts.Triple;

  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
  if (!TheTarget) {
    cling::errs() << "cling::IncrementalExecutor: unable to find target:\n"
                  << Error;
    return std::unique_ptr<TargetMachine>();
  }

// We have to use large code model for PowerPC64 because TOC and text sections
// can be more than 2GB apart.
#if defined(__powerpc64__) || defined(__PPC64__)
  CodeModel::Model CMModel = CodeModel::Large;
#else
  CodeModel::Model CMModel = CodeModel::JITDefault;
#endif
  CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
  switch (CGOpt.OptimizationLevel) {
    case 0: OptLevel = CodeGenOpt::None; break;
    case 1: OptLevel = CodeGenOpt::Less; break;
    case 2: OptLevel = CodeGenOpt::Default; break;
    case 3: OptLevel = CodeGenOpt::Aggressive; break;
    default: OptLevel = CodeGenOpt::Default;
  }

  std::string MCPU;
  std::string FeaturesStr;

  auto TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(Triple,
                                        MCPU, FeaturesStr,
                                        llvm::TargetOptions(),
                                        Optional<Reloc::Model>(), CMModel,
                                        OptLevel));
  TM->Options.EmulatedTLS = true;
  return TM;
}

} // anonymous namespace

IncrementalExecutor::IncrementalExecutor(clang::DiagnosticsEngine& diags,
                                         const clang::CompilerInstance& CI):
  m_Callbacks(nullptr), m_externalIncrementalExecutor(nullptr)
#if 0
  : m_Diags(diags)
#endif
{

  // MSVC doesn't support m_AtExitFuncsSpinLock=ATOMIC_FLAG_INIT; in the class definition
  std::atomic_flag_clear( &m_AtExitFuncsSpinLock );

  std::unique_ptr<TargetMachine> TM(CreateHostTargetMachine(CI));
  m_BackendPasses.reset(new BackendPasses(CI.getCodeGenOpts(),
                                          CI.getTargetOpts(),
                                          CI.getLangOpts(),
                                          *TM));
  m_JIT.reset(new IncrementalJIT(*this, std::move(TM)));
}

// Keep in source: ~unique_ptr<ClingJIT> needs ClingJIT
IncrementalExecutor::~IncrementalExecutor() {}

void IncrementalExecutor::shuttingDown() {
  // It is legal to register an atexit handler from within another atexit
  // handler and furthor-more the standard says they need to run in reverse
  // order, so this function must be recursion safe.
  AtExitFunctions Local;
  {
    cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
    // Check this case first, to avoid the swap all-together.
    if (m_AtExitFuncs.empty())
      return;
    Local.swap(m_AtExitFuncs);
  }
  for (auto&& Ordered : llvm::reverse(Local.ordered())) {
    for (auto&& AtExit : llvm::reverse(Ordered->second))
      AtExit();
    // The standard says that they need to run in reverse order, which means
    // anything added from 'AtExit()' must now be run!
    shuttingDown();
  }
}

void IncrementalExecutor::AddAtExitFunc(void (*func)(void*), void* arg,
                                       const std::shared_ptr<llvm::Module>& M) {
  // Register a CXAAtExit function
  cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
  m_AtExitFuncs[M].emplace_back(func, arg);
}

void unresolvedSymbol()
{
  // This might get called recursively, or a billion of times. Do not generate
  // useless output; unresolvedSymbol() is always handed out with an error
  // message - that's enough.
  //cling::errs() << "IncrementalExecutor: calling unresolved symbol, "
  //  "see previous error message!\n";

  // throw exception instead?
}

void* IncrementalExecutor::HandleMissingFunction(const std::string& mangled_name)
{
  // Not found in the map, add the symbol in the list of unresolved symbols
  if (m_unresolvedSymbols.insert(mangled_name).second) {
    //cling::errs() << "IncrementalExecutor: use of undefined symbol '"
    //             << mangled_name << "'!\n";
  }

  return utils::FunctionToVoidPtr(&unresolvedSymbol);
}

void* IncrementalExecutor::NotifyLazyFunctionCreators(const std::string& mangled_name)
{
  for (std::vector<LazyFunctionCreatorFunc_t>::iterator it
         = m_lazyFuncCreator.begin(), et = m_lazyFuncCreator.end();
       it != et; ++it) {
    void* ret = (void*)((LazyFunctionCreatorFunc_t)*it)(mangled_name);
    if (ret)
      return ret;
  }
  void *address = nullptr;
  if (m_externalIncrementalExecutor)
   address = m_externalIncrementalExecutor->getAddressOfGlobal(mangled_name);

  return (address ? address : HandleMissingFunction(mangled_name));
}

#if 0
// FIXME: employ to empty module dependencies *within* the *current* module.
static void
freeCallersOfUnresolvedSymbols(llvm::SmallVectorImpl<llvm::Function*>&
                               funcsToFree, llvm::ExecutionEngine* engine) {
  llvm::SmallPtrSet<llvm::Function*, 40> funcsToFreeUnique;
  for (size_t i = 0; i < funcsToFree.size(); ++i) {
    llvm::Function* func = funcsToFree[i];
    assert(func && "Cannot free NULL function");
    if (funcsToFreeUnique.insert(func).second) {
      for (llvm::Value::use_iterator IU = func->use_begin(),
             EU = func->use_end(); IU != EU; ++IU) {
        llvm::Instruction* instUser = llvm::dyn_cast<llvm::Instruction>(*IU);
        if (!instUser) continue;
        if (!instUser->getParent()) continue;
        if (llvm::Function* userFunc = instUser->getParent()->getParent())
          funcsToFree.push_back(userFunc);
      }
    }
  }
  for (llvm::SmallPtrSet<llvm::Function*, 40>::iterator
         I = funcsToFreeUnique.begin(), E = funcsToFreeUnique.end();
       I != E; ++I) {
    // This should force the JIT to recompile the function. But the stubs stay,
    // and the JIT reuses the stubs now pointing nowhere, i.e. without updating
    // the machine code address. Fix the JIT, or hope that MCJIT helps.
    //engine->freeMachineCodeForFunction(*I);
    engine->updateGlobalMapping(*I, 0);
  }
}
#endif

IncrementalExecutor::ExecutionResult
IncrementalExecutor::runStaticInitializersOnce(const Transaction& T) {
  auto m = T.getModule();
  assert(m.get() && "Module must not be null");

  // We don't care whether something was unresolved before.
  m_unresolvedSymbols.clear();

  // check if there is any unresolved symbol in the list
  if (diagnoseUnresolvedSymbols("static initializers"))
    return kExeUnresolvedSymbols;

  llvm::GlobalVariable* GV
     = m->getGlobalVariable("llvm.global_ctors", true);
  // Nothing to do is good, too.
  if (!GV) return kExeSuccess;

  // Close similarity to
  // m_engine->runStaticConstructorsDestructors(false) aka
  // llvm::ExecutionEngine::runStaticConstructorsDestructors()
  // is intentional; we do an extra pass to check whether the JIT
  // managed to collect all the symbols needed by the niitializers.
  // Should be an array of '{ i32, void ()* }' structs.  The first value is
  // the init priority, which we ignore.
  llvm::ConstantArray *InitList
    = llvm::dyn_cast<llvm::ConstantArray>(GV->getInitializer());

  // We need to delete it here just in case we have recursive inits, otherwise
  // it will call inits multiple times.
  GV->eraseFromParent();

  if (InitList == 0)
    return kExeSuccess;

  //SmallVector<Function*, 2> initFuncs;

  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
    llvm::ConstantStruct *CS
      = llvm::dyn_cast<llvm::ConstantStruct>(InitList->getOperand(i));
    if (CS == 0) continue;

    llvm::Constant *FP = CS->getOperand(1);
    if (FP->isNullValue())
      continue;  // Found a sentinal value, ignore.

    // Strip off constant expression casts.
    if (llvm::ConstantExpr *CE = llvm::dyn_cast<llvm::ConstantExpr>(FP))
      if (CE->isCast())
        FP = CE->getOperand(0);

    // Execute the ctor/dtor function!
    if (llvm::Function *F = llvm::dyn_cast<llvm::Function>(FP)) {
      const llvm::StringRef fName = F->getName();
      executeInit(fName);
/*
      initFuncs.push_back(F);
      if (fName.startswith("_GLOBAL__sub_I_")) {
        BasicBlock& BB = F->getEntryBlock();
        for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
          if (CallInst* call = dyn_cast<CallInst>(I))
            initFuncs.push_back(call->getCalledFunction());
      }
*/
    }
  }

/*
  for (SmallVector<Function*,2>::iterator I = initFuncs.begin(),
         E = initFuncs.end(); I != E; ++I) {
    // Cleanup also the dangling init functions. They are in the form:
    // define internal void @_GLOBAL__I_aN() section "..."{
    // entry:
    //   call void @__cxx_global_var_init(N-1)()
    //   call void @__cxx_global_var_initM()
    //   ret void
    // }
    //
    // define internal void @__cxx_global_var_init(N-1)() section "..." {
    // entry:
    //   call void @_ZN7MyClassC1Ev(%struct.MyClass* @n)
    //   ret void
    // }

    // Erase __cxx_global_var_init(N-1)() first.
    (*I)->removeDeadConstantUsers();
    (*I)->eraseFromParent();
  }
*/

  return kExeSuccess;
}

void IncrementalExecutor::runAndRemoveStaticDestructors(Transaction* T) {
  assert(T && "Must be set");
  // Collect all the dtors bound to this transaction.
  AtExitFunctions::mapped_type Local;
  {
    cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
    auto Itr = m_AtExitFuncs.find(T->getModule());
    if (Itr == m_AtExitFuncs.end()) return;
    m_AtExitFuncs.erase(Itr, &Local);
  } // end of spin lock lifetime block.

  // 'Unload' the cxa_atexit, atexit entities.
  for (auto&& AtExit : llvm::reverse(Local)) {
    AtExit();
    // Run anything that was just registered in 'AtExit()'
    runAndRemoveStaticDestructors(T);
  }
}

void
IncrementalExecutor::installLazyFunctionCreator(LazyFunctionCreatorFunc_t fp)
{
  m_lazyFuncCreator.push_back(fp);
}

bool
IncrementalExecutor::addSymbol(const char* Name,  void* Addr,
                               bool Jit) {
  return m_JIT->lookupSymbol(Name, Addr, Jit).second;
}

void* IncrementalExecutor::getAddressOfGlobal(llvm::StringRef symbolName,
                                              bool* fromJIT /*=0*/) {
  // Return a symbol's address, and whether it was jitted.
  void* address = m_JIT->lookupSymbol(symbolName).first;

  // It's not from the JIT if it's in a dylib.
  if (fromJIT)
    *fromJIT = !address;

  if (!address)
    return (void*)m_JIT->getSymbolAddress(symbolName, false /*no dlsym*/);

  return address;
}

void*
IncrementalExecutor::getPointerToGlobalFromJIT(const llvm::GlobalValue& GV) {
  // Get the function / variable pointer referenced by GV.

  // We don't care whether something was unresolved before.
  m_unresolvedSymbols.clear();

  void* addr = (void*)m_JIT->getSymbolAddress(GV.getName(),
                                              false /*no dlsym*/);

  if (diagnoseUnresolvedSymbols(GV.getName(), "symbol"))
    return 0;
  return addr;
}

bool IncrementalExecutor::diagnoseUnresolvedSymbols(llvm::StringRef trigger,
                                                    llvm::StringRef title) {
  if (m_unresolvedSymbols.empty())
    return false;

  llvm::SmallVector<llvm::Function*, 128> funcsToFree;
  for (const std::string& sym : m_unresolvedSymbols) {
#if 0
    // FIXME: This causes a lot of test failures, for some reason it causes
    // the call to HandleMissingFunction to be elided.
    unsigned diagID = m_Diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
                                              "%0 unresolved while jitting %1");
    (void)diagID;
    //m_Diags.Report(diagID) << sym << funcname; // TODO: demangle the names.
#endif

    cling::errs() << "IncrementalExecutor::executeFunction: symbol '" << sym
                  << "' unresolved while linking ";
    if (trigger.find(utils::Synthesize::UniquePrefix) != llvm::StringRef::npos)
      cling::errs() << "[cling interface function]";
    else {
      if (!title.empty())
        cling::errs() << title << " '";
      cling::errs() << trigger;
      if (!title.empty())
        cling::errs() << "'";
    }
    cling::errs() << "!\n";

    // Be helpful, demangle!
    std::string demangledName = platform::Demangle(sym);
    if (!demangledName.empty()) {
       cling::errs()
          << "You are probably missing the definition of "
          << demangledName << "\n"
          << "Maybe you need to load the corresponding shared library?\n";
    }

    //llvm::Function *ff = m_engine->FindFunctionNamed(i->c_str());
    // i could also reference a global variable, in which case ff == 0.
    //if (ff)
    //  funcsToFree.push_back(ff);
  }
  //freeCallersOfUnresolvedSymbols(funcsToFree, m_engine.get());
  m_unresolvedSymbols.clear();
  return true;
}

}// end namespace cling
<|endoftext|>


<commit_before>#include <FAST/Visualization/DualViewWindow.hpp>
#include <FAST/Visualization/HeatmapRenderer/HeatmapRenderer.hpp>
#include <FAST/Algorithms/ImageResampler/ImageResampler.hpp>
#include "FAST/Testing.hpp"
#include "FAST/Streamers/ImageFileStreamer.hpp"
#include "FAST/Visualization/SimpleWindow.hpp"
#include "FAST/Visualization/ImageRenderer/ImageRenderer.hpp"
#include "FAST/Visualization/MeshRenderer/MeshRenderer.hpp"
#include "FAST/Algorithms/NeuralNetwork/PixelClassifier.hpp"

using namespace fast;

int main() {
    Reporter::setGlobalReportMethod(Reporter::COUT);
    ImageFileStreamer::pointer streamer = ImageFileStreamer::New();
    streamer->setFilenameFormats({
         "/home/smistad/data/eyeguide/axillary_nerve_block/17/2017Feb13_150433/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/17/2017Feb13_150648/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/17/2017Feb13_150824/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/5/2016Dec30_082009/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/5/2016Dec30_082046/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/5/2016Dec30_082110/#.png",
    });
    streamer->enableLooping();
    streamer->setStartNumber(1);
    streamer->setSleepTime(50);
    streamer->setStreamingMode(STREAMING_MODE_PROCESS_ALL_FRAMES);

    PixelClassifier::pointer segmentation = PixelClassifier::New();
    segmentation->setNrOfClasses(6);
    segmentation->load("/home/smistad/workspace/eyeguide_keras/models/network_graph.pb");
    segmentation->setInputSize(256, 256);
    segmentation->setScaleFactor(1.0f/255.0f);
    segmentation->setOutputParameters({"Reshape_18"});
    segmentation->setInputConnection(streamer->getOutputPort());
    segmentation->setHeatmapOutput();
    segmentation->enableRuntimeMeasurements();

    HeatmapRenderer::pointer renderer = HeatmapRenderer::New();
    renderer->addInputConnection(segmentation->getOutputPort(1), Color::Red());
    renderer->addInputConnection(segmentation->getOutputPort(2), Color::Yellow());
    renderer->addInputConnection(segmentation->getOutputPort(3), Color::Green());
    renderer->addInputConnection(segmentation->getOutputPort(4), Color::Purple());
    renderer->addInputConnection(segmentation->getOutputPort(5), Color::Cyan());
    renderer->setMaxOpacity(0.2);
    renderer->setMinConfidence(0.25);
    renderer->enableRuntimeMeasurements();

    ImageRenderer::pointer renderer2 = ImageRenderer::New();
    renderer2->setInputConnection(streamer->getOutputPort());

    SimpleWindow::pointer window = SimpleWindow::New();

    window->addRenderer(renderer2);
    window->addRenderer(renderer);
    window->getView()->enableRuntimeMeasurements();
    window->setSize(1920, 1080);
    //window->enableFullscreen();
    window->getView()->set2DPixelSpacing(0.3);
    window->set2DMode();
    window->getView()->setBackgroundColor(Color::Black());
    window->start();

    segmentation->getAllRuntimes()->printAll();
    renderer->getAllRuntimes()->printAll();
    window->getView()->getAllRuntimes()->printAll();
}
<commit_msg>Small changes in ax heatmap<commit_after>#include <FAST/Visualization/DualViewWindow.hpp>
#include <FAST/Visualization/HeatmapRenderer/HeatmapRenderer.hpp>
#include <FAST/Algorithms/ImageResampler/ImageResampler.hpp>
#include "FAST/Testing.hpp"
#include "FAST/Streamers/ImageFileStreamer.hpp"
#include "FAST/Visualization/SimpleWindow.hpp"
#include "FAST/Visualization/ImageRenderer/ImageRenderer.hpp"
#include "FAST/Visualization/MeshRenderer/MeshRenderer.hpp"
#include "FAST/Algorithms/NeuralNetwork/PixelClassifier.hpp"

using namespace fast;

int main() {
    Reporter::setGlobalReportMethod(Reporter::COUT);
    ImageFileStreamer::pointer streamer = ImageFileStreamer::New();
    streamer->setFilenameFormats({
         //"/home/smistad/data/eyeguide/axillary_nerve_block/1/2016-10-07-135630/US-2D_#.mhd",
         "/home/smistad/data/eyeguide/axillary_nerve_block/16/2017Feb13_114646/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/17/2017Feb13_150433/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/17/2017Feb13_150648/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/17/2017Feb13_150824/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/5/2016Dec30_082009/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/5/2016Dec30_082046/#.png",
         "/home/smistad/data/eyeguide/axillary_nerve_block/5/2016Dec30_082110/#.png",
    });
    streamer->enableLooping();
    streamer->setStartNumber(1);
    streamer->setSleepTime(25);
    streamer->setStreamingMode(STREAMING_MODE_PROCESS_ALL_FRAMES);

    PixelClassifier::pointer segmentation = PixelClassifier::New();
    segmentation->setNrOfClasses(6);
    segmentation->load("/home/smistad/workspace/eyeguide_keras/models/network_graph.pb");
    segmentation->setInputSize(256, 256);
    segmentation->setScaleFactor(1.0f/255.0f);
    segmentation->setOutputParameters({"Reshape_18"});
    segmentation->setInputConnection(streamer->getOutputPort());
    segmentation->setHeatmapOutput();
    segmentation->enableRuntimeMeasurements();

    HeatmapRenderer::pointer renderer = HeatmapRenderer::New();
    renderer->addInputConnection(segmentation->getOutputPort(1), Color::Red());
    renderer->addInputConnection(segmentation->getOutputPort(2), Color::Yellow());
    renderer->addInputConnection(segmentation->getOutputPort(3), Color::Green());
    renderer->addInputConnection(segmentation->getOutputPort(4), Color::Purple());
    renderer->addInputConnection(segmentation->getOutputPort(5), Color::Cyan());
    renderer->setMaxOpacity(0.2);
    renderer->setMinConfidence(0.4);
    renderer->enableRuntimeMeasurements();

    ImageRenderer::pointer renderer2 = ImageRenderer::New();
    renderer2->setInputConnection(streamer->getOutputPort());

    SimpleWindow::pointer window = SimpleWindow::New();

    window->addRenderer(renderer2);
    window->addRenderer(renderer);
    window->getView()->enableRuntimeMeasurements();
    window->setSize(1920, 1080);
    //window->enableFullscreen();
    window->getView()->set2DPixelSpacing(0.3);
    window->set2DMode();
    window->getView()->setBackgroundColor(Color::Black());
    window->start();

    segmentation->getAllRuntimes()->printAll();
    renderer->getAllRuntimes()->printAll();
    window->getView()->getAllRuntimes()->printAll();
}
<|endoftext|>


<commit_before>/**
 *
 * Copyright (c) 2009-2011, Kitty Barnett
 *
 * The source code in this file is provided to you under the terms of the
 * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
 * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
 *
 * By copying, modifying or distributing this software, you acknowledge that
 * you have read and understood your obligations described above, and agree to
 * abide by those obligations.
 *
 */

#include "llviewerprecompiledheaders.h"
#include "llavatarnamecache.h"
#include "llscrolllistctrl.h"
#include "llviewerjointattachment.h"
#include "llviewerobjectlist.h"
#include "llvoavatarself.h"

#include "rlvfloaters.h"
#include "rlvhelper.h"
#include "rlvhandler.h"
#include "rlvlocks.h"

// ============================================================================
// Helper functions
//

// Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0g
std::string rlvGetItemNameFromObjID(const LLUUID& idObj, bool fIncludeAttachPt = true)
{
	const LLViewerObject* pObj = gObjectList.findObject(idObj);
	const LLViewerObject* pObjRoot = (pObj) ? pObj->getRootEdit() : NULL;
	const LLViewerInventoryItem* pItem = ((pObjRoot) && (pObjRoot->isAttachment())) ? gInventory.getItem(pObjRoot->getAttachmentItemID()) : NULL;

	std::string strItemName = (pItem) ? pItem->getName() : idObj.asString();
	if ( (!fIncludeAttachPt) || (!pObj) || (!pObj->isAttachment()) || (!isAgentAvatarValid()) )
		return strItemName;

	const LLViewerJointAttachment* pAttachPt =
		get_if_there(gAgentAvatarp->mAttachmentPoints, RlvAttachPtLookup::getAttachPointIndex(pObjRoot), (LLViewerJointAttachment*)NULL);
	std::string strAttachPtName = (pAttachPt) ? pAttachPt->getName() : std::string("Unknown");
	return llformat("%s (%s, %s)", strItemName.c_str(), strAttachPtName.c_str(), (pObj == pObjRoot) ? "root" : "child");
}

// Checked: 2011-05-23 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
bool rlvGetShowException(ERlvBehaviour eBhvr)
{
	switch (eBhvr)
	{
		case RLV_BHVR_RECVCHAT:
		case RLV_BHVR_RECVEMOTE:
		case RLV_BHVR_SENDIM:
		case RLV_BHVR_RECVIM:
		case RLV_BHVR_STARTIM:
		case RLV_BHVR_TPLURE:
		case RLV_BHVR_ACCEPTTP:
			return true;
		default:
			return false;
	}
}

// ============================================================================
// RlvFloaterBehaviours member functions
//

// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onOpen(const LLSD& sdKey)
{
	m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterBehaviours::onCommand, this, _1, _2));

	refreshAll();
}

// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onClose(bool fQuitting)
{
	m_ConnRlvCommand.disconnect();
}

// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName)
{
	uuid_vec_t::iterator itLookup = std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idAgent);
	if (itLookup != m_PendingLookup.end())
		m_PendingLookup.erase(itLookup);
	if (getVisible())
		refreshAll();
}

// Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c
void RlvFloaterBehaviours::onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
{
	if ( (RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType()) )
		refreshAll();
}

// Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c
void RlvFloaterBehaviours::refreshAll()
{
	LLCtrlListInterface* pBhvrList = childGetListInterface("behaviour_list");
	LLCtrlListInterface* pExceptList = childGetListInterface("exception_list");
	if ( (!pBhvrList) || (!pExceptList) )
		return;
	pBhvrList->operateOnAll(LLCtrlListInterface::OP_DELETE);
	pExceptList->operateOnAll(LLCtrlListInterface::OP_DELETE);

	if (!isAgentAvatarValid())
		return;

	//
	// Set-up a row we can just reuse
	//
	LLSD sdBhrRow; LLSD& sdBhvrColumns = sdBhrRow["columns"];
	sdBhvrColumns[0] = LLSD().with("column", "behaviour").with("type", "text");
	sdBhvrColumns[1] = LLSD().with("column", "issuer").with("type", "text");

	LLSD sdExceptRow; LLSD& sdExceptColumns = sdExceptRow["columns"];
	sdExceptColumns[0] = LLSD().with("column", "behaviour").with("type", "text");
	sdExceptColumns[1] = LLSD().with("column", "option").with("type", "text");
	sdExceptColumns[2] = LLSD().with("column", "issuer").with("type", "text");

	//
	// List behaviours
	//
	const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap();
	for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj)
	{
		const std::string strIssuer = rlvGetItemNameFromObjID(itObj->first);

		const rlv_command_list_t* pCommands = itObj->second.getCommandList();
		for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd)
		{
			LLUUID idOption;
			if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (rlvGetShowException(itCmd->getBehaviourType())) )
			{
				std::string strOption; LLAvatarName avName;
				if (LLAvatarNameCache::get(idOption, &avName))
				{
					strOption = (!avName.mUsername.empty()) ? avName.mUsername : avName.mDisplayName;
				}
				else if (!gCacheName->getGroupName(idOption, strOption))
				{
					if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idOption))
					{
						LLAvatarNameCache::get(idOption, boost::bind(&RlvFloaterBehaviours::onAvatarNameLookup, this, _1, _2));
						m_PendingLookup.push_back(idOption);
					}
					strOption = itCmd->getOption();
				}

				// List under the "Exception" tab
				sdExceptColumns[0]["value"] = itCmd->getBehaviour();
				sdExceptColumns[1]["value"] = strOption;
				sdExceptColumns[2]["value"] = strIssuer;
				pExceptList->addElement(sdExceptRow, ADD_BOTTOM);
			}
			else
			{
				// List under the "Restrictions" tab
				sdBhvrColumns[0]["value"] = itCmd->asString();
				sdBhvrColumns[1]["value"] = strIssuer;
				pBhvrList->addElement(sdBhrRow, ADD_BOTTOM);
			}
		}
	}
}

// ============================================================================
// RlvFloaterLocks member functions
//

// Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::onOpen(const LLSD& sdKey)
{
	m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterLocks::onRlvCommand, this, _1, _2));

	refreshAll();
}

// Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::onClose(bool fQuitting)
{
	m_ConnRlvCommand.disconnect();
}

// Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::onRlvCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
{
	// Refresh on any successful @XXX=y|n command where XXX is any of the attachment or wearable locking behaviours
	if ( (RLV_RET_SUCCESS == eRet) && ((RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType())) )
	{
		switch (rlvCmd.getBehaviourType())
		{
			case RLV_BHVR_DETACH:
			case RLV_BHVR_ADDATTACH:
			case RLV_BHVR_REMATTACH:
			case RLV_BHVR_ADDOUTFIT:
			case RLV_BHVR_REMOUTFIT:
				refreshAll();
				break;
			default:
				break;
		}
	}
}

// Checked: 2010-03-18 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::refreshAll()
{
	LLCtrlListInterface* pLockList = childGetListInterface("lock_list");
	if (!pLockList)
		return;
	pLockList->operateOnAll(LLCtrlListInterface::OP_DELETE);

	if (!isAgentAvatarValid())
		return;

	//
	// Set-up a row we can just reuse
	//
	LLSD sdRow;
	LLSD& sdColumns = sdRow["columns"];
	sdColumns[0]["column"] = "lock_type";   sdColumns[0]["type"] = "text";
	sdColumns[1]["column"] = "lock_addrem"; sdColumns[1]["type"] = "text";
	sdColumns[2]["column"] = "lock_target"; sdColumns[2]["type"] = "text";
	sdColumns[3]["column"] = "lock_origin"; sdColumns[3]["type"] = "text";

	//
	// List attachment locks
	//
	sdColumns[0]["value"] = "Attachment";
	sdColumns[1]["value"] = "rem";

	const RlvAttachmentLocks::rlv_attachobjlock_map_t& attachObjRem = gRlvAttachmentLocks.getAttachObjLocks();
	for (RlvAttachmentLocks::rlv_attachobjlock_map_t::const_iterator itAttachObj = attachObjRem.begin();
			itAttachObj != attachObjRem.end(); ++itAttachObj)
	{
		sdColumns[2]["value"] = rlvGetItemNameFromObjID(itAttachObj->first);
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachObj->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	//
	// List attachment point locks
	//
	sdColumns[0]["value"] = "Attachment Point";

	sdColumns[1]["value"] = "add";
	const RlvAttachmentLocks::rlv_attachptlock_map_t& attachPtAdd = gRlvAttachmentLocks.getAttachPtLocks(RLV_LOCK_ADD);
	for (RlvAttachmentLocks::rlv_attachptlock_map_t::const_iterator itAttachPt = attachPtAdd.begin();
			itAttachPt != attachPtAdd.end(); ++itAttachPt)
	{
		const LLViewerJointAttachment* pAttachPt =
			get_if_there(gAgentAvatarp->mAttachmentPoints, itAttachPt->first, (LLViewerJointAttachment*)NULL);
		sdColumns[2]["value"] = pAttachPt->getName();
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachPt->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	sdColumns[1]["value"] = "rem";
	const RlvAttachmentLocks::rlv_attachptlock_map_t& attachPtRem = gRlvAttachmentLocks.getAttachPtLocks(RLV_LOCK_REMOVE);
	for (RlvAttachmentLocks::rlv_attachptlock_map_t::const_iterator itAttachPt = attachPtRem.begin();
			itAttachPt != attachPtRem.end(); ++itAttachPt)
	{
		const LLViewerJointAttachment* pAttachPt =
			get_if_there(gAgentAvatarp->mAttachmentPoints, itAttachPt->first, (LLViewerJointAttachment*)NULL);
		sdColumns[2]["value"] = pAttachPt->getName();
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachPt->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	//
	// List wearable type locks
	//
	sdColumns[0]["value"] = "Wearable Type";

	sdColumns[1]["value"] = "add";
	const RlvWearableLocks::rlv_wearabletypelock_map_t& wearableTypeAdd = gRlvWearableLocks.getWearableTypeLocks(RLV_LOCK_ADD);
	for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeAdd.begin();
			itWearableType != wearableTypeAdd.end(); ++itWearableType)
	{
		sdColumns[2]["value"] = LLWearableType::getTypeLabel(itWearableType->first);
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	sdColumns[1]["value"] = "rem";
	const RlvWearableLocks::rlv_wearabletypelock_map_t& wearableTypeRem = gRlvWearableLocks.getWearableTypeLocks(RLV_LOCK_REMOVE);
	for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeRem.begin();
			itWearableType != wearableTypeRem.end(); ++itWearableType)
	{
		sdColumns[2]["value"] = LLWearableType::getTypeName(itWearableType->first);
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}
}

// ============================================================================
<commit_msg>- changed : split the "restrictions floater" into one tan for restrictions and one tab for exceptions<commit_after>/**
 *
 * Copyright (c) 2009-2011, Kitty Barnett
 *
 * The source code in this file is provided to you under the terms of the
 * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
 * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
 *
 * By copying, modifying or distributing this software, you acknowledge that
 * you have read and understood your obligations described above, and agree to
 * abide by those obligations.
 *
 */

#include "llviewerprecompiledheaders.h"
#include "llavatarnamecache.h"
#include "llscrolllistctrl.h"
#include "llviewerjointattachment.h"
#include "llviewerobjectlist.h"
#include "llvoavatarself.h"

#include "rlvfloaters.h"
#include "rlvhelper.h"
#include "rlvhandler.h"
#include "rlvlocks.h"

// ============================================================================
// Helper functions
//

// Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0g
std::string rlvGetItemNameFromObjID(const LLUUID& idObj, bool fIncludeAttachPt = true)
{
	const LLViewerObject* pObj = gObjectList.findObject(idObj);
	const LLViewerObject* pObjRoot = (pObj) ? pObj->getRootEdit() : NULL;
	const LLViewerInventoryItem* pItem = ((pObjRoot) && (pObjRoot->isAttachment())) ? gInventory.getItem(pObjRoot->getAttachmentItemID()) : NULL;

	std::string strItemName = (pItem) ? pItem->getName() : idObj.asString();
	if ( (!fIncludeAttachPt) || (!pObj) || (!pObj->isAttachment()) || (!isAgentAvatarValid()) )
		return strItemName;

	const LLViewerJointAttachment* pAttachPt =
		get_if_there(gAgentAvatarp->mAttachmentPoints, RlvAttachPtLookup::getAttachPointIndex(pObjRoot), (LLViewerJointAttachment*)NULL);
	std::string strAttachPtName = (pAttachPt) ? pAttachPt->getName() : std::string("Unknown");
	return llformat("%s (%s, %s)", strItemName.c_str(), strAttachPtName.c_str(), (pObj == pObjRoot) ? "root" : "child");
}

// Checked: 2011-05-23 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
bool rlvGetShowException(ERlvBehaviour eBhvr)
{
	switch (eBhvr)
	{
		case RLV_BHVR_RECVCHAT:
		case RLV_BHVR_RECVEMOTE:
		case RLV_BHVR_SENDIM:
		case RLV_BHVR_RECVIM:
		case RLV_BHVR_STARTIM:
		case RLV_BHVR_TPLURE:
		case RLV_BHVR_ACCEPTTP:
			return true;
		default:
			return false;
	}
}

// ============================================================================
// RlvFloaterBehaviours member functions
//

// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onOpen(const LLSD& sdKey)
{
	m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterBehaviours::onCommand, this, _1, _2));

	refreshAll();
}

// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onClose(bool fQuitting)
{
	m_ConnRlvCommand.disconnect();
}

// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName)
{
	uuid_vec_t::iterator itLookup = std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idAgent);
	if (itLookup != m_PendingLookup.end())
		m_PendingLookup.erase(itLookup);
	if (getVisible())
		refreshAll();
}

// Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c
void RlvFloaterBehaviours::onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
{
	if ( (RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType()) )
		refreshAll();
}

// Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c
void RlvFloaterBehaviours::refreshAll()
{
	LLCtrlListInterface* pBhvrList = childGetListInterface("behaviour_list");
	LLCtrlListInterface* pExceptList = childGetListInterface("exception_list");
	if ( (!pBhvrList) || (!pExceptList) )
		return;
	pBhvrList->operateOnAll(LLCtrlListInterface::OP_DELETE);
	pExceptList->operateOnAll(LLCtrlListInterface::OP_DELETE);

	if (!isAgentAvatarValid())
		return;

	//
	// Set-up a row we can just reuse
	//
	LLSD sdBhrRow; LLSD& sdBhvrColumns = sdBhrRow["columns"];
	sdBhvrColumns[0] = LLSD().with("column", "behaviour").with("type", "text");
	sdBhvrColumns[1] = LLSD().with("column", "issuer").with("type", "text");

	LLSD sdExceptRow; LLSD& sdExceptColumns = sdExceptRow["columns"];
	sdExceptColumns[0] = LLSD().with("column", "behaviour").with("type", "text");
	sdExceptColumns[1] = LLSD().with("column", "option").with("type", "text");
	sdExceptColumns[2] = LLSD().with("column", "issuer").with("type", "text");

	//
	// List behaviours
	//
	const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap();
	for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj)
	{
		const std::string strIssuer = rlvGetItemNameFromObjID(itObj->first);

		const rlv_command_list_t* pCommands = itObj->second.getCommandList();
		for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd)
		{
			std::string strOption; LLUUID idOption;
			if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) )
			{
				LLAvatarName avName;
				if (gObjectList.findObject(idOption))
				{
					strOption = rlvGetItemNameFromObjID(idOption, false);
				}
				else if (LLAvatarNameCache::get(idOption, &avName))
				{
					strOption = (!avName.mUsername.empty()) ? avName.mUsername : avName.mDisplayName;
				}
				else if (!gCacheName->getGroupName(idOption, strOption))
				{
					if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idOption))
					{
						LLAvatarNameCache::get(idOption, boost::bind(&RlvFloaterBehaviours::onAvatarNameLookup, this, _1, _2));
						m_PendingLookup.push_back(idOption);
					}
					strOption = itCmd->getOption();
				}
			}

			if ( (itCmd->hasOption()) && (rlvGetShowException(itCmd->getBehaviourType())) )
			{
				// List under the "Exception" tab
				sdExceptColumns[0]["value"] = itCmd->getBehaviour();
				sdExceptColumns[1]["value"] = strOption;
				sdExceptColumns[2]["value"] = strIssuer;
				pExceptList->addElement(sdExceptRow, ADD_BOTTOM);
			}
			else
			{
				// List under the "Restrictions" tab
				sdBhvrColumns[0]["value"] = itCmd->asString();
				sdBhvrColumns[1]["value"] = strIssuer;
				pBhvrList->addElement(sdBhrRow, ADD_BOTTOM);
			}
		}
	}
}

// ============================================================================
// RlvFloaterLocks member functions
//

// Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::onOpen(const LLSD& sdKey)
{
	m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterLocks::onRlvCommand, this, _1, _2));

	refreshAll();
}

// Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::onClose(bool fQuitting)
{
	m_ConnRlvCommand.disconnect();
}

// Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::onRlvCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
{
	// Refresh on any successful @XXX=y|n command where XXX is any of the attachment or wearable locking behaviours
	if ( (RLV_RET_SUCCESS == eRet) && ((RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType())) )
	{
		switch (rlvCmd.getBehaviourType())
		{
			case RLV_BHVR_DETACH:
			case RLV_BHVR_ADDATTACH:
			case RLV_BHVR_REMATTACH:
			case RLV_BHVR_ADDOUTFIT:
			case RLV_BHVR_REMOUTFIT:
				refreshAll();
				break;
			default:
				break;
		}
	}
}

// Checked: 2010-03-18 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvFloaterLocks::refreshAll()
{
	LLCtrlListInterface* pLockList = childGetListInterface("lock_list");
	if (!pLockList)
		return;
	pLockList->operateOnAll(LLCtrlListInterface::OP_DELETE);

	if (!isAgentAvatarValid())
		return;

	//
	// Set-up a row we can just reuse
	//
	LLSD sdRow;
	LLSD& sdColumns = sdRow["columns"];
	sdColumns[0]["column"] = "lock_type";   sdColumns[0]["type"] = "text";
	sdColumns[1]["column"] = "lock_addrem"; sdColumns[1]["type"] = "text";
	sdColumns[2]["column"] = "lock_target"; sdColumns[2]["type"] = "text";
	sdColumns[3]["column"] = "lock_origin"; sdColumns[3]["type"] = "text";

	//
	// List attachment locks
	//
	sdColumns[0]["value"] = "Attachment";
	sdColumns[1]["value"] = "rem";

	const RlvAttachmentLocks::rlv_attachobjlock_map_t& attachObjRem = gRlvAttachmentLocks.getAttachObjLocks();
	for (RlvAttachmentLocks::rlv_attachobjlock_map_t::const_iterator itAttachObj = attachObjRem.begin();
			itAttachObj != attachObjRem.end(); ++itAttachObj)
	{
		sdColumns[2]["value"] = rlvGetItemNameFromObjID(itAttachObj->first);
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachObj->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	//
	// List attachment point locks
	//
	sdColumns[0]["value"] = "Attachment Point";

	sdColumns[1]["value"] = "add";
	const RlvAttachmentLocks::rlv_attachptlock_map_t& attachPtAdd = gRlvAttachmentLocks.getAttachPtLocks(RLV_LOCK_ADD);
	for (RlvAttachmentLocks::rlv_attachptlock_map_t::const_iterator itAttachPt = attachPtAdd.begin();
			itAttachPt != attachPtAdd.end(); ++itAttachPt)
	{
		const LLViewerJointAttachment* pAttachPt =
			get_if_there(gAgentAvatarp->mAttachmentPoints, itAttachPt->first, (LLViewerJointAttachment*)NULL);
		sdColumns[2]["value"] = pAttachPt->getName();
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachPt->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	sdColumns[1]["value"] = "rem";
	const RlvAttachmentLocks::rlv_attachptlock_map_t& attachPtRem = gRlvAttachmentLocks.getAttachPtLocks(RLV_LOCK_REMOVE);
	for (RlvAttachmentLocks::rlv_attachptlock_map_t::const_iterator itAttachPt = attachPtRem.begin();
			itAttachPt != attachPtRem.end(); ++itAttachPt)
	{
		const LLViewerJointAttachment* pAttachPt =
			get_if_there(gAgentAvatarp->mAttachmentPoints, itAttachPt->first, (LLViewerJointAttachment*)NULL);
		sdColumns[2]["value"] = pAttachPt->getName();
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachPt->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	//
	// List wearable type locks
	//
	sdColumns[0]["value"] = "Wearable Type";

	sdColumns[1]["value"] = "add";
	const RlvWearableLocks::rlv_wearabletypelock_map_t& wearableTypeAdd = gRlvWearableLocks.getWearableTypeLocks(RLV_LOCK_ADD);
	for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeAdd.begin();
			itWearableType != wearableTypeAdd.end(); ++itWearableType)
	{
		sdColumns[2]["value"] = LLWearableType::getTypeLabel(itWearableType->first);
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}

	sdColumns[1]["value"] = "rem";
	const RlvWearableLocks::rlv_wearabletypelock_map_t& wearableTypeRem = gRlvWearableLocks.getWearableTypeLocks(RLV_LOCK_REMOVE);
	for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeRem.begin();
			itWearableType != wearableTypeRem.end(); ++itWearableType)
	{
		sdColumns[2]["value"] = LLWearableType::getTypeName(itWearableType->first);
		sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second);

		pLockList->addElement(sdRow, ADD_BOTTOM);
	}
}

// ============================================================================
<|endoftext|>


<commit_before>// https://leetcode.com/problems/word-break/

/*

  Given a string s and a dictionary of words dict, determine if s can be segmented into a
  space-separated sequence of one or more dictionary words.

  For example, given
  s = "leetcode",
  dict = ["leet", "code"].

  Return true because "leetcode" can be segmented as "leet code".
*/

#include <string>
#include <vector>
#include <utility>
#include <unordered_set>
#include <unordered_map>

using std::pair;
using std::string;
using std::vector;
using std::unordered_set;

class Solution {
public:
  bool wordBreak(string s, unordered_set<string>& wordDict) {
    return backTrack(s, 0, 0, wordDict, s.length());
  }
private:
  vector<pair<unsigned, unsigned>> m_words;

  bool backTrack(string s, unsigned offset, unsigned pos, unordered_set<string>& d, size_t len) {
    if (pos == len) {
      if (m_words.size() > offset) {
        auto const& p = m_words.back(); m_words.pop_back();
        return backTrack(s, p.first, p.second + 1, d, len);
      } else {
        return false;
      }
    }

    string sub = s.substr(offset, pos + 1 - offset);
    if (d.find(sub) != d.end()) {
      if (pos == len - 1) return true;
      else {
        m_words.push_back(std::make_pair(offset, pos));
        return backTrack(s, pos + 1, pos + 1, d, len);
      }
    }

    return backTrack(s, offset, pos + 1, d, len);
  }
};
<commit_msg>:new: finish word break<commit_after>// https://leetcode.com/problems/word-break/

/*

  Given a string s and a dictionary of words dict, determine if s can be segmented into a
  space-separated sequence of one or more dictionary words.

  For example, given
  s = "leetcode",
  dict = ["leet", "code"].

  Return true because "leetcode" can be segmented as "leet code".
*/

#include <string>
#include <vector>
#include <unordered_set>

using std::string;
using std::vector;
using std::unordered_set;

// leet
// false false false true

class Solution {
public:
  bool wordBreak(string s, unordered_set<string>& wordDict) {
    vector<bool> dp(s.length() + 1, false);
    dp.back() = true;

    // Start at the second to last letter of the word
    for (int offset = s.length() - 1; offset >= 0; offset--) {

      // Start at the offset, and increase substring length
      for (size_t pos = offset, len = s.length(); pos < len; pos++) {

        // When you reach a previous word boundary, check if current substring is also a word
        if (dp[pos + 1] == true && wordDict.find(s.substr(offset, pos + 1 - offset)) != wordDict.end()) {

          // Set position of first letter of word to true
          dp[offset] = true;
          break;
        }
      }
    }

    // If the first entry is true
    // It means that there was a word before it (and a word before that word and so one)
    return dp[0];
  }
};
<|endoftext|>


<commit_before>#include "main.h"

/* example constructor, sets some options */
Rail::Rail()
{
    // declare options, keep options as uppercase
    vector<string> temp;
    temp.push_back("INPUTFILE");
    temp.push_back("OUTPUTFILE");
    temp.push_back("NUMRAILS");
    temp.push_back("DECRYPT");
    set_opts(temp);

    // set default values, option must exist or error will printed
    set_opt_value("OUTPUTFILE", "encr_rail.txt");
    set_opt_value("DECRYPT", "0");
	set_opt_value("NUMRAILS", "5");
	// delete before merge
	set_opt_value("INPUTFILE", "makefile");
}

/* I am overriding the default module function
 * for displaying the description text
 */
void Rail::disp_desc()
{
    cout << "Module: ciphers/rail\n\tEncrypts (or decrypts, if number of rails known) a text file with the rail fence cipher.\n\tPlease define the following required options:\n\t\tINPUTFILE\tinput filename" << endl;
    cout << endl;
}

/* overrides the virtual function from Module
 * this is where the real meaty stuff happens
 */
int Rail::run()
{
	ifstream in;
	ofstream out;
	string ibuff, obuff;
	bool shouldDecrypt = false;

	// perform error checking on options first
	if (options["INPUTFILE"].empty()) {
		cout << "[-] Please specify an input file" << endl;
		return 1;
	}

	if (options["OUTPUTFILE"].empty()) {
		cout << "[-] Please specify an output file" << endl;
		return 2;
	}

	if (options["NUMRAILS"].empty()) {
		cout << "[-] Please specify the number of rails" << endl;
		return 3;
	}

	if (options["DECRYPT"] == "1"){
		shouldDecrypt = true;
	}

    cout << "[*] Opening input file: " << options["INPUTFILE"] << endl;
    in.open(options["INPUTFILE"]);

    if (!in.good()) {
        cout << "[-] Input file error" << endl;
        return 5;
    }

    cout << "[*] Opening output file: " << options["OUTPUTFILE"] << endl;
    out.open(options["OUTPUTFILE"]);

	if (!shouldDecrypt) {
		cout << "[*] Encrypting..." << endl;
		encrypt(&in, &out, stoi(options["NUMRAILS"]));
	}
	else {
		cout << "[*] Decrypting..." << endl;
		decrypt(&in, &out, stoi(options["NUMRAILS"]));
	}

    cout << "[*] Closing files" << endl;
    in.close();
    out.close();

    return 0;
}

void Rail::encrypt(ifstream* in, ostream* out, int numRails)
{
	vector< vector<char> > rails;
	rails.resize(numRails);
	char inChar;
	int currRail = 0;
	bool ascend = true;
	while (in->get(inChar)) {
		rails[currRail].push_back(inChar);
		if (ascend) {
			currRail++;
			if (currRail == numRails-1)
				ascend = false;
		}
		else {
			currRail--;
			if (currRail == 0)
				ascend = true;
		}
	}

	//Just pad for easier decryption honestly
	if (!ascend) {
		while (currRail > 0) {
			rails[currRail].push_back('\n');
			if (currRail > 0) currRail--;
		}
	}
	while (currRail < numRails) {
		rails[currRail].push_back('\n');
		currRail++;
	}

	for (vector<char> vec : rails) {
		for (char output : vec) {
			(*out) << output;
		}
	}
}

void Rail::decrypt(ifstream* in, ostream* out, int numRails)
{
	vector< vector<char> > rails;
	rails.resize(numRails);
	char inChar;

	string inLine;
	int length = 0;
	while (getline(*in, inLine)) {
		length += inLine.length();
	}
	(*in).clear();
	(*in).seekg(0, ios::beg);

	int numOnEdges = length / ((numRails * 2) - 2);
	int numInside = numOnEdges * 2 - 1;

	for (int numInLine = 0; numInLine < numOnEdges; numInLine++) {
		if (in->get(inChar)) {
			rails[0].push_back(inChar);
		}
	}
	for (int rail = 1; rail < numRails - 1; rail++) {
		for (int numInLine = 0; numInLine < numInside; numInLine++) {
			if (in->get(inChar)) {
				rails[rail].push_back(inChar);
			}
		}
	}
	for (int numInLine = 0; numInLine < numOnEdges; numInLine++) {
		if (in->get(inChar)) {
			rails[numRails-1].push_back(inChar);
		}
	}

	int edgeIndex = 0;
	int middleIndex = 0;
	int railIndex = 0;
	bool ascend = true;

	while (edgeIndex < numOnEdges) {
		if (railIndex == 0 || railIndex == numRails - 1) {
			(*out) << rails[edgeIndex][railIndex];
		}
		else {
			(*out) << rails[middleIndex][railIndex];
		}

		if (ascend) {
			railIndex++;
			if (railIndex == numRails - 1) {
				ascend = false;
				middleIndex++;
			}
		}
		else {
			railIndex--;
			if (railIndex == 0) {
				ascend = true;
				edgeIndex++;
				middleIndex++;
			}
		}
	}
}<commit_msg>further cleanup<commit_after>#include "main.h"

/* example constructor, sets some options */
Rail::Rail()
{
    // declare options, keep options as uppercase
    vector<string> temp;
    temp.push_back("INPUTFILE");
    temp.push_back("OUTPUTFILE");
    temp.push_back("NUMRAILS");
    temp.push_back("DECRYPT");
    set_opts(temp);

    // set default values, option must exist or error will printed
    set_opt_value("OUTPUTFILE", "encr_rail.txt");
    set_opt_value("DECRYPT", "0");
	set_opt_value("NUMRAILS", "5");
}

/* I am overriding the default module function
 * for displaying the description text
 */
void Rail::disp_desc()
{
    cout << "Module: ciphers/rail\n\tEncrypts (or decrypts, if number of rails known) a text file with the rail fence cipher.\n\tPlease define the following required options:\n\t\tINPUTFILE\tinput filename" << endl;
    cout << endl;
}

/* overrides the virtual function from Module
 * this is where the real meaty stuff happens
 */
int Rail::run()
{
	ifstream in;
	ofstream out;
	string ibuff, obuff;
	bool shouldDecrypt = false;

	// perform error checking on options first
	if (options["INPUTFILE"].empty()) {
		cout << "[-] Please specify an input file" << endl;
		return 1;
	}

	if (options["OUTPUTFILE"].empty()) {
		cout << "[-] Please specify an output file" << endl;
		return 2;
	}

	if (options["NUMRAILS"].empty()) {
		cout << "[-] Please specify the number of rails" << endl;
		return 3;
	}

	if (options["DECRYPT"] == "1"){
		shouldDecrypt = true;
	}

    cout << "[*] Opening input file: " << options["INPUTFILE"] << endl;
    in.open(options["INPUTFILE"]);

    if (!in.good()) {
        cout << "[-] Input file error" << endl;
        return 5;
    }

    cout << "[*] Opening output file: " << options["OUTPUTFILE"] << endl;
    out.open(options["OUTPUTFILE"]);

	if (!shouldDecrypt) {
		cout << "[*] Encrypting..." << endl;
		encrypt(&in, &out, stoi(options["NUMRAILS"]));
	}
	else {
		cout << "[*] Decrypting..." << endl;
		decrypt(&in, &out, stoi(options["NUMRAILS"]));
	}

    cout << "[*] Closing files" << endl;
    in.close();
    out.close();

    return 0;
}

void Rail::encrypt(ifstream* in, ostream* out, int numRails)
{
	vector< vector<char> > rails;
	rails.resize(numRails);
	char inChar;
	int currRail = 0;
	bool ascend = true;
	while (in->get(inChar)) {
		rails[currRail].push_back(inChar);
		if (ascend) {
			currRail++;
			if (currRail == numRails-1)
				ascend = false;
		}
		else {
			currRail--;
			if (currRail == 0)
				ascend = true;
		}
	}

	//Just pad for easier decryption honestly
	if (!ascend) {
		while (currRail > 0) {
			rails[currRail].push_back('\n');
			if (currRail > 0) currRail--;
		}
	}
	while (currRail < numRails) {
		rails[currRail].push_back('\n');
		currRail++;
	}

	for (vector<char> vec : rails) {
		for (char output : vec) {
			(*out) << output;
		}
	}
}

void Rail::decrypt(ifstream* in, ostream* out, int numRails)
{
	vector< vector<char> > rails;
	rails.resize(numRails);
	char inChar;

	string inLine;
	int length = 0;
	while (getline(*in, inLine)) {
		length += inLine.length();
	}
	(*in).clear();
	(*in).seekg(0, ios::beg);

	int numOnEdges = length / ((numRails * 2) - 2);
	int numInside = numOnEdges * 2 - 1;

	for (int numInLine = 0; numInLine < numOnEdges; numInLine++) {
		if (in->get(inChar)) {
			rails[0].push_back(inChar);
		}
	}
	for (int rail = 1; rail < numRails - 1; rail++) {
		for (int numInLine = 0; numInLine < numInside; numInLine++) {
			if (in->get(inChar)) {
				rails[rail].push_back(inChar);
			}
		}
	}
	for (int numInLine = 0; numInLine < numOnEdges; numInLine++) {
		if (in->get(inChar)) {
			rails[numRails-1].push_back(inChar);
		}
	}

	int edgeIndex = 0;
	int middleIndex = 0;
	int railIndex = 0;
	bool ascend = true;

	while (edgeIndex < numOnEdges) {
		if (railIndex == 0 || railIndex == numRails - 1) {
			(*out) << rails[edgeIndex][railIndex];
		}
		else {
			(*out) << rails[middleIndex][railIndex];
		}

		if (ascend) {
			railIndex++;
			if (railIndex == numRails - 1) {
				ascend = false;
				middleIndex++;
			}
		}
		else {
			railIndex--;
			if (railIndex == 0) {
				ascend = true;
				edgeIndex++;
				middleIndex++;
			}
		}
	}
}<|endoftext|>