<commit_before>/*
* File:  ipc_ops.cpp
* Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
*/

#include <string>

#include "common/sedna.h"

#include "common/ipc_ops.h"
#include "common/base.h"
#include "common/utils.h"
#include "common/u/usocket.h"
#include "common/u/uhdd.h"
#include "common/u/uutils.h"
#include "common/errdbg/d_printf.h"
#include "expat.h"

static std::string elem_content;
char* SEDNA_DATA = NULL;
void* sedna_gov_shm_ptr = NULL;
static UShMem gov_shm_service_dsc;

/******************************************************************************
 * Governor shared memory open/close
 ******************************************************************************/

void
open_gov_shm()
{
    if ( NULL == sedna_gov_shm_ptr )
    {
        if (0 != uOpenShMem(&gov_shm_service_dsc,
            GOVERNOR_SHARED_MEMORY_NAME,
            __sys_call_error))
            throw USER_EXCEPTION2(SE4400, "Can't open GOVERNOR shared memory");   /// SEDNA server is not running

        sedna_gov_shm_ptr = uAttachShMem(&gov_shm_service_dsc,
            NULL,
            0,
            __sys_call_error);

        if (NULL == sedna_gov_shm_ptr)
            throw USER_EXCEPTION2(SE4023, "GOVERNOR shared memory");   /// Can't attach to shared memory
    }
}

int
close_gov_shm()
{
    if ( NULL != sedna_gov_shm_ptr )
    {
        if ( 0 != uDettachShMem(&gov_shm_service_dsc, sedna_gov_shm_ptr, __sys_call_error))
            return -1;

        if ( 0 != uCloseShMem(&gov_shm_service_dsc, __sys_call_error))
            return -1;
    }

    return 0;
}

/******************************************************************************
 * Governor communication mechanism
 ******************************************************************************/

void send_command_to_gov(int port_number, char gov_address[], int cmd)
{
    USOCKET s;
    int rc;
    char *ptr;
    int32_t tmp;

    s = usocket(AF_INET, SOCK_STREAM, 0, __sys_call_error);

    if (uconnect_tcp(s, port_number, gov_address, __sys_call_error) == 0)
    {
        tmp = htonl(cmd);
        ptr = (char*) &(tmp);
        rc = 0;
        while(rc < 4)
        {
            rc += usend(s, ptr+rc, 4-rc, __sys_call_error);
        }
        rc = 0;
        ptr = (char*) &(rc);
        while(rc < 4)
        {
            rc += usend(s, ptr+rc, 4-rc, __sys_call_error);
        }
        ushutdown_close_socket(s, __sys_call_error);
    }
    else
        d_printf2("SOCKET ERROR: %s\n",usocket_error_translator());
}

int get_db_id_by_name(gov_config_struct* cfg, const char* db_name)
{
    for(int i=0; i< MAX_DBS_NUMBER; ++i)
    {
        if (strcmp(cfg->db_vars[i].db_name, db_name) == 0)
            return i;
    }

    return -1;
}

int get_next_free_db_id(gov_config_struct* cfg)
{
    for (int i=0; i< MAX_DBS_NUMBER; ++i)
    {
        if (cfg->db_vars[i].db_name[0] == '\0')
            return i;
    }

    return -1;
}

bool is_database_running(gov_config_struct* cfg, int database_id)
{
    return cfg->db_vars[database_id].mode != OM_SM_DOWN;
}

void erase_database_cell_in_gov_shm(int db_id, gov_config_struct* cfg)
{
    if (!cfg) return;
    if (db_id >= MAX_DBS_NUMBER || db_id < 0) return;

    memset(&(cfg->db_vars[db_id]), '\0', sizeof(gov_db_struct));
}

void fill_database_cell_in_gov_shm(gov_config_struct* cfg,
                                   int db_id,
                                   const char* db_name,
                                   int bufs_num,
                                   double upd_crt,
                                   int max_log_files,
                                   int tmp_file_initial_size /* size in PAGES */)
{
    strcpy(cfg->db_vars[db_id].db_name, db_name);
    cfg->db_vars[db_id].mode = OM_SM_DOWN;
    cfg->db_vars[db_id].sm_pid = -1;
    cfg->db_vars[db_id].bufs_num = bufs_num;
    cfg->db_vars[db_id].upd_crt = upd_crt;
    cfg->db_vars[db_id].max_log_files = max_log_files;
    cfg->db_vars[db_id].tmp_file_initial_size = tmp_file_initial_size;
}

/******************************************************************************
 * Parser for sednaconf file
 ******************************************************************************/

static void startElement_gov_cfg(void *cfg, const char *name, const char **atts)
{
}

static void endElement_gov_cfg(void *cfg, const char *name)
{
    if (strcmp(name, "sedna_data") == 0)
    {
        strcpy(((gov_header_struct*)cfg)->SEDNA_DATA, trim(elem_content).c_str());
    }
    if (strcmp(name, "listen_address") == 0)
    {
        strcpy(((gov_header_struct*)cfg)->lstnr_addr, trim(elem_content).c_str());
    }
    if (strcmp(name, "listener_port") == 0)
    {
        ((gov_header_struct*)cfg)->lstnr_port_number = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "ping_port") == 0)
    {
        ((gov_header_struct*)cfg)->ping_port_number = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "os_primitives_id_min_bound") == 0)
    {
        ((gov_header_struct*)cfg)->os_primitives_id_min_bound = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "event_log_level") == 0)
    {
        ((gov_header_struct*)cfg)->el_level = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "keep_alive_timeout") == 0)
    {
        ((gov_header_struct*)cfg)->ka_timeout = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "session_stack_depth") == 0)
    {
        ((gov_header_struct*)cfg)->pp_stack_depth = atoi(trim(elem_content).c_str());
    }

    elem_content = "";
}

static void characterData_gov_cfg(void *cfg, const XML_Char *s, int len)
{
    elem_content.append(s, len);
}

static void parse_config_file(gov_header_struct* cfg, std::string& cfg_text)
{
    XML_Parser parser = XML_ParserCreate (NULL);
    XML_SetElementHandler (parser, startElement_gov_cfg, endElement_gov_cfg);
    XML_SetCharacterDataHandler (parser, characterData_gov_cfg);
    XML_SetUserData (parser, cfg);

    if(cfg_text.length() > INT_MAX)
        throw USER_EXCEPTION2(SE4201,  "Too long sednaconf.xml file");

    int parse_res = XML_Parse (parser, cfg_text.c_str(), (int)cfg_text.length(), 1);

    if(parse_res == XML_STATUS_ERROR)
        throw USER_EXCEPTION2(SE4201,  "sednaconf.xml");

    XML_ParserFree(parser);
}

/******************************************************************************
 * Retrieve system config parameters
 ******************************************************************************/

void get_sednaconf_values(gov_header_struct* cfg)
{
    char sedna_cfg_file[U_MAX_PATH + 30];
    char proc_buf[U_MAX_PATH + 1];

    FILE* fs;
    char buf[1024];
    size_t size;
    std::string cfg_text;
    cfg_text.reserve(10240);

    uGetImageProcPath(proc_buf, __sys_call_error);
    if (proc_buf[0] == '\0')
        throw USER_EXCEPTION(SE4081);

    cfg->is_server_stop = SE_STOP_NO;
    strcpy(cfg->lstnr_addr, "localhost");
    cfg->lstnr_port_number = 5050;
    cfg->ping_port_number = 5151;
    cfg->os_primitives_id_min_bound = 1500;
    cfg->el_level = 3;
    cfg->ka_timeout = 0;
    cfg->pp_stack_depth = 4000;

    strcpy(cfg->SEDNA_DATA, proc_buf);
    strcpy(sedna_cfg_file,  proc_buf);

#ifdef _WIN32
    strcat(cfg->SEDNA_DATA, "\\..");
    strcat(sedna_cfg_file, "\\..\\etc\\sednaconf.xml");
#else
    strcat(cfg->SEDNA_DATA, "/..");
    strcat(sedna_cfg_file, "/../etc/sednaconf.xml");
#endif

    fs = fopen(sedna_cfg_file, "r");

#ifndef _WIN32
    if(NULL == fs)
    {
        strcpy(sedna_cfg_file, "/etc/sednaconf.xml");
        fs = fopen(sedna_cfg_file, "r");
    }
#endif /* _WIN32 */

    if (fs != NULL)
    {
        d_printf2("sedna_cfg_file=%s\n", sedna_cfg_file);

        while (true)
        {
            size = fread(buf, sizeof(char), 1024, fs);
            if (ferror(fs)) throw USER_EXCEPTION2(SE4044, sedna_cfg_file);
            cfg_text.append(buf, size);
            if (feof(fs)) break;
        }

        fclose(fs);
        parse_config_file(cfg, cfg_text);
    }
}

/*
 * The following methods fills given buffer with the sedna_data path.
 * They MUST not throw exception and should use fprintf(stderr, " ... ") to
 * log out error message.
 * The reason why we need this method is sedna soft fault mechanism, which
 * can be triggred at the very begining of any sedna process when
 * SEDNA_DATA variable is not set.
 */
static void get_sedna_data_path(const char* cfg_text, char* buf)
{
      const char* beg, *fin;
      const char* sedna_data_open_tag  = "<sedna_data>";
      const char* sedna_data_close_tag = "</sedna_data>";
      unsigned short value_shift = (unsigned short)strlen(sedna_data_open_tag);
      std::string save_buf(buf);

      beg = strstr(cfg_text, sedna_data_open_tag);
      fin = strstr(cfg_text, sedna_data_close_tag);

      d_printf2("cfg_text=%s\n", cfg_text);
      if (beg == NULL || fin == NULL) return;

      memcpy(buf, beg + value_shift, fin - beg + value_shift);
      buf[fin - beg + value_shift] = '\0';

      std::string tmp(buf);
      tmp = trim(tmp);

      if(tmp.length() > U_MAX_PATH)
      {
          fprintf(stderr, "Path in the 'sedna_data' parameter is too long in sednaconf.xml. Going to use default value.\n");
          strcpy(buf, save_buf.c_str());
      }
      else
          strcpy(buf, tmp.c_str());
}

int set_sedna_data(char* sd_buf, sys_call_error_fun fun)
{
    char proc_buf[U_MAX_PATH + 1];
    char sedna_cfg_file[U_MAX_PATH + 1];
    FILE* fs;
    char buf[1024];
    size_t size;
    std::string cfg_text;
    cfg_text.reserve(10240);

    uGetImageProcPath(proc_buf, fun);
    if (proc_buf[0] == '\0')
    {   fprintf(stderr, "Can't get process path to set sedna data\n");
    return 0;
    }

    strcpy(sd_buf, proc_buf);  /// Copy default SEDNA_DATA value
    strcpy(sedna_cfg_file, proc_buf);

#ifdef _WIN32
    strcat(sd_buf, "\\..");
    strcat(sedna_cfg_file, "\\..\\etc\\sednaconf.xml");
#else
    strcat(sd_buf, "/..");
    strcat(sedna_cfg_file, "/../etc/sednaconf.xml");
#endif

    fs = fopen(sedna_cfg_file, "r");

#ifndef _WIN32
    if(NULL == fs)
    {
        strcpy(sedna_cfg_file, "/etc/sednaconf.xml");
        fs = fopen(sedna_cfg_file, "r");
    }
#endif /* _WIN32 */

    if (fs != NULL)
    {
        d_printf2("sedna_cfg_file=%s\n", sedna_cfg_file);
        while (true)
        {
            size = fread(buf, sizeof(char), 1024, fs);
            if (ferror(fs))
            {
                fclose(fs);
                fprintf(stderr, "Can't read sednaconf.xml to set sedna data path. Going to use default value.\n");
                return 1;
            }
            cfg_text.append(buf, size);
            if (feof(fs)) break;
        }
        fclose(fs);

        get_sedna_data_path(cfg_text.c_str(), sd_buf);
    }

    d_printf2("sedna data path retrieved=%s\n", sd_buf);

    return 1;
}

<commit_msg>get sedna data path (fault version) cleanup<commit_after>/*
* File:  ipc_ops.cpp
* Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
*/

#include <string>

#include "common/sedna.h"

#include "common/ipc_ops.h"
#include "common/base.h"
#include "common/utils.h"
#include "common/u/usocket.h"
#include "common/u/uhdd.h"
#include "common/u/uutils.h"
#include "common/errdbg/d_printf.h"
#include "expat.h"

static std::string elem_content;
char* SEDNA_DATA = NULL;
void* sedna_gov_shm_ptr = NULL;
static UShMem gov_shm_service_dsc;

/******************************************************************************
 * Governor shared memory open/close
 ******************************************************************************/

void
open_gov_shm()
{
    if ( NULL == sedna_gov_shm_ptr )
    {
        if (0 != uOpenShMem(&gov_shm_service_dsc,
            GOVERNOR_SHARED_MEMORY_NAME,
            __sys_call_error))
            throw USER_EXCEPTION2(SE4400, "Can't open GOVERNOR shared memory");   /// SEDNA server is not running

        sedna_gov_shm_ptr = uAttachShMem(&gov_shm_service_dsc,
            NULL,
            0,
            __sys_call_error);

        if (NULL == sedna_gov_shm_ptr)
            throw USER_EXCEPTION2(SE4023, "GOVERNOR shared memory");   /// Can't attach to shared memory
    }
}

int
close_gov_shm()
{
    if ( NULL != sedna_gov_shm_ptr )
    {
        if ( 0 != uDettachShMem(&gov_shm_service_dsc, sedna_gov_shm_ptr, __sys_call_error))
            return -1;

        if ( 0 != uCloseShMem(&gov_shm_service_dsc, __sys_call_error))
            return -1;
    }

    return 0;
}

/******************************************************************************
 * Governor communication mechanism
 ******************************************************************************/

void send_command_to_gov(int port_number, char gov_address[], int cmd)
{
    USOCKET s;
    int rc;
    char *ptr;
    int32_t tmp;

    s = usocket(AF_INET, SOCK_STREAM, 0, __sys_call_error);

    if (uconnect_tcp(s, port_number, gov_address, __sys_call_error) == 0)
    {
        tmp = htonl(cmd);
        ptr = (char*) &(tmp);
        rc = 0;
        while(rc < 4)
        {
            rc += usend(s, ptr+rc, 4-rc, __sys_call_error);
        }
        rc = 0;
        ptr = (char*) &(rc);
        while(rc < 4)
        {
            rc += usend(s, ptr+rc, 4-rc, __sys_call_error);
        }
        ushutdown_close_socket(s, __sys_call_error);
    }
    else
        d_printf2("SOCKET ERROR: %s\n",usocket_error_translator());
}

int get_db_id_by_name(gov_config_struct* cfg, const char* db_name)
{
    for(int i=0; i< MAX_DBS_NUMBER; ++i)
    {
        if (strcmp(cfg->db_vars[i].db_name, db_name) == 0)
            return i;
    }

    return -1;
}

int get_next_free_db_id(gov_config_struct* cfg)
{
    for (int i=0; i< MAX_DBS_NUMBER; ++i)
    {
        if (cfg->db_vars[i].db_name[0] == '\0')
            return i;
    }

    return -1;
}

bool is_database_running(gov_config_struct* cfg, int database_id)
{
    return cfg->db_vars[database_id].mode != OM_SM_DOWN;
}

void erase_database_cell_in_gov_shm(int db_id, gov_config_struct* cfg)
{
    if (!cfg) return;
    if (db_id >= MAX_DBS_NUMBER || db_id < 0) return;

    memset(&(cfg->db_vars[db_id]), '\0', sizeof(gov_db_struct));
}

void fill_database_cell_in_gov_shm(gov_config_struct* cfg,
                                   int db_id,
                                   const char* db_name,
                                   int bufs_num,
                                   double upd_crt,
                                   int max_log_files,
                                   int tmp_file_initial_size /* size in PAGES */)
{
    strcpy(cfg->db_vars[db_id].db_name, db_name);
    cfg->db_vars[db_id].mode = OM_SM_DOWN;
    cfg->db_vars[db_id].sm_pid = -1;
    cfg->db_vars[db_id].bufs_num = bufs_num;
    cfg->db_vars[db_id].upd_crt = upd_crt;
    cfg->db_vars[db_id].max_log_files = max_log_files;
    cfg->db_vars[db_id].tmp_file_initial_size = tmp_file_initial_size;
}

/******************************************************************************
 * Parser for sednaconf file
 ******************************************************************************/

static void startElement_gov_cfg(void *cfg, const char *name, const char **atts)
{
}

static void endElement_gov_cfg(void *cfg, const char *name)
{
    if (strcmp(name, "sedna_data") == 0)
    {
        strcpy(((gov_header_struct*)cfg)->SEDNA_DATA, trim(elem_content).c_str());
    }
    if (strcmp(name, "listen_address") == 0)
    {
        strcpy(((gov_header_struct*)cfg)->lstnr_addr, trim(elem_content).c_str());
    }
    if (strcmp(name, "listener_port") == 0)
    {
        ((gov_header_struct*)cfg)->lstnr_port_number = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "ping_port") == 0)
    {
        ((gov_header_struct*)cfg)->ping_port_number = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "os_primitives_id_min_bound") == 0)
    {
        ((gov_header_struct*)cfg)->os_primitives_id_min_bound = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "event_log_level") == 0)
    {
        ((gov_header_struct*)cfg)->el_level = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "keep_alive_timeout") == 0)
    {
        ((gov_header_struct*)cfg)->ka_timeout = atoi(trim(elem_content).c_str());
    }
    if (strcmp(name, "session_stack_depth") == 0)
    {
        ((gov_header_struct*)cfg)->pp_stack_depth = atoi(trim(elem_content).c_str());
    }

    elem_content = "";
}

static void characterData_gov_cfg(void *cfg, const XML_Char *s, int len)
{
    elem_content.append(s, len);
}

static void parse_config_file(gov_header_struct* cfg, std::string& cfg_text)
{
    XML_Parser parser = XML_ParserCreate (NULL);
    XML_SetElementHandler (parser, startElement_gov_cfg, endElement_gov_cfg);
    XML_SetCharacterDataHandler (parser, characterData_gov_cfg);
    XML_SetUserData (parser, cfg);

    if(cfg_text.length() > INT_MAX)
        throw USER_EXCEPTION2(SE4201,  "Too long sednaconf.xml file");

    int parse_res = XML_Parse (parser, cfg_text.c_str(), (int)cfg_text.length(), 1);

    if(parse_res == XML_STATUS_ERROR)
        throw USER_EXCEPTION2(SE4201,  "sednaconf.xml");

    XML_ParserFree(parser);
}

/******************************************************************************
 * Retrieve system config parameters
 ******************************************************************************/

void get_sednaconf_values(gov_header_struct* cfg)
{
    char sedna_cfg_file[U_MAX_PATH + 30];
    char proc_buf[U_MAX_PATH + 1];

    FILE* fs;
    char buf[1024];
    size_t size;
    std::string cfg_text;
    cfg_text.reserve(10240);

    uGetImageProcPath(proc_buf, __sys_call_error);
    if (proc_buf[0] == '\0')
        throw USER_EXCEPTION(SE4081);

    cfg->is_server_stop = SE_STOP_NO;
    strcpy(cfg->lstnr_addr, "localhost");
    cfg->lstnr_port_number = 5050;
    cfg->ping_port_number = 5151;
    cfg->os_primitives_id_min_bound = 1500;
    cfg->el_level = 3;
    cfg->ka_timeout = 0;
    cfg->pp_stack_depth = 4000;

    strcpy(cfg->SEDNA_DATA, proc_buf);
    strcpy(sedna_cfg_file,  proc_buf);

#ifdef _WIN32
    strcat(cfg->SEDNA_DATA, "\\..");
    strcat(sedna_cfg_file, "\\..\\etc\\sednaconf.xml");
#else
    strcat(cfg->SEDNA_DATA, "/..");
    strcat(sedna_cfg_file, "/../etc/sednaconf.xml");
#endif

    fs = fopen(sedna_cfg_file, "r");

#ifndef _WIN32
    if(NULL == fs)
    {
        strcpy(sedna_cfg_file, "/etc/sednaconf.xml");
        fs = fopen(sedna_cfg_file, "r");
    }
#endif /* _WIN32 */

    if (fs != NULL)
    {
        d_printf2("sedna config file=%s\n", sedna_cfg_file);

        while (true)
        {
            size = fread(buf, sizeof(char), 1024, fs);
            if (ferror(fs)) throw USER_EXCEPTION2(SE4044, sedna_cfg_file);
            cfg_text.append(buf, size);
            if (feof(fs)) break;
        }

        fclose(fs);
        parse_config_file(cfg, cfg_text);
    }
}

/*
 * Note: This function returns a pointer to a substring of the original string.
 * If the given string was allocated dynamically, the caller must not overwrite
 * that pointer with the returned value, since the original pointer must be
 * deallocated using the same allocator with which it was allocated.  The return
 * value must NOT be deallocated using free() etc.
*/
static char *strtrim(char *str)
{
    char *end;

    // Trim leading space
    while(isspace(*str)) str++;

    if(*str == 0)  // All spaces?
        return str;

    // Trim trailing space
    end = str + strlen(str) - 1;
    while(end > str && isspace(*end)) end--;

    // Write new null terminator
    *(end+1) = 0;

    return str;
}

/*
 * The following methods fills in given buffer with the sedna_data path.
 * They MUST not throw exception and should use fprintf(stderr, " ... ") to
 * log out error message.
 * The reason why we need this method is sedna soft fault mechanism, which
 * can be triggred at the very begining of any sedna process when
 * SEDNA_DATA variable is not set.
 */
static int get_sedna_data_path(const char* cfg_text, char* dst)
{
    char temp[U_MAX_PATH + 1];
    const char* beg, *fin;
    const char* sedna_data_open_tag  = "<sedna_data>";
    const char* sedna_data_close_tag = "</sedna_data>";
    const unsigned short tag_shift = 12; // (unsigned short)strlen(sedna_data_open_tag);

    beg = strstr(cfg_text, sedna_data_open_tag);
    fin = strstr(cfg_text, sedna_data_close_tag);

    if (beg == NULL || fin == NULL) {
        fprintf(stderr, "'sedna_data' parameter value not found in sednaconf.xml. Going to use the default SEDNA_DATA value.\n");
        return 0;
    }

    beg += tag_shift;

    if (beg >= fin || fin - beg > U_MAX_PATH) {
        fprintf(stderr, "'sedna_data' parameter too long in sednaconf.xml. Going to use the default SEDNA_DATA value.\n");
        return 0;
    }

    memcpy(temp, beg, fin - beg);
    temp[fin - beg] = '\0';
    strcpy(dst, strtrim(temp));
    return 1;
}

int set_sedna_data(char* sd_buf, sys_call_error_fun fun)
{
    char proc_buf[U_MAX_PATH + 1];
    char sedna_cfg_file[U_MAX_PATH + 1];

    FILE* fs;
    char buf[1024];
    size_t size;
    std::string cfg_text;
    cfg_text.reserve(10240);

    uGetImageProcPath(proc_buf, fun);
    if (proc_buf[0] == '\0')
    {
        fprintf(stderr, "Can't get process path to set sedna data\n");
        return 0;
    }

    d_printf2("process image path=%s\n", proc_buf);
    strcpy(sd_buf, proc_buf);  // Copy part of the default SEDNA_DATA value
    strcpy(sedna_cfg_file, proc_buf);

#ifdef _WIN32
    strcat(sd_buf, "\\..");
    strcat(sedna_cfg_file, "\\..\\etc\\sednaconf.xml");
#else
    strcat(sd_buf, "/..");
    strcat(sedna_cfg_file, "/../etc/sednaconf.xml");
#endif

    fs = fopen(sedna_cfg_file, "r");

#ifndef _WIN32
    if(NULL == fs)
    {
        strcpy(sedna_cfg_file, "/etc/sednaconf.xml");
        fs = fopen(sedna_cfg_file, "r");
    }
#endif /* _WIN32 */

    if (fs != NULL)
    {
        d_printf2("sedna config file path=%s\n", sedna_cfg_file);
        while (true)
        {
            size = fread(buf, sizeof(char), 1024, fs);
            if (ferror(fs))
            {
                fclose(fs);
                fprintf(stderr, "Can't read sednaconf.xml to set sedna data path. Going to use default value.\n");
                return 1;
            }
            cfg_text.append(buf, size);
            if (feof(fs)) break;
        }
        fclose(fs);

        get_sedna_data_path(cfg_text.c_str(), sd_buf);
    }

    d_printf2("sedna data path retrieved=%s\n", sd_buf);
    return 1;
}
<|endoftext|>


<commit_before>//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Defines the registration function for the analyzer checkers.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/StaticAnalyzer/Checkers/ClangCheckers.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h"
#include "clang/StaticAnalyzer/Core/CheckerRegistry.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>

using namespace clang;
using namespace ento;
using llvm::sys::DynamicLibrary;

namespace {
class ClangCheckerRegistry : public CheckerRegistry {
  typedef void (*RegisterCheckersFn)(CheckerRegistry &);

  static bool isCompatibleAPIVersion(const char *versionString);
  static void warnIncompatible(DiagnosticsEngine *diags, StringRef pluginPath,
                               const char *pluginAPIVersion);

public:
  ClangCheckerRegistry(ArrayRef<std::string> plugins,
                       DiagnosticsEngine *diags = nullptr);
};

} // end anonymous namespace

ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins,
                                           DiagnosticsEngine *diags) {
  registerBuiltinCheckers(*this);

  for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
       i != e; ++i) {
    // Get access to the plugin.
    std::string err;
    DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
    if (!lib.isValid()) {
      diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err;
      continue;
    }

    // See if it's compatible with this build of clang.
    const char *pluginAPIVersion =
      (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
    if (!isCompatibleAPIVersion(pluginAPIVersion)) {
      warnIncompatible(diags, *i, pluginAPIVersion);
      continue;
    }

    // Register its checkers.
    RegisterCheckersFn registerPluginCheckers =
      (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
                                                      "clang_registerCheckers");
    if (registerPluginCheckers)
      registerPluginCheckers(*this);
  }
}

bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) {
  // If the version string is null, it's not an analyzer plugin.
  if (!versionString)
    return false;

  // For now, none of the static analyzer API is considered stable.
  // Versions must match exactly.
  if (strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0)
    return true;

  return false;
}

void ClangCheckerRegistry::warnIncompatible(DiagnosticsEngine *diags,
                                            StringRef pluginPath,
                                            const char *pluginAPIVersion) {
  if (!diags)
    return;
  if (!pluginAPIVersion)
    return;

  diags->Report(diag::warn_incompatible_analyzer_plugin_api)
      << llvm::sys::path::filename(pluginPath);
  diags->Report(diag::note_incompatible_analyzer_plugin_api)
      << CLANG_ANALYZER_API_VERSION_STRING
      << pluginAPIVersion;
}

std::unique_ptr<CheckerManager>
ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
                           ArrayRef<std::string> plugins,
                           DiagnosticsEngine &diags) {
  std::unique_ptr<CheckerManager> checkerMgr(
      new CheckerManager(langOpts, &opts));

  SmallVector<CheckerOptInfo, 8> checkerOpts;
  for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) {
    const std::pair<std::string, bool> &opt = opts.CheckersControlList[i];
    checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second));
  }

  ClangCheckerRegistry allCheckers(plugins, &diags);
  allCheckers.initializeManager(*checkerMgr, checkerOpts);
  allCheckers.validateCheckerOptions(opts, diags);
  checkerMgr->finishedCheckerRegistration();

  for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) {
    if (checkerOpts[i].isUnclaimed()) {
      diags.Report(diag::err_unknown_analyzer_checker)
          << checkerOpts[i].getName();
      diags.Report(diag::note_suggest_disabling_all_checkers);
    }

  }

  return checkerMgr;
}

void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) {
  out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
  out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";

  ClangCheckerRegistry(plugins).printHelp(out);
}
<commit_msg>Refactor: Simplify boolean conditional return statements in lib/StaticAnalyzer/Frontend<commit_after>//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Defines the registration function for the analyzer checkers.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/StaticAnalyzer/Checkers/ClangCheckers.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h"
#include "clang/StaticAnalyzer/Core/CheckerRegistry.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>

using namespace clang;
using namespace ento;
using llvm::sys::DynamicLibrary;

namespace {
class ClangCheckerRegistry : public CheckerRegistry {
  typedef void (*RegisterCheckersFn)(CheckerRegistry &);

  static bool isCompatibleAPIVersion(const char *versionString);
  static void warnIncompatible(DiagnosticsEngine *diags, StringRef pluginPath,
                               const char *pluginAPIVersion);

public:
  ClangCheckerRegistry(ArrayRef<std::string> plugins,
                       DiagnosticsEngine *diags = nullptr);
};

} // end anonymous namespace

ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins,
                                           DiagnosticsEngine *diags) {
  registerBuiltinCheckers(*this);

  for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
       i != e; ++i) {
    // Get access to the plugin.
    std::string err;
    DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
    if (!lib.isValid()) {
      diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err;
      continue;
    }

    // See if it's compatible with this build of clang.
    const char *pluginAPIVersion =
      (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
    if (!isCompatibleAPIVersion(pluginAPIVersion)) {
      warnIncompatible(diags, *i, pluginAPIVersion);
      continue;
    }

    // Register its checkers.
    RegisterCheckersFn registerPluginCheckers =
      (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
                                                      "clang_registerCheckers");
    if (registerPluginCheckers)
      registerPluginCheckers(*this);
  }
}

bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) {
  // If the version string is null, it's not an analyzer plugin.
  if (!versionString)
    return false;

  // For now, none of the static analyzer API is considered stable.
  // Versions must match exactly.
  return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
}

void ClangCheckerRegistry::warnIncompatible(DiagnosticsEngine *diags,
                                            StringRef pluginPath,
                                            const char *pluginAPIVersion) {
  if (!diags)
    return;
  if (!pluginAPIVersion)
    return;

  diags->Report(diag::warn_incompatible_analyzer_plugin_api)
      << llvm::sys::path::filename(pluginPath);
  diags->Report(diag::note_incompatible_analyzer_plugin_api)
      << CLANG_ANALYZER_API_VERSION_STRING
      << pluginAPIVersion;
}

std::unique_ptr<CheckerManager>
ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
                           ArrayRef<std::string> plugins,
                           DiagnosticsEngine &diags) {
  std::unique_ptr<CheckerManager> checkerMgr(
      new CheckerManager(langOpts, &opts));

  SmallVector<CheckerOptInfo, 8> checkerOpts;
  for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) {
    const std::pair<std::string, bool> &opt = opts.CheckersControlList[i];
    checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second));
  }

  ClangCheckerRegistry allCheckers(plugins, &diags);
  allCheckers.initializeManager(*checkerMgr, checkerOpts);
  allCheckers.validateCheckerOptions(opts, diags);
  checkerMgr->finishedCheckerRegistration();

  for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) {
    if (checkerOpts[i].isUnclaimed()) {
      diags.Report(diag::err_unknown_analyzer_checker)
          << checkerOpts[i].getName();
      diags.Report(diag::note_suggest_disabling_all_checkers);
    }

  }

  return checkerMgr;
}

void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) {
  out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
  out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";

  ClangCheckerRegistry(plugins).printHelp(out);
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unistd.h>

using namespace std;

extern "C" {
#include "iniparser.h"
}

char* base_path;
char* tester;
char* vm_name;

int  parse_ini_files(char * ini_instance,char* ini_v_machines,char* conf);
int get_archives(char* source,char* destination,char* username,char* ip);

int main(int argc, char * argv[])
{
	int status ;

	if (argc==2) {
		status = parse_ini_files(argv[1],(char*)"checker.ini",argv[1]);
	}
	return status ;
}

int parse_ini_files(char *ini_instance,char* ini_v_machines,char* conf)
{
	string temp;

	dictionary* instance; //instanta tema
	dictionary* v_machines; //fisier de configurare vms

	char* base_path;
	char* vm_name;
	char* jobs_path;
	char* username;
	char* ip;
	char* job_id;
	char* user_id;
	char* deadline;
	char* upload_time;
	char* penalty;
	char* kernel_msg;
	char* local_ip;
	char* vm_path;
	char* guest_user;
	char* guest_pass;
	char* guest_base_path;
	char* guest_shell_path;
	char* guest_home_in_bash;

	instance = iniparser_load(ini_instance);
	if (instance==NULL) {
		fprintf(stderr, "cannot parse file: %s\n", ini_instance);
		return -1 ;
	}

	v_machines=iniparser_load(ini_v_machines);
	if (v_machines==NULL){
		fprintf(stderr,"cannot parse file: %s\n",ini_v_machines);
		return -1;
	}

//	iniparser_dump(instance, stderr);
//	iniparser_dump(v_machines,stderr);

	//extrag din instanta de tema
	base_path=iniparser_getstring(instance,"Global:BasePath",NULL);
	vm_name=iniparser_getstring(instance,"Global:VMName",NULL);
	job_id=iniparser_getstring(instance,"Global:Job",NULL);
	user_id=iniparser_getstring(instance,"Global:UserId",NULL);
	deadline=iniparser_getstring(instance,"Global:Deadline",NULL);
	upload_time=iniparser_getstring(instance,"Global:UploadTime",NULL);
	penalty=iniparser_getstring(instance,"Global:Penalty",NULL);
	kernel_msg=iniparser_getstring(instance,"Global:KernelMsg",NULL);
	//jobs_path=iniparser_getstring(v_machines,"Global:JobsPath",NULL);
	//username=iniparser_getstring(v_machines,"Global:TesterUsername",NULL);
	ip=iniparser_getstring(instance,"Global:UploadIP",NULL);

	temp=vm_name;

	//extrag din fisierul de masini virtuale
	local_ip=iniparser_getstring(v_machines,"Global:LocalAddress",NULL);
	jobs_path=iniparser_getstring(v_machines,"Global:JobsPath",NULL);
	username=iniparser_getstring(v_machines,"Global:TesterUsername",NULL);
	vm_path=iniparser_getstring(v_machines,(temp+":VMPath").c_str(),NULL);
	guest_user=iniparser_getstring(v_machines,(temp+":GuestUser").c_str(),NULL);
	guest_pass=iniparser_getstring(v_machines,(temp+":GuestPassword").c_str(),NULL);
	guest_base_path=iniparser_getstring(v_machines,(temp+":GuestBasePath").c_str(),NULL);
	guest_shell_path=iniparser_getstring(v_machines,(temp+":GuestShellPath").c_str(),NULL);
//	guest_home_in_bash=iniparser_getstring(v_machines,(temp+"GuestHomeInBash").c_str());

	//get archives
	system((temp+"scp "+username+"@"+ip+":"+base_path+"/"+job_id+"/"+user_id+"/"+upload_time+"file.zip "+jobs_path+"/"+"file.zip").c_str());
	system((temp+"scp "+username+"@"+ip+":"+base_path+"/"+"tests"+"/"+job_id+".zip "+jobs_path+"/"+"tests.zip").c_str());

	//apelez executorul

	temp="bash -c \"";
	system((temp+"./executor "+vm_name+" "+ vm_path+" "+local_ip+" "+guest_user+" "+guest_pass+" "+guest_base_path+" "+guest_shell_path+"\"").c_str());

	//verific deadline + warninguri
	//din jobs_path am job_build si job_run

	//pun pe sistemul de upload rezultatele

	temp="";
	system((temp+"scp "+jobs_path+"/"+"job_build "+username+"@"+ip+":"+base_path+"/"+"checked"+"/"+job_id+"/"+user_id+"/"+upload_time+"/"+"job_build" ).c_str());
	system((temp+"scp "+jobs_path+"/"+"job_run "+username+"@"+ip+":"+base_path+"/"+"checked"+"/"+job_id+"/"+user_id+"/"+upload_time+"/"+"job_run").c_str());

	//pun arhiva si o dezarhivez
	system((temp+"scp "+jobs_path+"/"+"file.zip "+username+"@"+ip+":"+base_path+"/"+"checked"+"/"+job_id+"/"+user_id+"/"+upload_time+"/"+"file.zip" ).c_str());
	system((temp+"ssh "+username+"@"+ip+" "+"\"unzip "+base_path+"uncheked"+"/"+"file.zip"+"\"").c_str());
	system((temp+"ssh "+username+"@"+ip+" "+"\"rm -f "+base_path+"uncheked"+"/"+"file.zip"+"\"").c_str());

	//sterg fisierul de configurare
	system((temp+"ssh "+username+"@"+ip+" "+"\"rm -f "+base_path+"uncheked"+"/"+conf+"\"").c_str());

	iniparser_freedict(instance);
	iniparser_freedict(v_machines);
	return 0 ;
}

/*int get_archives(char* base_path,char* upload_time,char* user_id,char* job_id char* destination,char* username,char* ip)
{
	string temp;

	system((temp+"scp "+base_path+"/"+"file.zip"+" "+username+"@"+ip+":"+destination+"file.zip").c_str());
	system((temp+"scp "+source+"tests.zip"+" "+username+"@"+ip+":"+destination+"tests.zip").c_str());
}*/

<commit_msg>commander: unfinished<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unistd.h>

using namespace std;

extern "C" {
#include "iniparser.h"
}

char* base_path;
char* tester;
char* vm_name;

int  parse_ini_files(char * ini_instance,char* ini_v_machines,char* conf);
int get_archives(char* source,char* destination,char* username,char* ip);

int main(int argc, char * argv[])
{
	int status ;

	if (argc==2) {
		status = parse_ini_files(argv[1],(char*)"checker.ini",argv[1]);
	}
	return status ;
}

int parse_ini_files(char *ini_instance,char* ini_v_machines,char* conf)
{
	string temp;

	dictionary* instance; //instanta tema
	dictionary* v_machines; //fisier de configurare vms

	char* base_path;
	char* vm_name;
	char* jobs_path;
	char* username;
	char* ip;
	char* job_id;
	char* user_id;
	char* deadline;
	char* upload_time;
	char* penalty;
	char* kernel_msg;
	char* local_ip;
	char* vm_path;
	char* guest_user;
	char* guest_pass;
	char* guest_base_path;
	char* guest_shell_path;
	char* guest_home_in_bash;

	instance = iniparser_load(ini_instance);
	if (instance==NULL) {
		fprintf(stderr, "cannot parse file: %s\n", ini_instance);
		return -1 ;
	}

	v_machines=iniparser_load(ini_v_machines);
	if (v_machines==NULL){
		fprintf(stderr,"cannot parse file: %s\n",ini_v_machines);
		return -1;
	}

//	iniparser_dump(instance, stderr);
//	iniparser_dump(v_machines,stderr);

	//extrag din instanta de tema
	base_path=iniparser_getstring(instance,"Global:BasePath",NULL);
	vm_name=iniparser_getstring(instance,"Global:VMName",NULL);
	job_id=iniparser_getstring(instance,"Global:Job",NULL);
	user_id=iniparser_getstring(instance,"Global:UserId",NULL);
	deadline=iniparser_getstring(instance,"Global:Deadline",NULL);
	upload_time=iniparser_getstring(instance,"Global:UploadTime",NULL);
	penalty=iniparser_getstring(instance,"Global:Penalty",NULL);
	kernel_msg=iniparser_getstring(instance,"Global:KernelMsg",NULL);
	//jobs_path=iniparser_getstring(v_machines,"Global:JobsPath",NULL);
	//username=iniparser_getstring(v_machines,"Global:TesterUsername",NULL);
	ip=iniparser_getstring(instance,"Global:UploadIP",NULL);

	temp=vm_name;

	//extrag din fisierul de masini virtuale
	local_ip=iniparser_getstring(v_machines,"Global:LocalAddress",NULL);
	jobs_path=iniparser_getstring(v_machines,"Global:JobsPath",NULL);
	username=iniparser_getstring(v_machines,"Global:TesterUsername",NULL);
	vm_path=iniparser_getstring(v_machines,(temp+":VMPath").c_str(),NULL);
	guest_user=iniparser_getstring(v_machines,(temp+":GuestUser").c_str(),NULL);
	guest_pass=iniparser_getstring(v_machines,(temp+":GuestPassword").c_str(),NULL);
	guest_base_path=iniparser_getstring(v_machines,(temp+":GuestBasePath").c_str(),NULL);
	guest_shell_path=iniparser_getstring(v_machines,(temp+":GuestShellPath").c_str(),NULL);
//	guest_home_in_bash=iniparser_getstring(v_machines,(temp+"GuestHomeInBash").c_str());

	temp="";

	//get archives
	system((temp+"scp "+username+"@"+ip+":"+base_path+"/"+job_id+"/"+user_id+"/"+upload_time+"file.zip "+jobs_path+"/"+"file.zip").c_str());
	system((temp+"scp "+username+"@"+ip+":"+base_path+"/"+"tests"+"/"+job_id+".zip "+jobs_path+"/"+"tests.zip").c_str());

	//apelez executorul

	temp="bash -c \"";
	system((temp+"./executor "+vm_name+" "+ vm_path+" "+local_ip+" "+guest_user+" "+guest_pass+" "+guest_base_path+" "+guest_shell_path+"\"").c_str());

	//verific deadline + warninguri
	//din jobs_path am job_build si job_run

	//pun pe sistemul de upload rezultatele

	temp="";
	system((temp+"scp "+jobs_path+"/"+"job_build "+username+"@"+ip+":"+base_path+"/"+"checked"+"/"+job_id+"/"+user_id+"/"+upload_time+"/"+"job_build" ).c_str());
	system((temp+"scp "+jobs_path+"/"+"job_run "+username+"@"+ip+":"+base_path+"/"+"checked"+"/"+job_id+"/"+user_id+"/"+upload_time+"/"+"job_run").c_str());

	//pun arhiva si o dezarhivez
	system((temp+"scp "+jobs_path+"/"+"file.zip "+username+"@"+ip+":"+base_path+"/"+"checked"+"/"+job_id+"/"+user_id+"/"+upload_time+"/"+"file.zip" ).c_str());
	system((temp+"ssh "+username+"@"+ip+" "+"\"unzip "+base_path+"uncheked"+"/"+"file.zip"+"\"").c_str());
	system((temp+"ssh "+username+"@"+ip+" "+"\"rm -f "+base_path+"uncheked"+"/"+"file.zip"+"\"").c_str());

	//sterg fisierul de configurare
	system((temp+"ssh "+username+"@"+ip+" "+"\"rm -f "+base_path+"uncheked"+"/"+conf+"\"").c_str());

	iniparser_freedict(instance);
	iniparser_freedict(v_machines);
	return 0 ;
}

/*int get_archives(char* base_path,char* upload_time,char* user_id,char* job_id char* destination,char* username,char* ip)
{
	string temp;

	system((temp+"scp "+base_path+"/"+"file.zip"+" "+username+"@"+ip+":"+destination+"file.zip").c_str());
	system((temp+"scp "+source+"tests.zip"+" "+username+"@"+ip+":"+destination+"tests.zip").c_str());
}*/

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewobjectcontactredirector.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <svx/sdr/contact/viewobjectcontactredirector.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        // basic constructor.
        ViewObjectContactRedirector::ViewObjectContactRedirector()
        {
        }

        // The destructor.
        ViewObjectContactRedirector::~ViewObjectContactRedirector()
        {
        }

        void ViewObjectContactRedirector::PaintObject(ViewObjectContact& rOriginal, DisplayInfo& rDisplayInfo)
        {
            rOriginal.PaintObject(rDisplayInfo);
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>INTEGRATION: CWS aw033 (1.3.16); FILE MERGED 2008/05/27 14:49:59 aw 1.3.16.9: #i39532# changes DEV300 m12 resync corrections 2008/05/14 14:01:24 aw 1.3.16.8: RESYNC: (1.4-1.5); FILE MERGED 2008/01/22 12:29:31 aw 1.3.16.7: adaptions and 1st stripping 2007/07/06 13:43:08 aw 1.3.16.6: #i39532# moved from Primitive2DReference to Primitive2DSequence where possible to avoid extra-group primitive creations and deeper hierarchies as necessary 2006/10/19 10:59:17 aw 1.3.16.5: #i39532# primitive 2006/09/26 19:22:43 aw 1.3.16.4: RESYNC: (1.3-1.4); FILE MERGED 2006/08/09 17:12:26 aw 1.3.16.3: #i39532# 2006/06/02 14:17:51 aw 1.3.16.2: #i39532# adaptions to new primitives, error corrections 2006/05/12 12:46:24 aw 1.3.16.1: code changes for primitive support<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewobjectcontactredirector.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <svx/sdr/contact/viewobjectcontactredirector.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
#include <svx/sdr/contact/viewcontact.hxx>

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        // basic constructor.
        ViewObjectContactRedirector::ViewObjectContactRedirector()
        {
        }

        // The destructor.
        ViewObjectContactRedirector::~ViewObjectContactRedirector()
        {
        }

        drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
            const sdr::contact::ViewObjectContact& rOriginal,
            const sdr::contact::DisplayInfo& rDisplayInfo)
        {
            return rOriginal.createPrimitive2DSequence(rDisplayInfo);
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<|endoftext|>


<commit_before>#pragma once

#include <hash_map.hpp>
#include <list.hpp>
#include <kernel/interfaces/device_manager.hpp>

#include "block.hpp"
#include "character.hpp"

namespace device {

struct manager final : public interfaces::device_manager {

    explicit manager();
    void initialize() override;

    void register_device(utils::shared_ptr<block> &dev) override;
    void register_device(utils::shared_ptr<character> &dev) override;
    character *get_character_device(const character::type type, const character::id_t id) override;

private:

    constexpr uint16_t device_hash(const character::type type, const character::id_t id) const {
        return static_cast<uint16_t>(type) << 8 | static_cast<uint16_t>(id);
    }

    utils::hash_map<uint16_t, block *> block_map_;
    utils::hash_map<uint16_t, character *> character_map_;
    utils::list<utils::shared_ptr<block>> block_devices_;
    utils::list<utils::shared_ptr<character>> character_devices_;
};

} // namespace device

<commit_msg>Fix compilation on GCC<commit_after>#pragma once

#include <hash_map.hpp>
#include <list.hpp>
#include <kernel/interfaces/device_manager.hpp>

#include "block.hpp"
#include "character.hpp"

namespace device {

struct manager final : public interfaces::device_manager {

    explicit manager();
    void initialize() override;

    void register_device(utils::shared_ptr<block> &dev) override;
    void register_device(utils::shared_ptr<character> &dev) override;
    character *get_character_device(const character::type type, const character::id_t id) override;

private:

    constexpr static uint16_t device_hash(const character::type type, const character::id_t id) {
        return static_cast<uint16_t>(type) << 8 | static_cast<uint16_t>(id);
    }

    utils::hash_map<uint16_t, block *> block_map_;
    utils::hash_map<uint16_t, character *> character_map_;
    utils::list<utils::shared_ptr<block>> block_devices_;
    utils::list<utils::shared_ptr<character>> character_devices_;
};

} // namespace device

<|endoftext|>


<commit_before>/* @doc Computation of the dynamic aspect for a robot.
   This class will load the description of a robot from a VRML file
   following the OpenHRP syntax. Using ForwardVelocity it is then
   possible specifying the angular velocity and the angular value
   to get the absolute position, and absolute velocity of each
   body separetly. Heavy rewriting from the original source
   of Adrien and Jean-Remy.

   This implantation is an updated based on a mixture between
   the code provided by Jean-Remy and Adrien.

   Copyright (c) 2005-2006,
   @author Olivier Stasse, Ramzi Sellouati, Jean-Remy Chardonnet, Adrien Escande, Abderrahmane Kheddar
   Copyright (c) 2007-2009
   @author Olivier Stasse, Oussama Kannoun, Fumio Kanehiro.
   JRL-Japan, CNRS/AIST

   All rights reserved.

   Please refers to file License.txt for details on the license.

*/

/*! System includes */
#include <iostream>
#include <sstream>
#include <fstream>
#include <string.h>

#include "Debug.h"

/*! Local library includes. */
#include "MatrixAbstractLayer/MatrixAbstractLayer.h"
#include "dynamicsJRLJapan/DynamicBody.h"
#include "DynMultiBodyPrivate.h"
#include "robotDynamics/jrlBody.h"

#include "fileReader.h"

using namespace dynamicsJRLJapan;

void DynMultiBodyPrivate::BackwardDynamics(DynamicBodyPrivate & CurrentBody )
{
  MAL_S3x3_MATRIX(,double) aRt;

  MAL_S3x3_MATRIX(,double) currentBodyR;
  currentBodyR = MAL_S3x3_RET_TRANSPOSE(CurrentBody.R);

  MAL_S3_VECTOR(,double) lg;
  lg(0) = 0.0;
  lg(1) = 0.0;
  lg(2) = -9.81;

  /* Compute the torque
   * with eq. (7.147) Spong RMC p. 277
   *
   *
   */
  MAL_S3_VECTOR(,double) firstterm,
    sndterm, thirdterm, fifthterm,tmp;
  // Do not fourth term because it is the angular acceleration.

  /* Constant part */
  tmp = CurrentBody.dv_c - lg;
  tmp = MAL_S3x3_RET_A_by_B(currentBodyR,tmp);
  CurrentBody.m_Force =  tmp * CurrentBody.mass();

  /* 2nd term : -f_i x r_{i,ci} */
  vector3d lc = CurrentBody.localCenterOfMass();
  MAL_S3_VECTOR_CROSS_PRODUCT(sndterm,CurrentBody.m_Force, lc);

  /* 5th term : w_i x (I_i w_i)*/
  MAL_S3x3_MATRIX(,double) lI = CurrentBody.getInertie();
  tmp = MAL_S3x3_RET_A_by_B(currentBodyR,CurrentBody.w);
  tmp = MAL_S3x3_RET_A_by_B(lI,tmp);
  MAL_S3_VECTOR_CROSS_PRODUCT(fifthterm,CurrentBody.w,tmp);

  CurrentBody.m_Torque =  MAL_S3x3_RET_A_by_B(currentBodyR,CurrentBody.dw) + fifthterm -sndterm;

  /* Compute with the force
   * eq. (7.146) Spong RMC p. 277
   * fi = R^i_{i+1} * f_{i+1} + m_i * a_{c,i} - m_i * g_i
   * g_i is the gravity express in the i reference frame.
   */

  int IndexChild = CurrentBody.child;
  //cout << "Body : " << CurrentBody.getName() << endl;
  while(IndexChild!=-1)
    {
      DynamicBodyPrivate *Child = m_listOfBodies[IndexChild];
      //cout << "Child Bodies : " << Child->getName() << endl;
      aRt = Child->Riip1;
      //cout << "Riip1: " << aRt << endl;
      // /* Force computation. */
      //// Other immediate child are sisters of the other immediate childs.
      //cout << "Force: " << Child->m_Force << endl;
      tmp= MAL_S3x3_RET_A_by_B(aRt, Child->m_Force);
      CurrentBody.m_Force += tmp;

      /* Torque computation. */
      /* 1st term : R^i_{i+1} t_{i+1} */
      firstterm = MAL_S3x3_RET_A_by_B(aRt, Child->m_Torque);

      /* 3rd term : R_i_{i+1} f_{i+1} */
      MAL_S3_VECTOR_CROSS_PRODUCT(thirdterm,tmp, CurrentBody.w_c);

      CurrentBody.m_Torque += firstterm + thirdterm;

      /* Body selection. */
      IndexChild = m_listOfBodies[IndexChild]->sister;
      if (IndexChild!=-1)
	Child=m_listOfBodies[IndexChild];
    }

  // Update the vector related to the computed quantities.
  for(unsigned int i=0;i<m_StateVectorToJoint.size();i++)
    {
      unsigned int StateRankComputed=false;

      JointPrivate * aJoint = (JointPrivate *)m_JointVector[m_StateVectorToJoint[i]];
      if (aJoint!=0)
        {
	  DynamicBodyPrivate *aDB = (DynamicBodyPrivate *) aJoint->linkedBody();
	  if (aDB!=0)
            {
	      StateRankComputed = true;
	      for(unsigned int k=0;k<3;k++)
                {
		  m_Forces(i,k)=aDB->m_Force[k];
		  m_Torques(i,k) = aDB->m_Torque[k];
                }

            }
        }

      if (!StateRankComputed)
        {
	  for(unsigned int k=0;k<3;k++)
            {
	      m_Forces(i,k)=0.0;
	      m_Torques(i,k)=0.0;
            }
        }
    }
}
<commit_msg>Fix force and torque computation with the latest modifications.<commit_after>/* @doc Computation of the dynamic aspect for a robot.
   This class will load the description of a robot from a VRML file
   following the OpenHRP syntax. Using ForwardVelocity it is then
   possible specifying the angular velocity and the angular value
   to get the absolute position, and absolute velocity of each
   body separetly. Heavy rewriting from the original source
   of Adrien and Jean-Remy.

   This implantation is an updated based on a mixture between
   the code provided by Jean-Remy and Adrien.

   Copyright (c) 2005-2006,
   @author Olivier Stasse, Ramzi Sellouati, Jean-Remy Chardonnet, Adrien Escande, Abderrahmane Kheddar
   Copyright (c) 2007-2009
   @author Olivier Stasse, Oussama Kannoun, Fumio Kanehiro.
   JRL-Japan, CNRS/AIST

   All rights reserved.

   Please refers to file License.txt for details on the license.

*/

/*! System includes */
#include <iostream>
#include <sstream>
#include <fstream>
#include <string.h>

#include "Debug.h"

/*! Local library includes. */
#include "MatrixAbstractLayer/MatrixAbstractLayer.h"
#include "dynamicsJRLJapan/DynamicBody.h"
#include "DynMultiBodyPrivate.h"
#include "robotDynamics/jrlBody.h"

#include "fileReader.h"

using namespace dynamicsJRLJapan;

void DynMultiBodyPrivate::BackwardDynamics(DynamicBodyPrivate & CurrentBody )
{
  ODEBUG("=====================");
  ODEBUG("Body : " << CurrentBody.getName());
  MAL_S3x3_MATRIX(,double) aRt;

  MAL_S3x3_MATRIX(,double) currentBodyR;
  currentBodyR = MAL_S3x3_RET_TRANSPOSE(CurrentBody.R);

  MAL_S3_VECTOR(,double) lg;
  lg(0) = 0.0;
  lg(1) = 0.0;
  lg(2) = -9.81;

  /* Compute the torque
   * with eq. (7.147) Spong RMC p. 277
   *
   *
   */
  MAL_S3_VECTOR(,double) firstterm,
    sndterm, thirdterm, fifthterm,tmp,tmp2;
  // There is no fourth term because it is the angular acceleration.

  /* Constant part */
  tmp = CurrentBody.dv_c - lg;
  CurrentBody.m_Force =  tmp * CurrentBody.mass();
  ODEBUG("tmp: " << tmp << " tmp2: " << tmp2 );
  /* 2nd term : -f_i x r_{i,ci} */
  vector3d lc = CurrentBody.localCenterOfMass();
  MAL_S3_VECTOR_CROSS_PRODUCT(sndterm,CurrentBody.m_Force, lc);

  /* 5th term : w_i x (I_i w_i)*/
  MAL_S3x3_MATRIX(,double) lI = CurrentBody.getInertie();
  tmp = MAL_S3x3_RET_A_by_B(lI,CurrentBody.w);
  MAL_S3_VECTOR_CROSS_PRODUCT(fifthterm,CurrentBody.w,tmp);

  CurrentBody.m_Torque =  CurrentBody.dw + fifthterm -sndterm;

  /* Compute with the force
   * eq. (7.146) Spong RMC p. 277
   * fi = R^i_{i+1} * f_{i+1} + m_i * a_{c,i} - m_i * g_i
   * g_i is the gravity express in the i reference frame.
   */

  int IndexChild = CurrentBody.child;
  ODEBUG( " Force from Acceleration + gravity: " << CurrentBody.m_Force <<
	   " Acceleration: " << CurrentBody.dv_c );
  while(IndexChild!=-1)
    {
      DynamicBodyPrivate *Child = m_listOfBodies[IndexChild];
      ODEBUG( "Child Bodies : " << Child->getName() );
      aRt = Child->Riip1;
      ODEBUG( "Riip1: " << aRt );
      // /* Force computation. */
      //// Other immediate child are sisters of the other immediate childs.
      ODEBUG("Child Force: " << Child->m_Force );
      tmp= MAL_S3x3_RET_A_by_B(aRt, Child->m_Force);
      ODEBUG("Riip1 * fi+1: " << tmp );
      CurrentBody.m_Force += tmp;

      /* Torque computation. */
      /* 1st term : R^i_{i+1} t_{i+1} */
      firstterm = MAL_S3x3_RET_A_by_B(aRt, Child->m_Torque);

      /* 3rd term : R_i_{i+1} f_{i+1} */
      vector3d rip1ci = Child->p - CurrentBody.w_c;
      ODEBUG( "rip1ci:" << rip1ci);
      MAL_S3_VECTOR_CROSS_PRODUCT(thirdterm,tmp, rip1ci);

      CurrentBody.m_Torque += firstterm + thirdterm;

      /* Body selection. */
      IndexChild = m_listOfBodies[IndexChild]->sister;
      if (IndexChild!=-1)
	Child=m_listOfBodies[IndexChild];
    }
  ODEBUG("Force for Body " << CurrentBody.getName() << " " << CurrentBody.m_Force );
  ODEBUG("=====================");
  // Update the vector related to the computed quantities.
  for(unsigned int i=0;i<m_StateVectorToJoint.size();i++)
    {
      unsigned int StateRankComputed=false;

      JointPrivate * aJoint = (JointPrivate *)m_JointVector[m_StateVectorToJoint[i]];
      if (aJoint!=0)
        {
	  DynamicBodyPrivate *aDB = (DynamicBodyPrivate *) aJoint->linkedBody();
	  if (aDB!=0)
            {
	      StateRankComputed = true;
	      for(unsigned int k=0;k<3;k++)
                {
		  m_Forces(i,k)=aDB->m_Force[k];
		  m_Torques(i,k) = aDB->m_Torque[k];
                }

            }
        }

      if (!StateRankComputed)
        {
	  for(unsigned int k=0;k<3;k++)
            {
	      m_Forces(i,k)=0.0;
	      m_Torques(i,k)=0.0;
            }
        }
    }
}
<|endoftext|>


<commit_before>//
// C++ Implementation: requesttask
//
// Description:
//
//
// Author: SUSE AG  (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include "gwfield.h"
#include "request.h"
#include "response.h"

#include "requesttask.h"

RequestTask::RequestTask( Task * parent )
: Task( parent )
{
}

bool RequestTask::forMe( Transfer * transfer ) const
{
	// see if we can down-cast transfer to a Response
	Response * theResponse = dynamic_cast<Response *>(transfer);
	return (theResponse && theResponse->transactionId() == m_transactionId );
}

void RequestTask::setTransfer( Transfer * transfer )
{
	m_transactionId = static_cast<Request *>(transfer)->transactionId();
	Task::setTransfer( transfer );
}

bool RequestTask::take( Transfer * transfer )
{
	if ( forMe( transfer ) )
	{
		qDebug( "RequestTask::take() - Default take() Accepting transaction ack, taking no further action" );
		return true;
	}
	else
		return false;
}

#include "requesttask.moc"
<commit_msg>Make checking for a good return code the default condition for success, for request tasks.  May need to revert if the server doesn't always respond.<commit_after>//
// C++ Implementation: requesttask
//
// Description:
//
//
// Author: SUSE AG  (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include "gwfield.h"
#include "request.h"
#include "response.h"

#include "requesttask.h"

RequestTask::RequestTask( Task * parent )
: Task( parent )
{
}

bool RequestTask::forMe( Transfer * transfer ) const
{
	// see if we can down-cast transfer to a Response
	Response * theResponse = dynamic_cast<Response *>(transfer);
	return (theResponse && theResponse->transactionId() == m_transactionId );
}

void RequestTask::setTransfer( Transfer * transfer )
{
	m_transactionId = static_cast<Request *>(transfer)->transactionId();
	Task::setTransfer( transfer );
}

bool RequestTask::take( Transfer * transfer )
{
	if ( forMe( transfer ) )
	{
		qDebug( "RequestTask::take() - Default take() Accepting transaction ack, taking no further action" );
		Response * response = dynamic_cast<Response *>( transfer );
		Field::FieldList responseFields = response->fields();
		Field::SingleField * resultCodeField = responseFields.findSingleField( NM_A_SZ_RESULT_CODE );
		int resultCode = resultCodeField->value().toInt();
		if ( resultCode == GroupWise::None )
			setSuccess();
		else
			setError( resultCode );
		return true;
	}
	else
		return false;
}

#include "requesttask.moc"
<|endoftext|>


<commit_before>#include "pyclast.h"
#include <pybind11/stl.h>
#include <clang/AST/AST.h>
#include <clang/AST/ASTTypeTraits.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/ASTMatchers/ASTMatchersInternal.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include "clang/ASTMatchers/Dynamic/Parser.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Tooling/Tooling.h"

namespace py = pybind11;
using namespace clang::ast_matchers;
using namespace clang::ast_matchers::internal;
using namespace clang::ast_matchers::dynamic;
using namespace clang::tooling;

// FIXME: This is a temporary placeholder until a better solution can be found
DynTypedMatcher parseMatcherExpression(const std::string& code)
{
  Diagnostics Err;
  auto val = Parser::parseMatcherExpression(code, &Err);
  if(false == val.hasValue()) {
    throw std::logic_error("parse failed");
  }
  return val.getValue();
}

void matchString(const std::string& code, MatchFinder& finder,
                 const std::string& compileArgs = "-std=c++11",
                 const std::string& filename = "input.cpp")
{
    const FileContentMappings &VirtualMappedFiles = FileContentMappings();
    std::unique_ptr<FrontendActionFactory> Factory(
        newFrontendActionFactory(&finder));
    std::vector<std::string> args = {compileArgs, "-frtti", "-fexceptions",
                                     "-target", "i386-unknown-unknown"};
    runToolOnCodeWithArgs(
        Factory->create(), code, args, filename, "clang-tool",
        std::make_shared<clang::PCHContainerOperations>(),
        VirtualMappedFiles);
}

void install_wrappers(pybind11::module& m)
{
    m.def("parseMatcherExpression", parseMatcherExpression);
    m.def("matchString", matchString);
}

<commit_msg>bugfix for clang 3.8 call to runToolOnCodeWithArgs<commit_after>#include "pyclast.h"
#include <pybind11/stl.h>
#include <clang/AST/AST.h>
#include <clang/AST/ASTTypeTraits.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/ASTMatchers/ASTMatchersInternal.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include "clang/ASTMatchers/Dynamic/Parser.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Tooling/Tooling.h"

namespace py = pybind11;
using namespace clang::ast_matchers;
using namespace clang::ast_matchers::internal;
using namespace clang::ast_matchers::dynamic;
using namespace clang::tooling;

// FIXME: This is a temporary placeholder until a better solution can be found
DynTypedMatcher parseMatcherExpression(const std::string& code)
{
  Diagnostics Err;
  auto val = Parser::parseMatcherExpression(code, &Err);
  if(false == val.hasValue()) {
    throw std::logic_error("parse failed");
  }
  return val.getValue();
}

void matchString(const std::string& code, MatchFinder& finder,
                 const std::string& compileArgs = "-std=c++11",
                 const std::string& filename = "input.cpp")
{
    const FileContentMappings &VirtualMappedFiles = FileContentMappings();
    std::unique_ptr<FrontendActionFactory> Factory(
        newFrontendActionFactory(&finder));
    std::vector<std::string> args = {compileArgs, "-frtti", "-fexceptions",
                                     "-target", "i386-unknown-unknown"};
    runToolOnCodeWithArgs(
        Factory->create(), code, args, filename,
#if __clang_minor__ > 8
	"clang-tool",
#endif
        std::make_shared<clang::PCHContainerOperations>(),
        VirtualMappedFiles);
}

void install_wrappers(pybind11::module& m)
{
    m.def("parseMatcherExpression", parseMatcherExpression);
    m.def("matchString", matchString);
}

<|endoftext|>


<commit_before>#include <QApplication>
#include <QDesktopServices>
#include <QUrl>
#include <QDir>
#include <QProcess>
#include <QMainWindow>
#include <QSettings>
#include <QTranslator>
#include "crash-reporter-window.h"
#include "ui_crash-reporter-window.h"

QString savePath(const QString &file, bool exists = false)
{
	#ifdef TEST
		Q_UNUSED(exists);
		return QDir::toNativeSeparators(QDir::currentPath()+"/tests/resources/"+file);
	#else
		const QString &check = exists ? file : "settings.ini";
		if (QFile(QDir::toNativeSeparators(qApp->applicationDirPath()+"/"+check)).exists())
		{ return QDir::toNativeSeparators(qApp->applicationDirPath()+"/"+file); }
		if (QFile(QDir::toNativeSeparators(QDir::currentPath()+"/"+check)).exists())
		{ return QDir::toNativeSeparators(QDir::currentPath()+"/"+file); }
		if (QFile(QDir::toNativeSeparators(QDir::homePath()+"/Grabber/"+check)).exists())
		{ return QDir::toNativeSeparators(QDir::homePath()+"/Grabber/"+file); }
		#ifdef __linux__
			if (QFile(QDir::toNativeSeparators(QDir::homePath()+"/.Grabber/"+check)).exists())
			{ return QDir::toNativeSeparators(QDir::homePath()+"/.Grabber/"+file); }
		#endif
		return QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)+"/"+file);
	#endif
}

CrashReporterWindow::CrashReporterWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::CrashReporterWindow), m_restart(false)
{
	QSettings settings(savePath("settings.ini"), QSettings::IniFormat);

	// Translate UI
	const QString lang = settings.value("language", "English").toString();
	const QLocale locale = QLocale(lang);
	QLocale::setDefault(locale);
	auto *translator = new QTranslator(this);
	if (translator->load("crashreporter/"+lang))
	{
		qApp->installTranslator(translator);
	}

	// Setup UI with correct fields value
	ui->setupUi(this);
	ui->lineSettings->setText(savePath("settings.ini"));
	ui->lineLog->setText(savePath("main.log"));
	QFile f(savePath("lastdump"));
	if (f.exists())
	{
		if (f.open(QFile::ReadOnly))
		{
			ui->lineDump->setText(f.readAll());
			f.close();
		}
	}
}

CrashReporterWindow::~CrashReporterWindow()
{
	delete ui;
}

void CrashReporterWindow::restart()
{
	m_restart = true;
	sendCrashReport();
}

void CrashReporterWindow::sendCrashReport()
{
	if (ui->checkSend->isChecked())
	{
		QDesktopServices::openUrl(QUrl(QString(PROJECT_GITHUB_URL) + "/issues/new?labels[]=crash"));
	}

	finished();
}

void CrashReporterWindow::finished()
{
	if (m_restart && QFile::exists("Grabber.exe"))
	{
		QProcess::startDetached("\"Grabber.exe\"");
	}

	close();
}
<commit_msg>Add missing include in CrashReporter<commit_after>#include <QApplication>
#include <QDesktopServices>
#include <QUrl>
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QMainWindow>
#include <QSettings>
#include <QTranslator>
#include "crash-reporter-window.h"
#include "ui_crash-reporter-window.h"

QString savePath(const QString &file, bool exists = false)
{
	#ifdef TEST
		Q_UNUSED(exists);
		return QDir::toNativeSeparators(QDir::currentPath()+"/tests/resources/"+file);
	#else
		const QString &check = exists ? file : "settings.ini";
		if (QFile(QDir::toNativeSeparators(qApp->applicationDirPath()+"/"+check)).exists())
		{ return QDir::toNativeSeparators(qApp->applicationDirPath()+"/"+file); }
		if (QFile(QDir::toNativeSeparators(QDir::currentPath()+"/"+check)).exists())
		{ return QDir::toNativeSeparators(QDir::currentPath()+"/"+file); }
		if (QFile(QDir::toNativeSeparators(QDir::homePath()+"/Grabber/"+check)).exists())
		{ return QDir::toNativeSeparators(QDir::homePath()+"/Grabber/"+file); }
		#ifdef __linux__
			if (QFile(QDir::toNativeSeparators(QDir::homePath()+"/.Grabber/"+check)).exists())
			{ return QDir::toNativeSeparators(QDir::homePath()+"/.Grabber/"+file); }
		#endif
		return QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)+"/"+file);
	#endif
}

CrashReporterWindow::CrashReporterWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::CrashReporterWindow), m_restart(false)
{
	QSettings settings(savePath("settings.ini"), QSettings::IniFormat);

	// Translate UI
	const QString lang = settings.value("language", "English").toString();
	const QLocale locale = QLocale(lang);
	QLocale::setDefault(locale);
	auto *translator = new QTranslator(this);
	if (translator->load("crashreporter/"+lang))
	{
		qApp->installTranslator(translator);
	}

	// Setup UI with correct fields value
	ui->setupUi(this);
	ui->lineSettings->setText(savePath("settings.ini"));
	ui->lineLog->setText(savePath("main.log"));
	QFile f(savePath("lastdump"));
	if (f.exists())
	{
		if (f.open(QFile::ReadOnly))
		{
			ui->lineDump->setText(f.readAll());
			f.close();
		}
	}
}

CrashReporterWindow::~CrashReporterWindow()
{
	delete ui;
}

void CrashReporterWindow::restart()
{
	m_restart = true;
	sendCrashReport();
}

void CrashReporterWindow::sendCrashReport()
{
	if (ui->checkSend->isChecked())
	{
		QDesktopServices::openUrl(QUrl(QString(PROJECT_GITHUB_URL) + "/issues/new?labels[]=crash"));
	}

	finished();
}

void CrashReporterWindow::finished()
{
	if (m_restart && QFile::exists("Grabber.exe"))
	{
		QProcess::startDetached("\"Grabber.exe\"");
	}

	close();
}
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * Copyright (C) 2002-2022 Németh László
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <ctype.h>

#include "../hunspell/csutil.hxx"
#include "textparser.hxx"

#include <algorithm>

#ifndef W32
using namespace std;
#endif

// ISO-8859-1 HTML character entities

static const char* LATIN1[] = {
    "À", "Ã", "Å",  "Æ",  "È", "Ê",
    "Ì", "Ï",   "Ð",    "Ñ", "Ò", "Ø",
    "Ù", "Þ",  "à", "ã", "å",  "æ",
    "è", "ê",  "ì", "ï",   "ð",    "ñ",
    "ò", "ø", "ù", "þ",  "ÿ"};

#define LATIN1_LEN (sizeof(LATIN1) / sizeof(char*))

#define ENTITY_APOS "'"
#define UTF8_APOS "\xe2\x80\x99"
#define APOSTROPHE "'"

TextParser::TextParser(const char* wordchars) {
  init(wordchars);
}

TextParser::TextParser(const w_char* wordchars, int len) {
  init(wordchars, len);
}

TextParser::~TextParser() {}

int TextParser::is_wordchar(const char* w) {
  if (*w == '\0')
    return 0;
  if (utf8) {
    unsigned short idx;
    u8_u16(wc, w, true);
    if (wc.empty())
        return 0;
    idx = (wc[0].h << 8) + wc[0].l;
    return (unicodeisalpha(idx) ||
            (wordchars_utf16 &&
             std::binary_search(wordchars_utf16, wordchars_utf16 + wclen, wc[0])));
  } else {
    return wordcharacters[(*w + 256) % 256];
  }
}

const char* TextParser::get_latin1(const char* s) {
  if (s[0] == '&') {
    unsigned int i = 0;
    while ((i < LATIN1_LEN) && strncmp(LATIN1[i], s, strlen(LATIN1[i])))
      i++;
    if (i != LATIN1_LEN)
      return LATIN1[i];
  }
  return NULL;
}

void TextParser::init(const char* wordchars) {
  actual = 0;
  head = 0;
  token = 0;
  state = 0;
  utf8 = 0;
  checkurl = 0;
  wordchars_utf16 = NULL;
  wclen = 0;
  wordcharacters.resize(256, 0);
  if (!wordchars)
    wordchars = "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM";
  for (unsigned int j = 0; j < strlen(wordchars); ++j) {
    wordcharacters[(wordchars[j] + 256) % 256] = 1;
  }
}

void TextParser::init(const w_char* wc, int len) {
  actual = 0;
  head = 0;
  token = 0;
  state = 0;
  utf8 = 1;
  checkurl = 0;
  wordchars_utf16 = wc;
  wclen = len;
}

int TextParser::next_char(const char* ln, size_t* pos) {
  if (*(ln + *pos) == '\0')
    return 1;
  if (utf8) {
    if (*(ln + *pos) >> 7) {
      // jump to next UTF-8 character
      for ((*pos)++; (*(ln + *pos) & 0xc0) == 0x80; (*pos)++)
        ;
    } else {
      (*pos)++;
    }
  } else
    (*pos)++;
  return 0;
}

void TextParser::put_line(const char* word) {
  actual = (actual + 1) % MAXPREVLINE;
  line[actual].assign(word);
  token = 0;
  head = 0;
  check_urls();
}

std::string TextParser::get_prevline(int n) const {
  return line[(actual + MAXPREVLINE - n) % MAXPREVLINE];
}

std::string TextParser::get_line() const {
  return get_prevline(0);
}

bool TextParser::next_token(std::string &t) {
  const char* latin1;

  for (;;) {
    switch (state) {
      case 0:  // non word chars
        if (is_wordchar(line[actual].c_str() + head)) {
          state = 1;
          token = head;
        } else if ((latin1 = get_latin1(line[actual].c_str() + head))) {
          state = 1;
          token = head;
          head += strlen(latin1);
        }
        break;
      case 1:  // wordchar
        if ((latin1 = get_latin1(line[actual].c_str() + head))) {
          head += strlen(latin1);
        } else if ((is_wordchar(APOSTROPHE) ||
                    (is_utf8() && is_wordchar(UTF8_APOS))) &&
                   !line[actual].empty() && line[actual][head] == '\'' &&
                   is_wordchar(line[actual].c_str() + head + 1)) {
          head++;
        } else if (is_utf8() &&
                   is_wordchar(APOSTROPHE) &&  // add Unicode apostrophe
                                                      // to the WORDCHARS, if
                                                      // needed
                   strncmp(line[actual].c_str() + head, UTF8_APOS, strlen(UTF8_APOS)) ==
                       0 &&
                   is_wordchar(line[actual].c_str() + head + strlen(UTF8_APOS))) {
          head += strlen(UTF8_APOS) - 1;
        } else if (!is_wordchar(line[actual].c_str() + head)) {
          state = 0;
          if (alloc_token(token, &head, t))
            return true;
        }
        break;
    }
    if (next_char(line[actual].c_str(), &head))
      return false;
  }
}

size_t TextParser::get_tokenpos() {
  return token;
}

int TextParser::change_token(const char* word) {
  if (word) {
    std::string remainder(line[actual].substr(head));
    line[actual].resize(token);
    line[actual].append(word);
    line[actual].append(remainder);
    head = token;
    return 1;
  }
  return 0;
}

std::string TextParser::get_word(const std::string &tok) {
  return tok;
}

void TextParser::check_urls() {
  urlline.resize(line[actual].size() + 1);
  int url_state = 0;
  size_t url_head = 0;
  size_t url_token = 0;
  int url = 0;
  for (;;) {
    switch (url_state) {
      case 0:  // non word chars
        if (is_wordchar(line[actual].c_str() + url_head)) {
          url_state = 1;
          url_token = url_head;
          // Unix path
        } else if (line[actual][url_head] == '/') {
          url_state = 1;
          url_token = url_head;
          url = 1;
        }
        break;
      case 1:  // wordchar
        char ch = line[actual][url_head];
        // e-mail address
        if ((ch == '@') ||
            // MS-DOS, Windows path
            (strncmp(line[actual].c_str() + url_head, ":\\", 2) == 0) ||
            // URL
            (strncmp(line[actual].c_str() + url_head, "://", 3) == 0)) {
          url = 1;
        } else if (!(is_wordchar(line[actual].c_str() + url_head) || (ch == '-') ||
                     (ch == '_') || (ch == '\\') || (ch == '.') ||
                     (ch == ':') || (ch == '/') || (ch == '~') || (ch == '%') ||
                     (ch == '*') || (ch == '$') || (ch == '[') || (ch == ']') ||
                     (ch == '?') || (ch == '!') ||
                     ((ch >= '0') && (ch <= '9')))) {
          url_state = 0;
          if (url == 1) {
            for (size_t i = url_token; i < url_head; ++i) {
              urlline[i] = true;
            }
          }
          url = 0;
        }
        break;
    }
    urlline[url_head] = false;
    if (next_char(line[actual].c_str(), &url_head))
      return;
  }
}

int TextParser::get_url(size_t token_pos, size_t* hd) {
  for (size_t i = *hd; i < line[actual].size() && urlline[i]; i++, (*hd)++)
    ;
  return checkurl ? 0 : urlline[token_pos];
}

void TextParser::set_url_checking(int check) {
  checkurl = check;
}

bool TextParser::alloc_token(size_t tokn, size_t* hd, std::string& t) {
  size_t url_head = *hd;
  if (get_url(tokn, &url_head))
    return false;
  t = line[actual].substr(tokn, *hd - tokn);
  // remove colon for Finnish and Swedish language
  if (!t.empty() && t[t.size() - 1] == ':') {
    t.resize(t.size() - 1);
    if (t.empty()) {
      return false;
    }
  }
  return true;
}
<commit_msg>improve #630 test case from 0m0.723s -> 0m0.448s (#787) (#788)<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * Copyright (C) 2002-2022 Németh László
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <ctype.h>

#include "../hunspell/csutil.hxx"
#include "textparser.hxx"

#include <algorithm>

#ifndef W32
using namespace std;
#endif

// ISO-8859-1 HTML character entities

static const char* LATIN1[] = {
    "À", "Ã", "Å",  "Æ",  "È", "Ê",
    "Ì", "Ï",   "Ð",    "Ñ", "Ò", "Ø",
    "Ù", "Þ",  "à", "ã", "å",  "æ",
    "è", "ê",  "ì", "ï",   "ð",    "ñ",
    "ò", "ø", "ù", "þ",  "ÿ"};

#define LATIN1_LEN (sizeof(LATIN1) / sizeof(char*))

#define ENTITY_APOS "'"
#define UTF8_APOS "\xe2\x80\x99"
#define APOSTROPHE "'"

TextParser::TextParser(const char* wordchars) {
  init(wordchars);
}

TextParser::TextParser(const w_char* wordchars, int len) {
  init(wordchars, len);
}

TextParser::~TextParser() {}

int TextParser::is_wordchar(const char* w) {
  if (*w == '\0')
    return 0;
  size_t cache_index = (*w + 256) % 256;
  if (utf8) {
    const bool use_cache = cache_index < 0x80;
    if (use_cache)
      return wordcharacters[cache_index];
    if (u8_u16(wc, w, true) < 1)
        return 0;
    unsigned short idx = (wc[0].h << 8) + wc[0].l;
    return unicodeisalpha(idx) ||
           (wordchars_utf16 &&
            std::binary_search(wordchars_utf16, wordchars_utf16 + wclen, wc[0]));
  } else {
    return wordcharacters[cache_index];
  }
}

const char* TextParser::get_latin1(const char* s) {
  if (s[0] == '&') {
    unsigned int i = 0;
    while ((i < LATIN1_LEN) && strncmp(LATIN1[i], s, strlen(LATIN1[i])))
      i++;
    if (i != LATIN1_LEN)
      return LATIN1[i];
  }
  return NULL;
}

void TextParser::init(const char* wordchars) {
  actual = 0;
  head = 0;
  token = 0;
  state = 0;
  utf8 = 0;
  checkurl = 0;
  wordchars_utf16 = NULL;
  wclen = 0;
  wordcharacters.resize(256, 0);
  if (!wordchars)
    wordchars = "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM";
  for (unsigned int j = 0; j < strlen(wordchars); ++j) {
    wordcharacters[(wordchars[j] + 256) % 256] = 1;
  }
}

void TextParser::init(const w_char* wc_utf8, int len) {
  actual = 0;
  head = 0;
  token = 0;
  state = 0;
  utf8 = 1;
  checkurl = 0;
  wordchars_utf16 = wc_utf8;
  wclen = len;

  // build a cache for the simple cases
  wordcharacters.resize(0x80);
  w_char wc2;
  wc2.h = 0;
  for (unsigned char idx = 0; idx < 0x80; ++idx) {
    wc2.l = idx;
    int cache = unicodeisalpha(idx) ||
                (wordchars_utf16 &&
                 std::binary_search(wordchars_utf16, wordchars_utf16 + wclen, wc2));
    wordcharacters[idx] = cache;
  }
}

int TextParser::next_char(const char* ln, size_t* pos) {
  if (*(ln + *pos) == '\0')
    return 1;
  if (utf8) {
    if (*(ln + *pos) >> 7) {
      // jump to next UTF-8 character
      for ((*pos)++; (*(ln + *pos) & 0xc0) == 0x80; (*pos)++)
        ;
    } else {
      (*pos)++;
    }
  } else
    (*pos)++;
  return 0;
}

void TextParser::put_line(const char* word) {
  actual = (actual + 1) % MAXPREVLINE;
  line[actual].assign(word);
  token = 0;
  head = 0;
  check_urls();
}

std::string TextParser::get_prevline(int n) const {
  return line[(actual + MAXPREVLINE - n) % MAXPREVLINE];
}

std::string TextParser::get_line() const {
  return get_prevline(0);
}

bool TextParser::next_token(std::string &t) {
  const char* latin1;

  for (;;) {
    switch (state) {
      case 0:  // non word chars
        if (is_wordchar(line[actual].c_str() + head)) {
          state = 1;
          token = head;
        } else if ((latin1 = get_latin1(line[actual].c_str() + head))) {
          state = 1;
          token = head;
          head += strlen(latin1);
        }
        break;
      case 1:  // wordchar
        if ((latin1 = get_latin1(line[actual].c_str() + head))) {
          head += strlen(latin1);
        } else if ((is_wordchar(APOSTROPHE) ||
                    (is_utf8() && is_wordchar(UTF8_APOS))) &&
                   !line[actual].empty() && line[actual][head] == '\'' &&
                   is_wordchar(line[actual].c_str() + head + 1)) {
          head++;
        } else if (is_utf8() &&
                   is_wordchar(APOSTROPHE) &&  // add Unicode apostrophe
                                                      // to the WORDCHARS, if
                                                      // needed
                   strncmp(line[actual].c_str() + head, UTF8_APOS, strlen(UTF8_APOS)) ==
                       0 &&
                   is_wordchar(line[actual].c_str() + head + strlen(UTF8_APOS))) {
          head += strlen(UTF8_APOS) - 1;
        } else if (!is_wordchar(line[actual].c_str() + head)) {
          state = 0;
          if (alloc_token(token, &head, t))
            return true;
        }
        break;
    }
    if (next_char(line[actual].c_str(), &head))
      return false;
  }
}

size_t TextParser::get_tokenpos() {
  return token;
}

int TextParser::change_token(const char* word) {
  if (word) {
    std::string remainder(line[actual].substr(head));
    line[actual].resize(token);
    line[actual].append(word);
    line[actual].append(remainder);
    head = token;
    return 1;
  }
  return 0;
}

std::string TextParser::get_word(const std::string &tok) {
  return tok;
}

void TextParser::check_urls() {
  urlline.resize(line[actual].size() + 1);
  int url_state = 0;
  size_t url_head = 0;
  size_t url_token = 0;
  int url = 0;
  for (;;) {
    switch (url_state) {
      case 0:  // non word chars
        if (is_wordchar(line[actual].c_str() + url_head)) {
          url_state = 1;
          url_token = url_head;
          // Unix path
        } else if (line[actual][url_head] == '/') {
          url_state = 1;
          url_token = url_head;
          url = 1;
        }
        break;
      case 1:  // wordchar
        char ch = line[actual][url_head];
        // e-mail address
        if ((ch == '@') ||
            // MS-DOS, Windows path
            (strncmp(line[actual].c_str() + url_head, ":\\", 2) == 0) ||
            // URL
            (strncmp(line[actual].c_str() + url_head, "://", 3) == 0)) {
          url = 1;
        } else if (!(is_wordchar(line[actual].c_str() + url_head) || (ch == '-') ||
                     (ch == '_') || (ch == '\\') || (ch == '.') ||
                     (ch == ':') || (ch == '/') || (ch == '~') || (ch == '%') ||
                     (ch == '*') || (ch == '$') || (ch == '[') || (ch == ']') ||
                     (ch == '?') || (ch == '!') ||
                     ((ch >= '0') && (ch <= '9')))) {
          url_state = 0;
          if (url == 1) {
            for (size_t i = url_token; i < url_head; ++i) {
              urlline[i] = true;
            }
          }
          url = 0;
        }
        break;
    }
    urlline[url_head] = false;
    if (next_char(line[actual].c_str(), &url_head))
      return;
  }
}

int TextParser::get_url(size_t token_pos, size_t* hd) {
  for (size_t i = *hd; i < line[actual].size() && urlline[i]; i++, (*hd)++)
    ;
  return checkurl ? 0 : urlline[token_pos];
}

void TextParser::set_url_checking(int check) {
  checkurl = check;
}

bool TextParser::alloc_token(size_t tokn, size_t* hd, std::string& t) {
  size_t url_head = *hd;
  if (get_url(tokn, &url_head))
    return false;
  t = line[actual].substr(tokn, *hd - tokn);
  // remove colon for Finnish and Swedish language
  if (!t.empty() && t[t.size() - 1] == ':') {
    t.resize(t.size() - 1);
    if (t.empty()) {
      return false;
    }
  }
  return true;
}
<|endoftext|>


<commit_before><commit_msg>Mac build fix: Mac needs more includes than Linux<commit_after><|endoftext|>