<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: adodatalinks.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-25 10:48:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#if defined(WIN) || defined(WNT)
#if defined _MSC_VER
#pragma warning(push, 1)
#pragma warning(disable: 4917)
#endif
#include "msdasc.h"        // OLE DB Service Component header
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include "stdio.h"

#include <initguid.h>  // Include only once in your application
#include <adoid.h>     // needed for CLSID_CADOConnection
#include <adoint.h>    // needed for ADOConnection

#ifndef _DBAUI_ADO_DATALINK_HXX_
#include "adodatalinks.hxx"
#endif

BSTR PromptEdit(long hWnd,BSTR connstr);
BSTR PromptNew(long hWnd);

::rtl::OUString getAdoDatalink(long hWnd,::rtl::OUString& oldLink)
{
    ::rtl::OUString dataLink;
    if (oldLink.getLength())
    {
        dataLink=reinterpret_cast<sal_Unicode *>(PromptEdit(hWnd,(BSTR)oldLink.getStr()));
    }
    else
        dataLink=reinterpret_cast<sal_Unicode *>(PromptNew(hWnd));
    return dataLink;
}
BSTR PromptNew(long hWnd)
{
    BSTR connstr=NULL;
    HRESULT hr;
    IDataSourceLocator* dlPrompt = NULL;
    ADOConnection* piTmpConnection = NULL;
    BSTR _result=NULL;

     // Initialize COM
     ::CoInitialize( NULL );

    // Instantiate DataLinks object.
      hr = CoCreateInstance(
                    CLSID_DataLinks,                //clsid -- Data Links UI
                    NULL,                           //pUnkOuter
                    CLSCTX_INPROC_SERVER,           //dwClsContext
                    IID_IDataSourceLocator,     //riid
                    (void**)&dlPrompt   //ppvObj
                    );
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    dlPrompt->put_hWnd(hWnd);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    // Prompt for connection information.
    hr = dlPrompt->PromptNew((IDispatch **)&piTmpConnection);

    if( FAILED( hr ) || !piTmpConnection )
    {
        dlPrompt->Release( );
        return connstr;
    }

    hr = piTmpConnection->get_ConnectionString(&_result);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    piTmpConnection->Release( );
    dlPrompt->Release( );
    CoUninitialize();
    return _result;
}

BSTR PromptEdit(long hWnd,BSTR connstr)
{
    HRESULT hr;
    IDataSourceLocator* dlPrompt = NULL;
    ADOConnection* piTmpConnection = NULL;
    BSTR _result=NULL;

     // Initialize COM
     ::CoInitialize( NULL );

     hr = CoCreateInstance(CLSID_CADOConnection,
                NULL,
                CLSCTX_INPROC_SERVER,
                IID_IADOConnection,
                (LPVOID *)&piTmpConnection);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        return connstr;
    }

    hr = piTmpConnection->put_ConnectionString(connstr);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        return connstr;
    }

    // Instantiate DataLinks object.
      hr = CoCreateInstance(
                    CLSID_DataLinks,                //clsid -- Data Links UI
                    NULL,                           //pUnkOuter
                    CLSCTX_INPROC_SERVER,           //dwClsContext
                    IID_IDataSourceLocator,     //riid
                    (void**)&dlPrompt   //ppvObj
                    );
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    dlPrompt->put_hWnd(hWnd);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    VARIANT_BOOL pbSuccess;

    // Prompt for connection information.
    hr = dlPrompt->PromptEdit((IDispatch **)&piTmpConnection,&pbSuccess);
    if( SUCCEEDED( hr ) && FALSE == pbSuccess ) //if user press cancel then FALSE == pbSuccess
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    if( FAILED( hr ) )
    {
        // Prompt for new connection information.
        piTmpConnection->Release( );
        piTmpConnection = NULL;
        hr = dlPrompt->PromptNew((IDispatch **)&piTmpConnection);
        if(  FAILED( hr ) || !piTmpConnection )
        {
            dlPrompt->Release( );
            return connstr;
        }
    }

    hr = piTmpConnection->get_ConnectionString(&_result);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    piTmpConnection->Release( );
    dlPrompt->Release( );
    CoUninitialize();
    return _result;
}
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.7.168); FILE MERGED 2008/03/31 13:27:14 rt 1.7.168.1: #i87441# Change license header to LPGL v3.<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: adodatalinks.cxx,v $
 * $Revision: 1.8 $
 *
 * 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_dbaccess.hxx"

#if defined(WIN) || defined(WNT)
#if defined _MSC_VER
#pragma warning(push, 1)
#pragma warning(disable: 4917)
#endif
#include "msdasc.h"        // OLE DB Service Component header
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include "stdio.h"

#include <initguid.h>  // Include only once in your application
#include <adoid.h>     // needed for CLSID_CADOConnection
#include <adoint.h>    // needed for ADOConnection

#ifndef _DBAUI_ADO_DATALINK_HXX_
#include "adodatalinks.hxx"
#endif

BSTR PromptEdit(long hWnd,BSTR connstr);
BSTR PromptNew(long hWnd);

::rtl::OUString getAdoDatalink(long hWnd,::rtl::OUString& oldLink)
{
    ::rtl::OUString dataLink;
    if (oldLink.getLength())
    {
        dataLink=reinterpret_cast<sal_Unicode *>(PromptEdit(hWnd,(BSTR)oldLink.getStr()));
    }
    else
        dataLink=reinterpret_cast<sal_Unicode *>(PromptNew(hWnd));
    return dataLink;
}
BSTR PromptNew(long hWnd)
{
    BSTR connstr=NULL;
    HRESULT hr;
    IDataSourceLocator* dlPrompt = NULL;
    ADOConnection* piTmpConnection = NULL;
    BSTR _result=NULL;

     // Initialize COM
     ::CoInitialize( NULL );

    // Instantiate DataLinks object.
      hr = CoCreateInstance(
                    CLSID_DataLinks,                //clsid -- Data Links UI
                    NULL,                           //pUnkOuter
                    CLSCTX_INPROC_SERVER,           //dwClsContext
                    IID_IDataSourceLocator,     //riid
                    (void**)&dlPrompt   //ppvObj
                    );
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    dlPrompt->put_hWnd(hWnd);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    // Prompt for connection information.
    hr = dlPrompt->PromptNew((IDispatch **)&piTmpConnection);

    if( FAILED( hr ) || !piTmpConnection )
    {
        dlPrompt->Release( );
        return connstr;
    }

    hr = piTmpConnection->get_ConnectionString(&_result);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    piTmpConnection->Release( );
    dlPrompt->Release( );
    CoUninitialize();
    return _result;
}

BSTR PromptEdit(long hWnd,BSTR connstr)
{
    HRESULT hr;
    IDataSourceLocator* dlPrompt = NULL;
    ADOConnection* piTmpConnection = NULL;
    BSTR _result=NULL;

     // Initialize COM
     ::CoInitialize( NULL );

     hr = CoCreateInstance(CLSID_CADOConnection,
                NULL,
                CLSCTX_INPROC_SERVER,
                IID_IADOConnection,
                (LPVOID *)&piTmpConnection);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        return connstr;
    }

    hr = piTmpConnection->put_ConnectionString(connstr);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        return connstr;
    }

    // Instantiate DataLinks object.
      hr = CoCreateInstance(
                    CLSID_DataLinks,                //clsid -- Data Links UI
                    NULL,                           //pUnkOuter
                    CLSCTX_INPROC_SERVER,           //dwClsContext
                    IID_IDataSourceLocator,     //riid
                    (void**)&dlPrompt   //ppvObj
                    );
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    dlPrompt->put_hWnd(hWnd);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    VARIANT_BOOL pbSuccess;

    // Prompt for connection information.
    hr = dlPrompt->PromptEdit((IDispatch **)&piTmpConnection,&pbSuccess);
    if( SUCCEEDED( hr ) && FALSE == pbSuccess ) //if user press cancel then FALSE == pbSuccess
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    if( FAILED( hr ) )
    {
        // Prompt for new connection information.
        piTmpConnection->Release( );
        piTmpConnection = NULL;
        hr = dlPrompt->PromptNew((IDispatch **)&piTmpConnection);
        if(  FAILED( hr ) || !piTmpConnection )
        {
            dlPrompt->Release( );
            return connstr;
        }
    }

    hr = piTmpConnection->get_ConnectionString(&_result);
    if( FAILED( hr ) )
    {
        piTmpConnection->Release( );
        dlPrompt->Release( );
        return connstr;
    }

    piTmpConnection->Release( );
    dlPrompt->Release( );
    CoUninitialize();
    return _result;
}
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: finteraction.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:03:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef DBAUI_FILEPICKER_INTERACTION_HXX
#include "finteraction.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif

//........................................................................
namespace dbaui
{
//........................................................................
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::ucb;

    //====================================================================
    //= OFilePickerInteractionHandler
    //====================================================================
    DBG_NAME( OFilePickerInteractionHandler )
    //--------------------------------------------------------------------
    OFilePickerInteractionHandler::OFilePickerInteractionHandler( const Reference< XInteractionHandler >& _rxMaster )
        :m_xMaster( _rxMaster )
        ,m_bDoesNotExist(sal_False)
    {
        DBG_CTOR( OFilePickerInteractionHandler, NULL );
        DBG_ASSERT( m_xMaster.is(), "OFilePickerInteractionHandler::OFilePickerInteractionHandler: invalid master handler!" );
    }

    //--------------------------------------------------------------------
    OFilePickerInteractionHandler::~OFilePickerInteractionHandler( )
    {
        DBG_DTOR( OFilePickerInteractionHandler, NULL );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OFilePickerInteractionHandler::handle( const Reference< XInteractionRequest >& _rxRequest ) throw (RuntimeException)
    {
        InteractiveIOException aIoException;
        if ( _rxRequest->getRequest() >>= aIoException )
        {
            if ( IOErrorCode_NOT_EXISTING == aIoException.Code )
            {
                m_bDoesNotExist = sal_True;
                return;
            }
        }

        if ( m_xMaster.is() )
            m_xMaster->handle( _rxRequest );
    }

//........................................................................
}   // namespace svt
//........................................................................

<commit_msg>INTEGRATION: CWS pchfix02 (1.3.184); FILE MERGED 2006/09/01 17:24:29 kaib 1.3.184.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: finteraction.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:09:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef DBAUI_FILEPICKER_INTERACTION_HXX
#include "finteraction.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif

//........................................................................
namespace dbaui
{
//........................................................................
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::ucb;

    //====================================================================
    //= OFilePickerInteractionHandler
    //====================================================================
    DBG_NAME( OFilePickerInteractionHandler )
    //--------------------------------------------------------------------
    OFilePickerInteractionHandler::OFilePickerInteractionHandler( const Reference< XInteractionHandler >& _rxMaster )
        :m_xMaster( _rxMaster )
        ,m_bDoesNotExist(sal_False)
    {
        DBG_CTOR( OFilePickerInteractionHandler, NULL );
        DBG_ASSERT( m_xMaster.is(), "OFilePickerInteractionHandler::OFilePickerInteractionHandler: invalid master handler!" );
    }

    //--------------------------------------------------------------------
    OFilePickerInteractionHandler::~OFilePickerInteractionHandler( )
    {
        DBG_DTOR( OFilePickerInteractionHandler, NULL );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OFilePickerInteractionHandler::handle( const Reference< XInteractionRequest >& _rxRequest ) throw (RuntimeException)
    {
        InteractiveIOException aIoException;
        if ( _rxRequest->getRequest() >>= aIoException )
        {
            if ( IOErrorCode_NOT_EXISTING == aIoException.Code )
            {
                m_bDoesNotExist = sal_True;
                return;
            }
        }

        if ( m_xMaster.is() )
            m_xMaster->handle( _rxRequest );
    }

//........................................................................
}   // namespace svt
//........................................................................

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * X testing environment - Google Test environment feat. dummy x server
 *
 * Copyright (C) 2011 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ****************************************************************************/

#include "xorg/gtest/environment.h"
#include "xorg/gtest/process.h"

#include <sys/types.h>
#include <unistd.h>

#include <cerrno>
#include <csignal>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stdexcept>

#include <X11/Xlib.h>

struct xorg::testing::Environment::Private {
  std::string path_to_conf;
  std::string path_to_server;
  int display;
  Process process;
};

xorg::testing::Environment::Environment(const std::string& path_to_conf,
                                        const std::string& path_to_server,
                                        int display)
    : d_(new Private) {
  d_->path_to_conf = path_to_conf;
  d_->path_to_server = path_to_server;
  d_->display = display;
}

void xorg::testing::Environment::SetUp() {
  static char display_string[6];
  snprintf(display_string, 6, ":%d", d_->display);

  d_->process.Start(d_->path_to_server, d_->path_to_server.c_str(),
                    display_string, "-config", d_->path_to_conf.c_str(), NULL);

  setenv("DISPLAY", display_string, true);

  for (int i = 0; i < 10; ++i) {
    Display* display = XOpenDisplay(NULL);

    if (display) {
      XCloseDisplay(display);
      return;
    }

    int status;
    int pid = waitpid(d_->process.Pid(), &status, WNOHANG);
    if (pid == d_->process.Pid())
      throw std::runtime_error("Dummy X server failed to start, did you run as "
                               "root?");
    else if (pid == 0)
      sleep(1); /* Give the dummy X server some time to start */
    else if (pid == -1)
      throw std::runtime_error("Could not get status of dummy X server "
                               "process");
    else
      throw std::runtime_error("Invalid child PID returned by Process::Wait()");
  }

  throw std::runtime_error("Unable to open connection to dummy X server");
}

void xorg::testing::Environment::TearDown() {
  if (!d_->process.Terminate()) {
    std::cerr << "Warning: Failed to terminate dummy Xorg server: "
              << std::strerror(errno) << "\n";
    if (!d_->process.Kill())
      std::cerr << "Warning: Failed to kill dummy Xorg server: "
                << std::strerror(errno) << "\n";
  }
}
<commit_msg>Add initializer for Environment::Private struct since it is not a POD<commit_after>/*****************************************************************************
 *
 * X testing environment - Google Test environment feat. dummy x server
 *
 * Copyright (C) 2011 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ****************************************************************************/

#include "xorg/gtest/environment.h"
#include "xorg/gtest/process.h"

#include <sys/types.h>
#include <unistd.h>

#include <cerrno>
#include <csignal>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stdexcept>

#include <X11/Xlib.h>

struct xorg::testing::Environment::Private {
  Private(const std::string& conf, const std::string& server, int display_num)
      : path_to_conf(conf), path_to_server(server), display(display_num) {
  }

  const std::string path_to_conf;
  const std::string path_to_server;
  const int display;
  Process process;
};

xorg::testing::Environment::Environment(const std::string& path_to_conf,
                                        const std::string& path_to_server,
                                        int display)
    : d_(new Private(path_to_conf, path_to_server, display)) {
}

void xorg::testing::Environment::SetUp() {
  static char display_string[6];
  snprintf(display_string, 6, ":%d", d_->display);

  d_->process.Start(d_->path_to_server, d_->path_to_server.c_str(),
                    display_string, "-config", d_->path_to_conf.c_str(), NULL);

  setenv("DISPLAY", display_string, true);

  for (int i = 0; i < 10; ++i) {
    Display* display = XOpenDisplay(NULL);

    if (display) {
      XCloseDisplay(display);
      return;
    }

    int status;
    int pid = waitpid(d_->process.Pid(), &status, WNOHANG);
    if (pid == d_->process.Pid())
      throw std::runtime_error("Dummy X server failed to start, did you run as "
                               "root?");
    else if (pid == 0)
      sleep(1); /* Give the dummy X server some time to start */
    else if (pid == -1)
      throw std::runtime_error("Could not get status of dummy X server "
                               "process");
    else
      throw std::runtime_error("Invalid child PID returned by Process::Wait()");
  }

  throw std::runtime_error("Unable to open connection to dummy X server");
}

void xorg::testing::Environment::TearDown() {
  if (!d_->process.Terminate()) {
    std::cerr << "Warning: Failed to terminate dummy Xorg server: "
              << std::strerror(errno) << "\n";
    if (!d_->process.Kill())
      std::cerr << "Warning: Failed to kill dummy Xorg server: "
                << std::strerror(errno) << "\n";
  }
}
<|endoftext|>


<commit_before>/*******************************************************************************
Copyright (c) 2014, Jan Koester jan.koester@gmx.net
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

#include <fcntl.h>
#include <sys/sysinfo.h>
#include <cstdlib>
#include <config.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>

#define READEVENT 0
#define SENDEVENT 1

#include "../event.h"

libhttppp::Event::Event(ServerSocket *serversocket) {
    _ServerSocket=serversocket;
    _ServerSocket->setnonblocking();
    _ServerSocket->listenSocket();
    _EventEndloop =true;
    _Cpool= new ConnectionPool(_ServerSocket);
    _Events = new epoll_event[(_ServerSocket->getMaxconnections())];
    _firstConnectionContext=NULL;
    _lastConnectionContext=NULL;
}

libhttppp::Event::~Event() {
  delete   _Cpool;
  delete[] _Events;
  delete _firstConnectionContext;
  _lastConnectionContext=NULL;
}

libhttppp::Event* _EventIns=NULL;

void libhttppp::Event::CtrlHandler(int signum) {
    _EventIns->_EventEndloop=false;
}

void libhttppp::Event::runEventloop() {
    _setEvent = (struct epoll_event){0};
    for(int i=0; i<_ServerSocket->getMaxconnections(); i++)
        _Events[i].data.fd = -1;
    _epollFD = epoll_create1(0);

    if (_epollFD == -1) {
        _httpexception.Critical("can't create epoll");
        throw _httpexception;
    }

    _setEvent.events = EPOLLIN;
    _setEvent.data.fd = _ServerSocket->getSocket();

    if (epoll_ctl(_epollFD, EPOLL_CTL_ADD, _ServerSocket->getSocket(), &_setEvent) < 0) {
        _httpexception.Critical("can't create epoll");
        throw _httpexception;
    }

    int srvssocket=_ServerSocket->getSocket();
    int maxconnets=_ServerSocket->getMaxconnections();
    while(_EventEndloop) {
        int n = epoll_wait(_epollFD,_Events,maxconnets, EPOLLWAIT);
        if(n<0){
            if(errno== EINTR){
                continue;
            }else{
                 _httpexception.Critical("epoll wait failure");
                 throw _httpexception;
            }

        }
        for(int i=0; i<n; i++) {
            ConnectionContext *curct=NULL;
            if(_Events[i].data.fd == srvssocket) {
              try {
              /*will create warning debug mode that normally because the check already connection
               * with this socket if getconnection throw they will be create a new one
               */
                curct=addConnection();
                ClientSocket *clientsocket=curct->_CurConnection->getClientSocket();
                int fd=_ServerSocket->acceptEvent(clientsocket);
                clientsocket->setnonblocking();
                if(fd>0) {
                  _setEvent.data.ptr = (void*) curct;
                  _setEvent.events = EPOLLIN|EPOLLET|EPOLLONESHOT;
                  if(epoll_ctl(_epollFD, EPOLL_CTL_ADD, fd, &_setEvent)==-1 && errno==EEXIST)
                    epoll_ctl(_epollFD, EPOLL_CTL_MOD,fd, &_setEvent);
                  ConnectEvent(curct->_CurConnection);
                } else {
                  delConnection(curct->_CurConnection);
                }
              } catch(HTTPException &e) {
                delConnection(curct->_CurConnection);
                if(e.isCritical())
                  throw e;
              }
            } else {
                curct=(ConnectionContext*)_Events[i].data.ptr;
                if(_Events[i].events & EPOLLIN) {
                    Thread(ReadEvent,curct);
                }else{
                    CloseEvent(curct);
                }
            }
        }
        _EventIns=this;
        signal(SIGINT, CtrlHandler);
    }
}

libhttppp::Event::ConnectionContext::ConnectionContext(){
  _CurConnection=NULL;
  _CurCPool=NULL;
  _CurEvent=NULL;
  _nextConnectionContext=NULL;
}

libhttppp::Event::ConnectionContext::~ConnectionContext(){
  delete _nextConnectionContext;
}

libhttppp::Event::ConnectionContext * libhttppp::Event::ConnectionContext::nextConnectionContext(){
  return _nextConnectionContext;
}

libhttppp::Event::ConnectionContext * libhttppp::Event::addConnection(){
  if(!_firstConnectionContext){
    _firstConnectionContext=new ConnectionContext();
    _lastConnectionContext=_firstConnectionContext;
  }else{
    _lastConnectionContext->_nextConnectionContext=new ConnectionContext();
    _lastConnectionContext=_lastConnectionContext->_nextConnectionContext;
  }
  _lastConnectionContext->_CurConnection=_Cpool->addConnection();
  _lastConnectionContext->_CurCPool=_Cpool;
  _lastConnectionContext->_CurEvent=this;
  return _lastConnectionContext;
}

libhttppp::Event::ConnectionContext * libhttppp::Event::delConnection(libhttppp::Connection* delcon){
  _Cpool->delConnection(delcon);
  ConnectionContext *prevcontext=NULL;
  for(ConnectionContext *curcontext=_firstConnectionContext; curcontext;
      curcontext=curcontext->nextConnectionContext()){
    if(curcontext->_CurConnection==delcon){
      if(prevcontext){
        prevcontext->_nextConnectionContext=curcontext->_nextConnectionContext;
        if(_lastConnectionContext->_CurConnection==delcon)
          _lastConnectionContext=prevcontext;
      }else{
        _firstConnectionContext=curcontext->_nextConnectionContext;
        if(_lastConnectionContext->_CurConnection==delcon)
          _lastConnectionContext=_firstConnectionContext;
      }
      curcontext->_nextConnectionContext=NULL;
      delete curcontext;
      break;
    }
    prevcontext=curcontext;
  }
  if(prevcontext && prevcontext->_nextConnectionContext){
    return prevcontext->_nextConnectionContext;
  }else{
    ConnectionContext *fcontext=_firstConnectionContext;
    return fcontext;
  }
}

/*Workers*/
void *libhttppp::Event::ReadEvent(void *curcon){
  ConnectionContext *ccon=(ConnectionContext*)curcon;
  Event *eventins=ccon->_CurEvent;
  Connection *con=(Connection*)ccon->_CurConnection;
  try {
    char buf[BLOCKSIZE];
    int rcvsize=0;
    do{
      rcvsize=eventins->_ServerSocket->recvData(con->getClientSocket(),buf,BLOCKSIZE);
      if(rcvsize>0)
        con->addRecvQueue(buf,rcvsize);
    }while(rcvsize>0);
    eventins->RequestEvent(con);
    WriteEvent(ccon);
  } catch(HTTPException &e) {
       if(e.isCritical()) {
         throw e;
       }
       if(e.isError()){
          CloseEvent(ccon);
       }
  }
  return NULL;
}

void *libhttppp::Event::WriteEvent(void* curcon){
  ConnectionContext *ccon=(ConnectionContext*)curcon;
  Event *eventins=ccon->_CurEvent;
  Connection *con=(Connection*)ccon->_CurConnection;
  try {
    ssize_t sended=0;
    while(con->getSendData()){
      sended=eventins->_ServerSocket->sendData(con->getClientSocket(),
                                    (void*)con->getSendData()->getData(),
                                    con->getSendData()->getDataSize());
      if(sended>0)
        con->resizeSendQueue(sended);
      eventins->ResponseEvent(con);
    };
  } catch(HTTPException &e) {
    con->cleanSendData();
    CloseEvent(ccon);
  }
  return NULL;
}

void *libhttppp::Event::CloseEvent(void *curcon){
  ConnectionContext *ccon=(ConnectionContext*)curcon;
  Event *eventins=ccon->_CurEvent;
  Connection *con=(Connection*)ccon->_CurConnection;
  eventins->DisconnectEvent(con);
  try {
    epoll_ctl(eventins->_epollFD, EPOLL_CTL_DEL, con->getClientSocket()->getSocket(), &eventins->_setEvent);
    eventins->delConnection(con);
    curcon=NULL;
    eventins->_httpexception.Note("Connection shutdown!");
  } catch(HTTPException &e) {
    eventins->_httpexception.Note("Can't do Connection shutdown!");
  }
  return NULL;
}

/*Event Handlers*/
void libhttppp::Event::RequestEvent(Connection *curcon) {
    return;
}

void libhttppp::Event::ResponseEvent(libhttppp::Connection *curcon) {
    return;
}

void libhttppp::Event::ConnectEvent(libhttppp::Connection *curcon) {
    return;
}

void libhttppp::Event::DisconnectEvent(Connection *curcon) {
    return;
}
<commit_msg>removed eoneshot flag<commit_after>/*******************************************************************************
Copyright (c) 2014, Jan Koester jan.koester@gmx.net
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

#include <fcntl.h>
#include <sys/sysinfo.h>
#include <cstdlib>
#include <config.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>

#define READEVENT 0
#define SENDEVENT 1

#include "../event.h"

libhttppp::Event::Event(ServerSocket *serversocket) {
    _ServerSocket=serversocket;
    _ServerSocket->setnonblocking();
    _ServerSocket->listenSocket();
    _EventEndloop =true;
    _Cpool= new ConnectionPool(_ServerSocket);
    _Events = new epoll_event[(_ServerSocket->getMaxconnections())];
    _firstConnectionContext=NULL;
    _lastConnectionContext=NULL;
}

libhttppp::Event::~Event() {
  delete   _Cpool;
  delete[] _Events;
  delete _firstConnectionContext;
  _lastConnectionContext=NULL;
}

libhttppp::Event* _EventIns=NULL;

void libhttppp::Event::CtrlHandler(int signum) {
    _EventIns->_EventEndloop=false;
}

void libhttppp::Event::runEventloop() {
    _setEvent = (struct epoll_event){0};
    for(int i=0; i<_ServerSocket->getMaxconnections(); i++)
        _Events[i].data.fd = -1;
    _epollFD = epoll_create1(0);

    if (_epollFD == -1) {
        _httpexception.Critical("can't create epoll");
        throw _httpexception;
    }

    _setEvent.events = EPOLLIN;
    _setEvent.data.fd = _ServerSocket->getSocket();

    if (epoll_ctl(_epollFD, EPOLL_CTL_ADD, _ServerSocket->getSocket(), &_setEvent) < 0) {
        _httpexception.Critical("can't create epoll");
        throw _httpexception;
    }

    int srvssocket=_ServerSocket->getSocket();
    int maxconnets=_ServerSocket->getMaxconnections();
    while(_EventEndloop) {
        int n = epoll_wait(_epollFD,_Events,maxconnets, EPOLLWAIT);
        if(n<0){
            if(errno== EINTR){
                continue;
            }else{
                 _httpexception.Critical("epoll wait failure");
                 throw _httpexception;
            }

        }
        for(int i=0; i<n; i++) {
            ConnectionContext *curct=NULL;
            if(_Events[i].data.fd == srvssocket) {
              try {
              /*will create warning debug mode that normally because the check already connection
               * with this socket if getconnection throw they will be create a new one
               */
                curct=addConnection();
                ClientSocket *clientsocket=curct->_CurConnection->getClientSocket();
                int fd=_ServerSocket->acceptEvent(clientsocket);
                clientsocket->setnonblocking();
                if(fd>0) {
                  _setEvent.data.ptr = (void*) curct;
                  _setEvent.events = EPOLLIN|EPOLLET;
                  if(epoll_ctl(_epollFD, EPOLL_CTL_ADD, fd, &_setEvent)==-1 && errno==EEXIST)
                    epoll_ctl(_epollFD, EPOLL_CTL_MOD,fd, &_setEvent);
                  ConnectEvent(curct->_CurConnection);
                } else {
                  delConnection(curct->_CurConnection);
                }
              } catch(HTTPException &e) {
                delConnection(curct->_CurConnection);
                if(e.isCritical())
                  throw e;
              }
            } else {
                curct=(ConnectionContext*)_Events[i].data.ptr;
                if(_Events[i].events & EPOLLIN) {
                    Thread(ReadEvent,curct);
                }else{
                    CloseEvent(curct);
                }
            }
        }
        _EventIns=this;
        signal(SIGINT, CtrlHandler);
    }
}

libhttppp::Event::ConnectionContext::ConnectionContext(){
  _CurConnection=NULL;
  _CurCPool=NULL;
  _CurEvent=NULL;
  _nextConnectionContext=NULL;
}

libhttppp::Event::ConnectionContext::~ConnectionContext(){
  delete _nextConnectionContext;
}

libhttppp::Event::ConnectionContext * libhttppp::Event::ConnectionContext::nextConnectionContext(){
  return _nextConnectionContext;
}

libhttppp::Event::ConnectionContext * libhttppp::Event::addConnection(){
  if(!_firstConnectionContext){
    _firstConnectionContext=new ConnectionContext();
    _lastConnectionContext=_firstConnectionContext;
  }else{
    _lastConnectionContext->_nextConnectionContext=new ConnectionContext();
    _lastConnectionContext=_lastConnectionContext->_nextConnectionContext;
  }
  _lastConnectionContext->_CurConnection=_Cpool->addConnection();
  _lastConnectionContext->_CurCPool=_Cpool;
  _lastConnectionContext->_CurEvent=this;
  return _lastConnectionContext;
}

libhttppp::Event::ConnectionContext * libhttppp::Event::delConnection(libhttppp::Connection* delcon){
  _Cpool->delConnection(delcon);
  ConnectionContext *prevcontext=NULL;
  for(ConnectionContext *curcontext=_firstConnectionContext; curcontext;
      curcontext=curcontext->nextConnectionContext()){
    if(curcontext->_CurConnection==delcon){
      if(prevcontext){
        prevcontext->_nextConnectionContext=curcontext->_nextConnectionContext;
        if(_lastConnectionContext->_CurConnection==delcon)
          _lastConnectionContext=prevcontext;
      }else{
        _firstConnectionContext=curcontext->_nextConnectionContext;
        if(_lastConnectionContext->_CurConnection==delcon)
          _lastConnectionContext=_firstConnectionContext;
      }
      curcontext->_nextConnectionContext=NULL;
      delete curcontext;
      break;
    }
    prevcontext=curcontext;
  }
  if(prevcontext && prevcontext->_nextConnectionContext){
    return prevcontext->_nextConnectionContext;
  }else{
    ConnectionContext *fcontext=_firstConnectionContext;
    return fcontext;
  }
}

/*Workers*/
void *libhttppp::Event::ReadEvent(void *curcon){
  ConnectionContext *ccon=(ConnectionContext*)curcon;
  Event *eventins=ccon->_CurEvent;
  Connection *con=(Connection*)ccon->_CurConnection;
  try {
    char buf[BLOCKSIZE];
    int rcvsize=0;
    do{
      rcvsize=eventins->_ServerSocket->recvData(con->getClientSocket(),buf,BLOCKSIZE);
      if(rcvsize>0)
        con->addRecvQueue(buf,rcvsize);
    }while(rcvsize>0);
    eventins->RequestEvent(con);
    WriteEvent(ccon);
  } catch(HTTPException &e) {
       if(e.isCritical()) {
         throw e;
       }
       if(e.isError()){
          CloseEvent(ccon);
       }
  }
  return NULL;
}

void *libhttppp::Event::WriteEvent(void* curcon){
  ConnectionContext *ccon=(ConnectionContext*)curcon;
  Event *eventins=ccon->_CurEvent;
  Connection *con=(Connection*)ccon->_CurConnection;
  try {
    ssize_t sended=0;
    while(con->getSendData()){
      sended=eventins->_ServerSocket->sendData(con->getClientSocket(),
                                    (void*)con->getSendData()->getData(),
                                    con->getSendData()->getDataSize());
      if(sended>0)
        con->resizeSendQueue(sended);
      eventins->ResponseEvent(con);
    };
  } catch(HTTPException &e) {
    con->cleanSendData();
    CloseEvent(ccon);
  }
  return NULL;
}

void *libhttppp::Event::CloseEvent(void *curcon){
  ConnectionContext *ccon=(ConnectionContext*)curcon;
  Event *eventins=ccon->_CurEvent;
  Connection *con=(Connection*)ccon->_CurConnection;
  eventins->DisconnectEvent(con);
  try {
    epoll_ctl(eventins->_epollFD, EPOLL_CTL_DEL, con->getClientSocket()->getSocket(), &eventins->_setEvent);
    eventins->delConnection(con);
    curcon=NULL;
    eventins->_httpexception.Note("Connection shutdown!");
  } catch(HTTPException &e) {
    eventins->_httpexception.Note("Can't do Connection shutdown!");
  }
  return NULL;
}

/*Event Handlers*/
void libhttppp::Event::RequestEvent(Connection *curcon) {
    return;
}

void libhttppp::Event::ResponseEvent(libhttppp::Connection *curcon) {
    return;
}

void libhttppp::Event::ConnectEvent(libhttppp::Connection *curcon) {
    return;
}

void libhttppp::Event::DisconnectEvent(Connection *curcon) {
    return;
}
<|endoftext|>


<commit_before>// Chemfiles, a modern library for chemistry file reading and writing
// Copyright (C) 2015-2016 Guillaume Fraux and contributors
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

#include <cassert>
#include <sstream>

#include <fmt/format.h>
#include <fmt/ostream.h>

#include "chemfiles/formats/XYZ.hpp"

#include "chemfiles/Error.hpp"
#include "chemfiles/File.hpp"
#include "chemfiles/Frame.hpp"

using namespace chemfiles;

/// Fast-forward the file for one step, returning `false` if the file does
/// not contain one more step.
static bool forward(TextFile& file);

XYZFormat::XYZFormat(const std::string& path, File::Mode mode): file_(TextFile::create(path, mode)), steps_positions_() {
    while (!file_->eof()) {
        auto position = file_->tellg();
        if (!file_ || position == std::streampos(-1)) {
            throw FormatError("Error while reading '" + path + "' as XYZ");
        }
        if (forward(*file_)) {
            steps_positions_.push_back(position);
        }
    }
    file_->rewind();
}

std::string XYZFormat::description() const {
    return "XYZ file format.";
}

size_t XYZFormat::nsteps() {
    return steps_positions_.size();
}

void XYZFormat::read_step(const size_t step, Frame& frame) {
    assert(step < steps_positions_.size());
    file_->seekg(steps_positions_[step]);
    read(frame);
}

void XYZFormat::read(Frame& frame) {
    size_t natoms = 0;
    try {
        natoms = std::stoul(file_->readline());
        file_->readline(); // XYZ comment line;
    } catch (const std::exception& e) {
        throw FormatError("Can not read next step: " + std::string(e.what()));
    }

    std::vector<std::string> lines;
    try {
        lines = file_->readlines(natoms);
    } catch (const FileError& e) {
        throw FormatError("Can not read file: " + std::string(e.what()));
    }

    frame.reserve(natoms);
    frame.resize(0);

    for (size_t i = 0; i < lines.size(); i++) {
        std::istringstream string_stream;
        double x = 0, y = 0, z = 0;
        std::string name;

        string_stream.str(lines[i]);
        string_stream >> name >> x >> y >> z;

        frame.add_atom(Atom(name), {{x, y, z}});
    }
}

void XYZFormat::write(const Frame& frame) {
    auto& topology = frame.topology();
    auto& positions = frame.positions();
    assert(frame.natoms() == topology.natoms());

    fmt::print(*file_, "{}\n", frame.natoms());
    fmt::print(*file_, "Written by the chemfiles library\n", frame.natoms());

    for (size_t i = 0; i < frame.natoms(); i++) {
        auto type = topology[i].type();
        if (type == "") {type = "X";}
        fmt::print(
            *file_, "{} {} {} {}\n",
            type, positions[i][0], positions[i][1], positions[i][2]
        );
    }

    steps_positions_.push_back(file_->tellg());
}

bool forward(TextFile& file) {
    if (!file) {return false;}

    std::string line;
    try {
        line = file.readline();
    } catch (const FileError&) {
        // No more line left in the file
        return false;
    }

    long long natoms = 0;
    try {
        natoms = std::stoll(line);
    } catch (const std::invalid_argument&) {
        // We could not read an integer, so give up here
        return false;
    }

    if (natoms < 0) {
        throw FormatError(
            "Number of atoms can not be negative in '" + file.filename()
        );
    }

    try {
        file.readlines(static_cast<size_t>(natoms) + 1);
    } catch (const FileError&) {
        // We could not read the lines from the file
        throw FormatError(
            "Not enough lines in '" + file.filename() + "' for XYZ format"
        );
    }
    return true;
}
<commit_msg>Write name in XYZ format rather than type<commit_after>// Chemfiles, a modern library for chemistry file reading and writing
// Copyright (C) 2015-2016 Guillaume Fraux and contributors
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

#include <cassert>
#include <sstream>

#include <fmt/format.h>
#include <fmt/ostream.h>

#include "chemfiles/formats/XYZ.hpp"

#include "chemfiles/Error.hpp"
#include "chemfiles/File.hpp"
#include "chemfiles/Frame.hpp"

using namespace chemfiles;

/// Fast-forward the file for one step, returning `false` if the file does
/// not contain one more step.
static bool forward(TextFile& file);

XYZFormat::XYZFormat(const std::string& path, File::Mode mode): file_(TextFile::create(path, mode)), steps_positions_() {
    while (!file_->eof()) {
        auto position = file_->tellg();
        if (!file_ || position == std::streampos(-1)) {
            throw FormatError("Error while reading '" + path + "' as XYZ");
        }
        if (forward(*file_)) {
            steps_positions_.push_back(position);
        }
    }
    file_->rewind();
}

std::string XYZFormat::description() const {
    return "XYZ file format.";
}

size_t XYZFormat::nsteps() {
    return steps_positions_.size();
}

void XYZFormat::read_step(const size_t step, Frame& frame) {
    assert(step < steps_positions_.size());
    file_->seekg(steps_positions_[step]);
    read(frame);
}

void XYZFormat::read(Frame& frame) {
    size_t natoms = 0;
    try {
        natoms = std::stoul(file_->readline());
        file_->readline(); // XYZ comment line;
    } catch (const std::exception& e) {
        throw FormatError("Can not read next step: " + std::string(e.what()));
    }

    std::vector<std::string> lines;
    try {
        lines = file_->readlines(natoms);
    } catch (const FileError& e) {
        throw FormatError("Can not read file: " + std::string(e.what()));
    }

    frame.reserve(natoms);
    frame.resize(0);

    for (size_t i = 0; i < lines.size(); i++) {
        std::istringstream string_stream;
        double x = 0, y = 0, z = 0;
        std::string name;

        string_stream.str(lines[i]);
        string_stream >> name >> x >> y >> z;

        frame.add_atom(Atom(name), {{x, y, z}});
    }
}

void XYZFormat::write(const Frame& frame) {
    auto& topology = frame.topology();
    auto& positions = frame.positions();
    assert(frame.natoms() == topology.natoms());

    fmt::print(*file_, "{}\n", frame.natoms());
    fmt::print(*file_, "Written by the chemfiles library\n", frame.natoms());

    for (size_t i = 0; i < frame.natoms(); i++) {
        auto name = topology[i].name();
        if (name == "") {name = "X";}
        fmt::print(
            *file_, "{} {} {} {}\n",
            name, positions[i][0], positions[i][1], positions[i][2]
        );
    }

    steps_positions_.push_back(file_->tellg());
}

bool forward(TextFile& file) {
    if (!file) {return false;}

    std::string line;
    try {
        line = file.readline();
    } catch (const FileError&) {
        // No more line left in the file
        return false;
    }

    long long natoms = 0;
    try {
        natoms = std::stoll(line);
    } catch (const std::invalid_argument&) {
        // We could not read an integer, so give up here
        return false;
    }

    if (natoms < 0) {
        throw FormatError(
            "Number of atoms can not be negative in '" + file.filename()
        );
    }

    try {
        file.readlines(static_cast<size_t>(natoms) + 1);
    } catch (const FileError&) {
        // We could not read the lines from the file
        throw FormatError(
            "Not enough lines in '" + file.filename() + "' for XYZ format"
        );
    }
    return true;
}
<|endoftext|>


<commit_before>/*
 * GAMS - General Algebraic Modeling System C++ API
 *
 * Copyright (c) 2017-2020 GAMS Software GmbH <support@gams.com>
 * Copyright (c) 2017-2020 GAMS Development Corp. <support@gams.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "gamsjobimpl.h"
#include "gmomcc.h"
#include "gamscheckpoint.h"
#include "gamslog.h"
#include "gamsoptions.h"
#include "gamsplatform.h"
#include "gamspath.h"
#include "gamsexceptionexecution.h"

#include <sstream>
#include <fstream>
#include <iostream>
// rogo remove
#include <QDebug>

using namespace std;

namespace gams {

GAMSJobImpl::GAMSJobImpl(GAMSWorkspace workspace,
                         const std::string& jobName,
                         const std::string& fileName,
                         const GAMSCheckpoint* checkpoint)
    : mWs(workspace), mJobName(jobName), mFileName(fileName)
{
    DEB << "---- Entering GAMSJob constructor ----";
    if (checkpoint != nullptr) {
        if (!GAMSPath::exists(checkpoint->fileName()) )
            throw GAMSException("Checkpoint file " + checkpoint->fileName() + " does not exist");
        mCheckpointStart = new GAMSCheckpoint(*checkpoint);
    }
}

bool GAMSJobImpl::operator!=(const GAMSJobImpl& other) const
{
    return (mWs != other.mWs) || (mJobName != other.mJobName);
}

bool GAMSJobImpl::operator==(const GAMSJobImpl& other) const
{
    return !(operator!=(other));
}

GAMSDatabase GAMSJobImpl::outDB()
{
    return mOutDb;
}

GAMSJobImpl::~GAMSJobImpl() {
    if (mCheckpointStart != nullptr)
        delete mCheckpointStart; // this is intended to only free the wrapper, not the *Impl if used anywhere
}

// TODO(RG): what are these?
//   shared_ptr<GAMSJobImpl> GAMSJobImpl::fromString(GAMSWorkspace workspace, string gamsSource, const GAMSCheckpoint *checkpoint, string jobName)
//   {
//      shared_ptr<GAMSJobImpl> jobImpl = make_shared<GAMSJobImpl>(workspace, "", "", checkpoint);
//      if (jobName == "")
//         jobImpl->mJobName = workspace.mImpl->jobAdd();
//      else
//      {
//         jobImpl->mJobName = jobName;
//         if (!workspace.mImpl->jobAdd(jobImpl->mJobName))
//            throw GAMSException("Job with name " + jobName + " already exists");
//      }

//      jobImpl->mFileName = GPath(workspace.workingDirectory()) / (jobImpl->mJobName + ".gms");

//      std::ofstream sourceWriter(jobImpl->mFileName);
//      sourceWriter << gamsSource;
//      sourceWriter.close();

//      return jobImpl;
//   }

//   shared_ptr<GAMSJobImpl> GAMSJobImpl::fromFile(GAMSWorkspace workspace, string fileName, const GAMSCheckpoint *checkpoint, string jobName)
//   {
//      shared_ptr<GAMSJobImpl> jobImpl = make_shared<GAMSJobImpl>(workspace, "", "", checkpoint);
//      if (jobName == "")
//         jobImpl->mJobName = workspace.mImpl->jobAdd();
//      else
//      {
//         jobImpl->mJobName = jobName;
//         if (!workspace.mImpl->jobAdd(jobImpl->mJobName))
//            throw GAMSException("Job with name " + jobName + " already exists");
//      }
//      if (GPath(fileName).isAbsolute())
//         jobImpl->mFileName = fileName;
//      else
//         jobImpl->mFileName = GPath(workspace.workingDirectory()) / fileName;

//      if (!GPath::exists(jobImpl->mFileName))
//         throw GAMSException("Could not create GAMSJob instance from non-existing file [" + jobImpl->mFileName + "]");

//      return jobImpl;
//   }

// TODO(RG): check how "output" parameter was used in original version
void GAMSJobImpl::run(GAMSOptions* gamsOptions, GAMSCheckpoint* checkpoint, ostream* output, bool createOutDb,
                      vector<GAMSDatabase> databases)
{
    // TODO(JM) backward replacement of pointer logic with instance of gamsOptions
    GAMSOptions tmpOpt = GAMSOptions(mWs, gamsOptions);
    GAMSCheckpoint* tmpCP = nullptr;

    if (mCheckpointStart != nullptr)
        tmpOpt.setRestart(mCheckpointStart->fileName());

    if (checkpoint != nullptr) {
        if (mCheckpointStart != checkpoint) {
            tmpCP = new GAMSCheckpoint(mWs, "");
            tmpOpt.setSave(tmpCP->fileName());
        } else {
            tmpOpt.setSave(checkpoint->fileName());
        }
    }
    if (mWs.debug() >= GAMSEnum::DebugLevel::ShowLog) {
        tmpOpt.setLogOption(3);
    } else {
        // can only happen if we are called from GAMSModelInstance
        if (tmpOpt.logOption() != 2) {
            if (output == nullptr)
                tmpOpt.setLogOption(0);
            else
                tmpOpt.setLogOption(3);
        }
    }

    if (!databases.empty()) {
        for (GAMSDatabase db: databases) {
            db.doExport("");
            if (db.inModelName() != "")
                tmpOpt.setDefine(db.inModelName(), db.name());
        }
    }
    // TODO: c sharp, solver options
    //if (tmpOpt.SolverOptions.size() > size_t(0))
    //{
    //    for each (tuple<string, int> slvOpt in tmpOpt.SolverOptions)
    //    {
    //        string path = workspace.workingDirectory;
    //        path += PATHSEPERATOR;
    //        path += get<0>(slvOpt) + OptFileExtension(get<1>(slvOpt));
    //        optWriteParameterFile(tmpOpt.OPT, path.c_str()); // TODO: which OPT do we need here?
    //    }
    //        // TODO: continue: GAMSJob::run [l513]
    //}

    GAMSPath jobFileInfo(GAMSPath(mWs.workingDirectory()) / mJobName);

    // This has been set directly in the constructor
//    char buffer[GMS_SSSIZE];
//    for (int i = 1; i < gmoProc_nrofmodeltypes; i++)  // TODO(JM) change type of i to int and adapt casts
//        optSetStrStr(tmpOpt.optPtr(), cfgModelTypeName(tmpOpt.optPtr(), i, buffer), tmpOpt.SelectedSolvers[i].c_str());

    if (createOutDb && tmpOpt.gdx() == "") {
        tmpOpt.setGdx(mWs.nextDatabaseName());
    }
    if (tmpOpt.logFile() == "")
        tmpOpt.setLogFile(jobFileInfo.suffix(".log").toStdString());
    tmpOpt.setOutput(mJobName + ".lst");
    tmpOpt.setCurDir(mWs.workingDirectory());
    tmpOpt.setInput(mFileName);
    GAMSPath pfFileName = jobFileInfo.suffix(".pf");
    try {
        tmpOpt.writeOptionFile(pfFileName);
    } catch (GAMSException& e) {
        throw GAMSException(e.what() + (" for GAMSJob " + mJobName));
    }

    //TODO(CW): we might need to check if the GAMSJob is already running and avoid multiple starts. Also check this in C# an other languages

// TODO(RG): get result from runProcess
//    if (output && mWs.debug() >= GAMSEnum::DebugLevel::ShowLog)
//        MSG << result;
//    else if (output)
//        *output << result;

    if (createOutDb) {
        //TODO: should we always delete the outDB before a new run? Affects C#, Pytohn and Java as well
        //outdb = nullptr;
        GAMSPath gdxPath(tmpOpt.gdx());
        if (!gdxPath.is_absolute())
            gdxPath = GAMSPath(mWs.workingDirectory()) / gdxPath;
        gdxPath.setSuffix(".gdx");
        if (gdxPath.exists()) {
            mOutDb = mWs.addDatabaseFromGDXForcedName(gdxPath.toStdString(), gdxPath.suffix(""), "");
        }
    }
    GAMSPath gamsExe(mWs.systemDirectory());
    gamsExe / "gams"+cExeSuffix;
    qDebug() << "gamsexe" << gamsExe.string().c_str(); // rogo: delete

    string result;
    int exitCode = GAMSPlatform::runProcess(mWs.workingDirectory(), gamsExe.string(), mJobName, result);
    if (exitCode != 0) {
        if ((mWs.debug() < GAMSEnum::DebugLevel::KeepFiles) && mWs.usingTmpWorkingDir())
            throw GAMSExceptionExecution("GAMS return code not 0 (" + to_string(exitCode) +
                                         "), set GAMSWorkspace.Debug to KeepFiles or higher or define the \
                                         GAMSWorkspace.WorkingDirectory to receive a listing file with more details",
                                         exitCode);
        else
            throw GAMSExceptionExecution("GAMS return code not 0 (" + to_string(exitCode) + "), check " +
                                         (GAMSPath(mWs.workingDirectory()) / tmpOpt.output()).toStdString() +
                                         " for more details", exitCode);
    }

    if (tmpCP) {
        GAMSPath implFile(checkpoint->fileName());
        if (implFile.exists()) {
            implFile.remove();
        }
        implFile = tmpCP->fileName();
        implFile.rename(checkpoint->fileName());
        delete tmpCP; tmpCP=nullptr;
    }

    if (mWs.debug() < GAMSEnum::DebugLevel::KeepFiles)
    {
        try { GAMSPath(pfFileName).remove(); }
        catch(...) { }
    }
}

bool GAMSJobImpl::interrupt()
{
    //TODO(CW): implement for linux and mac
    /*qint64*/ int pid = 0 /*mProc.processId()*/; // TODO(RG): we need std process handling here
    if(pid == 0)
        return false;
    return GAMSPlatform::interrupt(pid);
}

}
<commit_msg>resolved todo related to runprocess output<commit_after>/*
 * GAMS - General Algebraic Modeling System C++ API
 *
 * Copyright (c) 2017-2020 GAMS Software GmbH <support@gams.com>
 * Copyright (c) 2017-2020 GAMS Development Corp. <support@gams.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "gamsjobimpl.h"
#include "gmomcc.h"
#include "gamscheckpoint.h"
#include "gamslog.h"
#include "gamsoptions.h"
#include "gamsplatform.h"
#include "gamspath.h"
#include "gamsexceptionexecution.h"

#include <sstream>
#include <fstream>
#include <iostream>
// rogo remove
#include <QDebug>

using namespace std;

namespace gams {

GAMSJobImpl::GAMSJobImpl(GAMSWorkspace workspace,
                         const std::string& jobName,
                         const std::string& fileName,
                         const GAMSCheckpoint* checkpoint)
    : mWs(workspace), mJobName(jobName), mFileName(fileName)
{
    DEB << "---- Entering GAMSJob constructor ----";
    if (checkpoint != nullptr) {
        if (!GAMSPath::exists(checkpoint->fileName()) )
            throw GAMSException("Checkpoint file " + checkpoint->fileName() + " does not exist");
        mCheckpointStart = new GAMSCheckpoint(*checkpoint);
    }
}

bool GAMSJobImpl::operator!=(const GAMSJobImpl& other) const
{
    return (mWs != other.mWs) || (mJobName != other.mJobName);
}

bool GAMSJobImpl::operator==(const GAMSJobImpl& other) const
{
    return !(operator!=(other));
}

GAMSDatabase GAMSJobImpl::outDB()
{
    return mOutDb;
}

GAMSJobImpl::~GAMSJobImpl() {
    if (mCheckpointStart != nullptr)
        delete mCheckpointStart; // this is intended to only free the wrapper, not the *Impl if used anywhere
}

// TODO(RG): what are these?
//   shared_ptr<GAMSJobImpl> GAMSJobImpl::fromString(GAMSWorkspace workspace, string gamsSource, const GAMSCheckpoint *checkpoint, string jobName)
//   {
//      shared_ptr<GAMSJobImpl> jobImpl = make_shared<GAMSJobImpl>(workspace, "", "", checkpoint);
//      if (jobName == "")
//         jobImpl->mJobName = workspace.mImpl->jobAdd();
//      else
//      {
//         jobImpl->mJobName = jobName;
//         if (!workspace.mImpl->jobAdd(jobImpl->mJobName))
//            throw GAMSException("Job with name " + jobName + " already exists");
//      }

//      jobImpl->mFileName = GPath(workspace.workingDirectory()) / (jobImpl->mJobName + ".gms");

//      std::ofstream sourceWriter(jobImpl->mFileName);
//      sourceWriter << gamsSource;
//      sourceWriter.close();

//      return jobImpl;
//   }

//   shared_ptr<GAMSJobImpl> GAMSJobImpl::fromFile(GAMSWorkspace workspace, string fileName, const GAMSCheckpoint *checkpoint, string jobName)
//   {
//      shared_ptr<GAMSJobImpl> jobImpl = make_shared<GAMSJobImpl>(workspace, "", "", checkpoint);
//      if (jobName == "")
//         jobImpl->mJobName = workspace.mImpl->jobAdd();
//      else
//      {
//         jobImpl->mJobName = jobName;
//         if (!workspace.mImpl->jobAdd(jobImpl->mJobName))
//            throw GAMSException("Job with name " + jobName + " already exists");
//      }
//      if (GPath(fileName).isAbsolute())
//         jobImpl->mFileName = fileName;
//      else
//         jobImpl->mFileName = GPath(workspace.workingDirectory()) / fileName;

//      if (!GPath::exists(jobImpl->mFileName))
//         throw GAMSException("Could not create GAMSJob instance from non-existing file [" + jobImpl->mFileName + "]");

//      return jobImpl;
//   }

// TODO(RG): check how "output" parameter was used in original version
void GAMSJobImpl::run(GAMSOptions* gamsOptions, GAMSCheckpoint* checkpoint, ostream* output, bool createOutDb,
                      vector<GAMSDatabase> databases)
{
    // TODO(JM) backward replacement of pointer logic with instance of gamsOptions
    GAMSOptions tmpOpt = GAMSOptions(mWs, gamsOptions);
    GAMSCheckpoint* tmpCP = nullptr;

    if (mCheckpointStart != nullptr)
        tmpOpt.setRestart(mCheckpointStart->fileName());

    if (checkpoint != nullptr) {
        if (mCheckpointStart != checkpoint) {
            tmpCP = new GAMSCheckpoint(mWs, "");
            tmpOpt.setSave(tmpCP->fileName());
        } else {
            tmpOpt.setSave(checkpoint->fileName());
        }
    }
    if (mWs.debug() >= GAMSEnum::DebugLevel::ShowLog) {
        tmpOpt.setLogOption(3);
    } else {
        // can only happen if we are called from GAMSModelInstance
        if (tmpOpt.logOption() != 2) {
            if (output == nullptr)
                tmpOpt.setLogOption(0);
            else
                tmpOpt.setLogOption(3);
        }
    }

    if (!databases.empty()) {
        for (GAMSDatabase db: databases) {
            db.doExport("");
            if (db.inModelName() != "")
                tmpOpt.setDefine(db.inModelName(), db.name());
        }
    }
    // TODO: c sharp, solver options
    //if (tmpOpt.SolverOptions.size() > size_t(0))
    //{
    //    for each (tuple<string, int> slvOpt in tmpOpt.SolverOptions)
    //    {
    //        string path = workspace.workingDirectory;
    //        path += PATHSEPERATOR;
    //        path += get<0>(slvOpt) + OptFileExtension(get<1>(slvOpt));
    //        optWriteParameterFile(tmpOpt.OPT, path.c_str()); // TODO: which OPT do we need here?
    //    }
    //        // TODO: continue: GAMSJob::run [l513]
    //}

    GAMSPath jobFileInfo(GAMSPath(mWs.workingDirectory()) / mJobName);

    // This has been set directly in the constructor
//    char buffer[GMS_SSSIZE];
//    for (int i = 1; i < gmoProc_nrofmodeltypes; i++)  // TODO(JM) change type of i to int and adapt casts
//        optSetStrStr(tmpOpt.optPtr(), cfgModelTypeName(tmpOpt.optPtr(), i, buffer), tmpOpt.SelectedSolvers[i].c_str());

    if (createOutDb && tmpOpt.gdx() == "") {
        tmpOpt.setGdx(mWs.nextDatabaseName());
    }
    if (tmpOpt.logFile() == "")
        tmpOpt.setLogFile(jobFileInfo.suffix(".log").toStdString());
    tmpOpt.setOutput(mJobName + ".lst");
    tmpOpt.setCurDir(mWs.workingDirectory());
    tmpOpt.setInput(mFileName);
    GAMSPath pfFileName = jobFileInfo.suffix(".pf");
    try {
        tmpOpt.writeOptionFile(pfFileName);
    } catch (GAMSException& e) {
        throw GAMSException(e.what() + (" for GAMSJob " + mJobName));
    }

    //TODO(CW): we might need to check if the GAMSJob is already running and avoid multiple starts. Also check this in C# an other languages
    if (createOutDb) {
        //TODO: should we always delete the outDB before a new run? Affects C#, Pytohn and Java as well
        //outdb = nullptr;
        GAMSPath gdxPath(tmpOpt.gdx());
        if (!gdxPath.is_absolute())
            gdxPath = GAMSPath(mWs.workingDirectory()) / gdxPath;
        gdxPath.setSuffix(".gdx");
        if (gdxPath.exists()) {
            mOutDb = mWs.addDatabaseFromGDXForcedName(gdxPath.toStdString(), gdxPath.suffix(""), "");
        }
    }
    GAMSPath gamsExe(mWs.systemDirectory());
    gamsExe / "gams"+cExeSuffix;
    qDebug() << "gamsexe" << gamsExe.string().c_str(); // rogo: delete

    string result;
    int exitCode = GAMSPlatform::runProcess(mWs.workingDirectory(), gamsExe.string(), mJobName, result);

    if (output && mWs.debug() >= GAMSEnum::DebugLevel::ShowLog)
        MSG << result;
    else if (output)
        *output << result;

    if (exitCode != 0) {
        if ((mWs.debug() < GAMSEnum::DebugLevel::KeepFiles) && mWs.usingTmpWorkingDir())
            throw GAMSExceptionExecution("GAMS return code not 0 (" + to_string(exitCode) +
                                         "), set GAMSWorkspace.Debug to KeepFiles or higher or define the \
                                         GAMSWorkspace.WorkingDirectory to receive a listing file with more details",
                                         exitCode);
        else
            throw GAMSExceptionExecution("GAMS return code not 0 (" + to_string(exitCode) + "), check " +
                                         (GAMSPath(mWs.workingDirectory()) / tmpOpt.output()).toStdString() +
                                         " for more details", exitCode);
    }

    if (tmpCP) {
        GAMSPath implFile(checkpoint->fileName());
        if (implFile.exists()) {
            implFile.remove();
        }
        implFile = tmpCP->fileName();
        implFile.rename(checkpoint->fileName());
        delete tmpCP; tmpCP=nullptr;
    }

    if (mWs.debug() < GAMSEnum::DebugLevel::KeepFiles)
    {
        try { GAMSPath(pfFileName).remove(); }
        catch(...) { }
    }
}

bool GAMSJobImpl::interrupt()
{
    //TODO(CW): implement for linux and mac
    /*qint64*/ int pid = 0 /*mProc.processId()*/; // TODO(RG): we need std process handling here
    if(pid == 0)
        return false;
    return GAMSPlatform::interrupt(pid);
}

}
<|endoftext|>


<commit_before>/***********************************************************************************************************************
 * Copyright (C) 2016 Andrew Zonenberg and contributors                                                                *
 *                                                                                *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General   *
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *
 * any later version.                                                                                *
 *                                                                                *
 * This program 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 for     *
 * more details.                                                                                *
 *                                                                                *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may   *
 * find one here:                                                                                *
 * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt                                                              *
 * or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA                                      *
 **********************************************************************************************************************/

#include "gp4par.h"

using namespace std;

int main(int argc, char* argv[])
{
	Severity console_verbosity = Severity::NOTICE;

	//Netlist file
	string fname = "";

	//Output file
	string ofname = "";

	//Action to take with unused pins;
	Greenpak4IOB::PullDirection unused_pull = Greenpak4IOB::PULL_NONE;
	Greenpak4IOB::PullStrength  unused_drive = Greenpak4IOB::PULL_1M;

	//Specifies whether we should increase drive current of pullups/downs during boot to reach a stable state faster
	bool ioPrecharge = false;

	//Specifies that we should disable the on-die charge pump for the analog IP
	bool disableChargePump = false;

	//Turns off the internal LDO and connects Vdd directly to Vcore
	bool ldoBypass = false;

	//Number of times to re-try the boot process
	int bootRetry = 1;

	//Target chip
	Greenpak4Device::GREENPAK4_PART part = Greenpak4Device::GREENPAK4_SLG46620;

	//Bitstream metadata
	unsigned int userid = 0;
	bool readProtect = false;

	//Parse command-line arguments
	for(int i=1; i<argc; i++)
	{
		string s(argv[i]);

		//Let the logger eat its args first
		if(ParseLoggerArguments(i, argc, argv, console_verbosity))
			continue;

		else if(s == "--help")
		{
			ShowUsage();
			return 0;
		}
		else if(s == "--version")
		{
			ShowVersion();
			return 0;
		}
		else if(s == "--unused-pull")
		{
			if(i+1 < argc)
			{
				string pull = argv[++i];
				if(pull == "down")
					unused_pull = Greenpak4IOB::PULL_DOWN;
				else if(pull == "up")
					unused_pull = Greenpak4IOB::PULL_UP;
				else if( (pull == "none") || (pull == "float") )
					unused_pull = Greenpak4IOB::PULL_NONE;
				else
				{
					printf("--unused-pull must be one of up, down, float, none\n");
					return 1;
				}
			}
			else
			{
				printf("--unused-pull requires an argument\n");
				return 1;
			}
		}
		else if(s == "--unused-drive")
		{
			if(i+1 < argc)
			{
				string drive = argv[++i];
				if(drive == "10k")
					unused_drive = Greenpak4IOB::PULL_10K;
				else if(drive == "100k")
					unused_drive = Greenpak4IOB::PULL_100K;
				else if(drive == "1M")
					unused_drive = Greenpak4IOB::PULL_1M;
				else
				{
					printf("--unused-drive must be one of 10k, 100k, 1M\n");
					return 1;
				}
			}
			else
			{
				printf("--unused-drive requires an argument\n");
				return 1;
			}
		}
		else if(s == "--usercode")
		{
			if(i+1 < argc)
				sscanf(argv[++i], "%x", &userid);
			else
			{
				printf("--usercode requires an argument\n");
				return 1;
			}
		}
		else if( (s == "--part") || (s == "-p") )
		{
			if(i+1 < argc)
			{
				int p;
				sscanf(argv[++i], "SLG%d", &p);

				switch(p)
				{
					case 46620:
						part = Greenpak4Device::GREENPAK4_SLG46620;
						break;

					case 46621:
						part = Greenpak4Device::GREENPAK4_SLG46621;
						break;

					case 46140:
						part = Greenpak4Device::GREENPAK4_SLG46140;
						break;

					default:
						printf("invalid part (supported: 46620, 46621, 46140)\n");
						return 1;
				}
			}
			else
			{
				printf("--usercode requires an argument\n");
				return 1;
			}
		}
		else if(s == "--read-protect")
			readProtect = true;
		else if(s == "--io-precharge")
			ioPrecharge = true;
		else if(s == "--disable-charge-pump")
			disableChargePump = true;
		else if(s == "--ldo-bypass")
			ldoBypass = true;
		else if(s == "--boot-retry")
		{
			if(i+1 < argc)
				bootRetry = atoi(argv[++i]);
			else
			{
				printf("--boot-retry requires an argument\n");
				return 1;
			}
		}
		else if(s == "-o" || s == "--output")
		{
			if(i+1 < argc)
				ofname = argv[++i];
			else
			{
				printf("--output requires an argument\n");
				return 1;
			}
		}

		//assume it's the netlist file if it'[s the first non-switch argument
		else if( (s[0] != '-') && (fname == "") )
			fname = s;

		else
		{
			printf("Unrecognized command-line argument \"%s\", use --help\n", s.c_str());
			return 1;
		}
	}

	//Netlist filenames must be specified
	if( (fname == "") || (ofname == "") )
	{
		ShowUsage();
		return 1;
	}

	//Set up logging
	g_log_sinks.emplace(g_log_sinks.begin(), new STDLogSink(console_verbosity));

	//Print header
	if(console_verbosity >= Severity::NOTICE)
		ShowVersion();

	//Print configuration
	LogNotice("\nDevice configuration:\n");
	{
		LogIndenter li;

		string dev = "<invalid>";
		switch(part)
		{
			case Greenpak4Device::GREENPAK4_SLG46620:
				dev = "SLG46620V";
				break;

			case Greenpak4Device::GREENPAK4_SLG46621:
				dev = "SLG46621V";
				break;

			case Greenpak4Device::GREENPAK4_SLG46140:
				dev = "SLG46140V";
				break;
		}

		LogNotice("Target device:   %s\n", dev.c_str());
		LogNotice("VCC range:       not yet implemented\n");

		string pull;
		string drive;

		switch(unused_pull)
		{
			case Greenpak4IOB::PULL_NONE:
				pull = "float";
				break;

			case Greenpak4IOB::PULL_DOWN:
				pull = "pull down with ";
				break;

			case Greenpak4IOB::PULL_UP:
				pull = "pull up with ";
				break;

			default:
				LogError("Invalid pull direction\n");
				return 1;
		}

		if(unused_pull != Greenpak4IOB::PULL_NONE)
		{
			switch(unused_drive)
			{
				case Greenpak4IOB::PULL_10K:
					drive = "10K";
					break;

				case Greenpak4IOB::PULL_100K:
					drive = "100K";
					break;

				case Greenpak4IOB::PULL_1M:
					drive = "1M";
					break;

				default:
					LogError("Invalid pull strength\n");
					return 1;
			}
		}

		LogNotice("Unused pins:     %s %s\n", pull.c_str(), drive.c_str());

		LogNotice("User ID code:    %02x\n", userid);
		LogNotice("Read protection: %s\n", readProtect ? "enabled" : "disabled");
		LogNotice("I/O precharge:   %s\n", ioPrecharge ? "enabled" : "disabled");
		LogNotice("Charge pump:     %s\n", disableChargePump ? "off" : "auto");
		LogNotice("LDO:             %s\n", ldoBypass ? "bypassed" : "enabled");
		LogNotice("Boot retry:      %d times\n", bootRetry);
	}

	//Parse the unplaced netlist
	LogNotice("\nLoading Yosys JSON file \"%s\".\n", fname.c_str());
	Greenpak4Netlist netlist(fname);
	if(!netlist.Validate())
		return 1;

	//Create the device and initialize all IO pins
	Greenpak4Device device(part, unused_pull, unused_drive);
	device.SetIOPrecharge(ioPrecharge);
	device.SetDisableChargePump(disableChargePump);
	device.SetLDOBypass(ldoBypass);
	device.SetNVMRetryCount(bootRetry);

	//Do the actual P&R
	LogNotice("\nSynthesizing top-level module \"%s\".\n", netlist.GetTopModule()->GetName().c_str());
	if(!DoPAR(&netlist, &device))
		return 1;

	//Write the final bitstream
	LogNotice("\nWriting final bitstream to output file \"%s\", using ID code 0x%x.\n",
		ofname.c_str(), (int)userid);
	{
		LogIndenter li;
		if(!device.WriteToFile(ofname, userid, readProtect))
			return 1;
	}

	//TODO: Static timing analysis
	LogNotice("\nStatic timing analysis: not yet implemented\n");

	return 0;
}

void ShowUsage()
{
	printf(//                                                                               v 80th column
		"Usage: gp4par -p part -o bitstream.txt netlist.json\n"
		"    --debug\n"
		"        Prints lots of internal debugging information.\n"
		"    --disable-charge-pump\n"
		"        Disables the on-die charge pump which powers the analog hard IP when the\n"
		"        supply voltage drops below 2.7V. Provided for completeness since the\n"
		"        Silego GUI lets you specify it; there's no obvious reason to use it.\n"
		"    --io-precharge\n"
		"        Hooks a 2K resistor in parallel with pullup/down resistors during POR.\n"
		"        This can help external capacitive loads to reach a stable voltage faster.\n"
		"    -l, --logfile        <file>\n"
		"        Causes verbose log messages to be written to <file>.\n"
		"    -L, --logfile-lines  <file>\n"
		"        Causes verbose log messages to be written to <file>, flushing after\n"
		"        each line.\n"
		"    --ldo-bypass\n"
		"        Disable the on-die LDO and use an external 1.8V Vdd as Vcore.\n"
		"        May cause device damage if set with higher Vdd supply.\n"
		"    -o, --output         <bitstream>\n"
		"        Writes bitstream into the specified file.\n"
		"    -p, --part\n"
		"        Specifies the part to target (SLG46620V, SLG46621V, or SLG46140V)\n"
		"    -q, --quiet\n"
		"        Causes only warnings and errors to be written to the console.\n"
		"        Specify twice to also silence warnings.\n"
		"    --unused-pull        [down|up|float]\n"
		"        Specifies direction to pull unused pins.\n"
		"    --unused-drive       [10k|100k|1m]\n"
		"        Specifies strength of pullup/down resistor on unused pins.\n"
		"    --verbose\n"
		"        Prints additional information about the design.\n");
}

void ShowVersion()
{
	printf(
		"GreenPAK 4 place-and-route by Andrew D. Zonenberg.\n"
		"\n"
		"License: LGPL v2.1+\n"
		"This is free software: you are free to change and redistribute it.\n"
		"There is NO WARRANTY, to the extent permitted by law.\n");
}
<commit_msg>gp4par: Fix copy/paste error in error message<commit_after>/***********************************************************************************************************************
 * Copyright (C) 2016 Andrew Zonenberg and contributors                                                                *
 *                                                                                *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General   *
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *
 * any later version.                                                                                *
 *                                                                                *
 * This program 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 for     *
 * more details.                                                                                *
 *                                                                                *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may   *
 * find one here:                                                                                *
 * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt                                                              *
 * or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA                                      *
 **********************************************************************************************************************/

#include "gp4par.h"

using namespace std;

int main(int argc, char* argv[])
{
	Severity console_verbosity = Severity::NOTICE;

	//Netlist file
	string fname = "";

	//Output file
	string ofname = "";

	//Action to take with unused pins;
	Greenpak4IOB::PullDirection unused_pull = Greenpak4IOB::PULL_NONE;
	Greenpak4IOB::PullStrength  unused_drive = Greenpak4IOB::PULL_1M;

	//Specifies whether we should increase drive current of pullups/downs during boot to reach a stable state faster
	bool ioPrecharge = false;

	//Specifies that we should disable the on-die charge pump for the analog IP
	bool disableChargePump = false;

	//Turns off the internal LDO and connects Vdd directly to Vcore
	bool ldoBypass = false;

	//Number of times to re-try the boot process
	int bootRetry = 1;

	//Target chip
	Greenpak4Device::GREENPAK4_PART part = Greenpak4Device::GREENPAK4_SLG46620;

	//Bitstream metadata
	unsigned int userid = 0;
	bool readProtect = false;

	//Parse command-line arguments
	for(int i=1; i<argc; i++)
	{
		string s(argv[i]);

		//Let the logger eat its args first
		if(ParseLoggerArguments(i, argc, argv, console_verbosity))
			continue;

		else if(s == "--help")
		{
			ShowUsage();
			return 0;
		}
		else if(s == "--version")
		{
			ShowVersion();
			return 0;
		}
		else if(s == "--unused-pull")
		{
			if(i+1 < argc)
			{
				string pull = argv[++i];
				if(pull == "down")
					unused_pull = Greenpak4IOB::PULL_DOWN;
				else if(pull == "up")
					unused_pull = Greenpak4IOB::PULL_UP;
				else if( (pull == "none") || (pull == "float") )
					unused_pull = Greenpak4IOB::PULL_NONE;
				else
				{
					printf("--unused-pull must be one of up, down, float, none\n");
					return 1;
				}
			}
			else
			{
				printf("--unused-pull requires an argument\n");
				return 1;
			}
		}
		else if(s == "--unused-drive")
		{
			if(i+1 < argc)
			{
				string drive = argv[++i];
				if(drive == "10k")
					unused_drive = Greenpak4IOB::PULL_10K;
				else if(drive == "100k")
					unused_drive = Greenpak4IOB::PULL_100K;
				else if(drive == "1M")
					unused_drive = Greenpak4IOB::PULL_1M;
				else
				{
					printf("--unused-drive must be one of 10k, 100k, 1M\n");
					return 1;
				}
			}
			else
			{
				printf("--unused-drive requires an argument\n");
				return 1;
			}
		}
		else if(s == "--usercode")
		{
			if(i+1 < argc)
				sscanf(argv[++i], "%x", &userid);
			else
			{
				printf("--usercode requires an argument\n");
				return 1;
			}
		}
		else if( (s == "--part") || (s == "-p") )
		{
			if(i+1 < argc)
			{
				int p;
				sscanf(argv[++i], "SLG%d", &p);

				switch(p)
				{
					case 46620:
						part = Greenpak4Device::GREENPAK4_SLG46620;
						break;

					case 46621:
						part = Greenpak4Device::GREENPAK4_SLG46621;
						break;

					case 46140:
						part = Greenpak4Device::GREENPAK4_SLG46140;
						break;

					default:
						printf("invalid part (supported: 46620, 46621, 46140)\n");
						return 1;
				}
			}
			else
			{
				printf("--part requires an argument\n");
				return 1;
			}
		}
		else if(s == "--read-protect")
			readProtect = true;
		else if(s == "--io-precharge")
			ioPrecharge = true;
		else if(s == "--disable-charge-pump")
			disableChargePump = true;
		else if(s == "--ldo-bypass")
			ldoBypass = true;
		else if(s == "--boot-retry")
		{
			if(i+1 < argc)
				bootRetry = atoi(argv[++i]);
			else
			{
				printf("--boot-retry requires an argument\n");
				return 1;
			}
		}
		else if(s == "-o" || s == "--output")
		{
			if(i+1 < argc)
				ofname = argv[++i];
			else
			{
				printf("--output requires an argument\n");
				return 1;
			}
		}

		//assume it's the netlist file if it'[s the first non-switch argument
		else if( (s[0] != '-') && (fname == "") )
			fname = s;

		else
		{
			printf("Unrecognized command-line argument \"%s\", use --help\n", s.c_str());
			return 1;
		}
	}

	//Netlist filenames must be specified
	if( (fname == "") || (ofname == "") )
	{
		ShowUsage();
		return 1;
	}

	//Set up logging
	g_log_sinks.emplace(g_log_sinks.begin(), new STDLogSink(console_verbosity));

	//Print header
	if(console_verbosity >= Severity::NOTICE)
		ShowVersion();

	//Print configuration
	LogNotice("\nDevice configuration:\n");
	{
		LogIndenter li;

		string dev = "<invalid>";
		switch(part)
		{
			case Greenpak4Device::GREENPAK4_SLG46620:
				dev = "SLG46620V";
				break;

			case Greenpak4Device::GREENPAK4_SLG46621:
				dev = "SLG46621V";
				break;

			case Greenpak4Device::GREENPAK4_SLG46140:
				dev = "SLG46140V";
				break;
		}

		LogNotice("Target device:   %s\n", dev.c_str());
		LogNotice("VCC range:       not yet implemented\n");

		string pull;
		string drive;

		switch(unused_pull)
		{
			case Greenpak4IOB::PULL_NONE:
				pull = "float";
				break;

			case Greenpak4IOB::PULL_DOWN:
				pull = "pull down with ";
				break;

			case Greenpak4IOB::PULL_UP:
				pull = "pull up with ";
				break;

			default:
				LogError("Invalid pull direction\n");
				return 1;
		}

		if(unused_pull != Greenpak4IOB::PULL_NONE)
		{
			switch(unused_drive)
			{
				case Greenpak4IOB::PULL_10K:
					drive = "10K";
					break;

				case Greenpak4IOB::PULL_100K:
					drive = "100K";
					break;

				case Greenpak4IOB::PULL_1M:
					drive = "1M";
					break;

				default:
					LogError("Invalid pull strength\n");
					return 1;
			}
		}

		LogNotice("Unused pins:     %s %s\n", pull.c_str(), drive.c_str());

		LogNotice("User ID code:    %02x\n", userid);
		LogNotice("Read protection: %s\n", readProtect ? "enabled" : "disabled");
		LogNotice("I/O precharge:   %s\n", ioPrecharge ? "enabled" : "disabled");
		LogNotice("Charge pump:     %s\n", disableChargePump ? "off" : "auto");
		LogNotice("LDO:             %s\n", ldoBypass ? "bypassed" : "enabled");
		LogNotice("Boot retry:      %d times\n", bootRetry);
	}

	//Parse the unplaced netlist
	LogNotice("\nLoading Yosys JSON file \"%s\".\n", fname.c_str());
	Greenpak4Netlist netlist(fname);
	if(!netlist.Validate())
		return 1;

	//Create the device and initialize all IO pins
	Greenpak4Device device(part, unused_pull, unused_drive);
	device.SetIOPrecharge(ioPrecharge);
	device.SetDisableChargePump(disableChargePump);
	device.SetLDOBypass(ldoBypass);
	device.SetNVMRetryCount(bootRetry);

	//Do the actual P&R
	LogNotice("\nSynthesizing top-level module \"%s\".\n", netlist.GetTopModule()->GetName().c_str());
	if(!DoPAR(&netlist, &device))
		return 1;

	//Write the final bitstream
	LogNotice("\nWriting final bitstream to output file \"%s\", using ID code 0x%x.\n",
		ofname.c_str(), (int)userid);
	{
		LogIndenter li;
		if(!device.WriteToFile(ofname, userid, readProtect))
			return 1;
	}

	//TODO: Static timing analysis
	LogNotice("\nStatic timing analysis: not yet implemented\n");

	return 0;
}

void ShowUsage()
{
	printf(//                                                                               v 80th column
		"Usage: gp4par -p part -o bitstream.txt netlist.json\n"
		"    --debug\n"
		"        Prints lots of internal debugging information.\n"
		"    --disable-charge-pump\n"
		"        Disables the on-die charge pump which powers the analog hard IP when the\n"
		"        supply voltage drops below 2.7V. Provided for completeness since the\n"
		"        Silego GUI lets you specify it; there's no obvious reason to use it.\n"
		"    --io-precharge\n"
		"        Hooks a 2K resistor in parallel with pullup/down resistors during POR.\n"
		"        This can help external capacitive loads to reach a stable voltage faster.\n"
		"    -l, --logfile        <file>\n"
		"        Causes verbose log messages to be written to <file>.\n"
		"    -L, --logfile-lines  <file>\n"
		"        Causes verbose log messages to be written to <file>, flushing after\n"
		"        each line.\n"
		"    --ldo-bypass\n"
		"        Disable the on-die LDO and use an external 1.8V Vdd as Vcore.\n"
		"        May cause device damage if set with higher Vdd supply.\n"
		"    -o, --output         <bitstream>\n"
		"        Writes bitstream into the specified file.\n"
		"    -p, --part\n"
		"        Specifies the part to target (SLG46620V, SLG46621V, or SLG46140V)\n"
		"    -q, --quiet\n"
		"        Causes only warnings and errors to be written to the console.\n"
		"        Specify twice to also silence warnings.\n"
		"    --unused-pull        [down|up|float]\n"
		"        Specifies direction to pull unused pins.\n"
		"    --unused-drive       [10k|100k|1m]\n"
		"        Specifies strength of pullup/down resistor on unused pins.\n"
		"    --verbose\n"
		"        Prints additional information about the design.\n");
}

void ShowVersion()
{
	printf(
		"GreenPAK 4 place-and-route by Andrew D. Zonenberg.\n"
		"\n"
		"License: LGPL v2.1+\n"
		"This is free software: you are free to change and redistribute it.\n"
		"There is NO WARRANTY, to the extent permitted by law.\n");
}
<|endoftext|>