<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: desktopbecdef.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: ihi $ $Date: 2006-08-04 12:28:17 $
 *
 *  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 _COM_SUN_STAR_CONFIGURATION_BACKEND_XSCHEMASUPPLIER_HPP_
#include <com/sun/star/configuration/backend/XSingleLayerStratum.hpp>
#endif

#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
#include <com/sun/star/registry/XRegistryKey.hpp>
#endif

#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
#include <cppuhelper/implementationentry.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#include "uno/current_context.hxx"

namespace css = com::sun::star ;
namespace uno = css::uno ;
namespace lang = css::lang ;
namespace backend = css::configuration::backend ;

//==============================================================================

static uno::Reference<uno::XInterface> SAL_CALL createDesktopBackend(const uno::Reference<uno::XComponentContext>& xContext)
{
    try {
        uno::Reference< uno::XCurrentContext > xCurrentContext(uno::getCurrentContext());

        if (xCurrentContext.is())
        {
            uno::Any aValue = xCurrentContext->getValueByName(
                rtl::OUString::createFromAscii( "system.desktop-environment" ) );

            rtl::OUString aDesktopEnvironment;
            if ( aValue >>= aDesktopEnvironment )
            {
                rtl::OUString aDesktopService;
                if ( aDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "gnome" ) )
                    aDesktopService = rtl::OUString::createFromAscii( "com.sun.star.configuration.backend.GconfBackend" );
                else if ( aDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "kde" ) )
                    aDesktopService = rtl::OUString::createFromAscii( "com.sun.star.configuration.backend.KDEBackend" );
                else
                    return uno::Reference<uno::XInterface>();

                uno::Reference< lang::XMultiComponentFactory > xServiceManager = xContext->getServiceManager();
                if( xServiceManager.is() )
                {
                    return uno::Reference< backend::XSingleLayerStratum >::query(
                            xServiceManager->createInstanceWithContext( aDesktopService, xContext) );
                }
            }
        }
    } catch (uno::RuntimeException e) {
    }

    return uno::Reference<uno::XInterface>();
}

static rtl::OUString SAL_CALL getBackendName(void) {
    return rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.configuration.backend.DesktopBackend") );
}

static uno::Sequence<rtl::OUString> SAL_CALL getBackendServiceNames(void)
{
    uno::Sequence<rtl::OUString> aServices(2) ;
    aServices[0] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.DesktopBackend")) ;
    aServices[1] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.PlatformBackend")) ;

    return aServices ;
}

static uno::Sequence<rtl::OUString> SAL_CALL getSupportedComponents(void)
{
    const sal_Int32 nComponents = 7;

    uno::Sequence<rtl::OUString> aSupportedComponentsList(nComponents) ;

    aSupportedComponentsList[0] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.VCL")) ;
    aSupportedComponentsList[1] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet")) ;
    aSupportedComponentsList[2] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common")) ;
    aSupportedComponentsList[3] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths")) ;

    aSupportedComponentsList[4] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.UserProfile")) ;
    aSupportedComponentsList[5] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Recovery")) ;
    aSupportedComponentsList[6] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")) ;

    return aSupportedComponentsList ;
}
//==============================================================================

static const cppu::ImplementationEntry kImplementations_entries[] =
{
    {
        createDesktopBackend,
        getBackendName,
        getBackendServiceNames,
        cppu::createSingleComponentFactory,
        NULL,
        0
    },
    { NULL, NULL, NULL, NULL, NULL, 0 }
} ;
//------------------------------------------------------------------------------

extern "C" void SAL_CALL component_getImplementationEnvironment(
                                            const sal_Char **aEnvTypeName,
                                            uno_Environment ** /* aEnvironment */)
{
    *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
}

//------------------------------------------------------------------------------

extern "C" sal_Bool SAL_CALL component_writeInfo(void * /* pServiceManager */,
                                                 void *pRegistryKey)
{
    using namespace ::com::sun::star::registry;
    if (pRegistryKey)
    {
        try
        {
            uno::Reference< XRegistryKey > xImplKey = static_cast< XRegistryKey* >( pRegistryKey )->createKey(
                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + getBackendName()
            );

            // Register associated service names
            uno::Reference< XRegistryKey > xServicesKey = xImplKey->createKey(
                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES") )
            );

            uno::Sequence<rtl::OUString> sServiceNames = getBackendServiceNames();
            for (sal_Int32 i = 0 ; i < sServiceNames.getLength() ; ++ i)
                xServicesKey->createKey(sServiceNames[i]);

            // Register supported components
            uno::Reference<XRegistryKey> xComponentKey = xImplKey->createKey(
                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/DATA/SupportedComponents") )
            );

            xComponentKey->setAsciiListValue( getSupportedComponents() );

            return sal_True;
        }

        catch( InvalidRegistryException& )
        {
            OSL_ENSURE(sal_False, "InvalidRegistryException caught");
        }
    }

    return sal_False;
}

//------------------------------------------------------------------------------

extern "C" void *component_getFactory(const sal_Char *aImplementationName,
                                      void *aServiceManager,
                                      void *aRegistryKey)
{
    return cppu::component_getFactoryHelper(
        aImplementationName,
        aServiceManager,
        aRegistryKey,
        kImplementations_entries) ;
}
//------------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS pchfix02 (1.2.6); FILE MERGED 2006/09/01 17:39:02 kaib 1.2.6.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: desktopbecdef.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 01:36:39 $
 *
 *  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_shell.hxx"

#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XSCHEMASUPPLIER_HPP_
#include <com/sun/star/configuration/backend/XSingleLayerStratum.hpp>
#endif

#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
#include <com/sun/star/registry/XRegistryKey.hpp>
#endif

#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
#include <cppuhelper/implementationentry.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#include "uno/current_context.hxx"

namespace css = com::sun::star ;
namespace uno = css::uno ;
namespace lang = css::lang ;
namespace backend = css::configuration::backend ;

//==============================================================================

static uno::Reference<uno::XInterface> SAL_CALL createDesktopBackend(const uno::Reference<uno::XComponentContext>& xContext)
{
    try {
        uno::Reference< uno::XCurrentContext > xCurrentContext(uno::getCurrentContext());

        if (xCurrentContext.is())
        {
            uno::Any aValue = xCurrentContext->getValueByName(
                rtl::OUString::createFromAscii( "system.desktop-environment" ) );

            rtl::OUString aDesktopEnvironment;
            if ( aValue >>= aDesktopEnvironment )
            {
                rtl::OUString aDesktopService;
                if ( aDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "gnome" ) )
                    aDesktopService = rtl::OUString::createFromAscii( "com.sun.star.configuration.backend.GconfBackend" );
                else if ( aDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "kde" ) )
                    aDesktopService = rtl::OUString::createFromAscii( "com.sun.star.configuration.backend.KDEBackend" );
                else
                    return uno::Reference<uno::XInterface>();

                uno::Reference< lang::XMultiComponentFactory > xServiceManager = xContext->getServiceManager();
                if( xServiceManager.is() )
                {
                    return uno::Reference< backend::XSingleLayerStratum >::query(
                            xServiceManager->createInstanceWithContext( aDesktopService, xContext) );
                }
            }
        }
    } catch (uno::RuntimeException e) {
    }

    return uno::Reference<uno::XInterface>();
}

static rtl::OUString SAL_CALL getBackendName(void) {
    return rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.configuration.backend.DesktopBackend") );
}

static uno::Sequence<rtl::OUString> SAL_CALL getBackendServiceNames(void)
{
    uno::Sequence<rtl::OUString> aServices(2) ;
    aServices[0] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.DesktopBackend")) ;
    aServices[1] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.PlatformBackend")) ;

    return aServices ;
}

static uno::Sequence<rtl::OUString> SAL_CALL getSupportedComponents(void)
{
    const sal_Int32 nComponents = 7;

    uno::Sequence<rtl::OUString> aSupportedComponentsList(nComponents) ;

    aSupportedComponentsList[0] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.VCL")) ;
    aSupportedComponentsList[1] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet")) ;
    aSupportedComponentsList[2] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common")) ;
    aSupportedComponentsList[3] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths")) ;

    aSupportedComponentsList[4] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.UserProfile")) ;
    aSupportedComponentsList[5] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Recovery")) ;
    aSupportedComponentsList[6] = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")) ;

    return aSupportedComponentsList ;
}
//==============================================================================

static const cppu::ImplementationEntry kImplementations_entries[] =
{
    {
        createDesktopBackend,
        getBackendName,
        getBackendServiceNames,
        cppu::createSingleComponentFactory,
        NULL,
        0
    },
    { NULL, NULL, NULL, NULL, NULL, 0 }
} ;
//------------------------------------------------------------------------------

extern "C" void SAL_CALL component_getImplementationEnvironment(
                                            const sal_Char **aEnvTypeName,
                                            uno_Environment ** /* aEnvironment */)
{
    *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
}

//------------------------------------------------------------------------------

extern "C" sal_Bool SAL_CALL component_writeInfo(void * /* pServiceManager */,
                                                 void *pRegistryKey)
{
    using namespace ::com::sun::star::registry;
    if (pRegistryKey)
    {
        try
        {
            uno::Reference< XRegistryKey > xImplKey = static_cast< XRegistryKey* >( pRegistryKey )->createKey(
                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + getBackendName()
            );

            // Register associated service names
            uno::Reference< XRegistryKey > xServicesKey = xImplKey->createKey(
                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES") )
            );

            uno::Sequence<rtl::OUString> sServiceNames = getBackendServiceNames();
            for (sal_Int32 i = 0 ; i < sServiceNames.getLength() ; ++ i)
                xServicesKey->createKey(sServiceNames[i]);

            // Register supported components
            uno::Reference<XRegistryKey> xComponentKey = xImplKey->createKey(
                rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/DATA/SupportedComponents") )
            );

            xComponentKey->setAsciiListValue( getSupportedComponents() );

            return sal_True;
        }

        catch( InvalidRegistryException& )
        {
            OSL_ENSURE(sal_False, "InvalidRegistryException caught");
        }
    }

    return sal_False;
}

//------------------------------------------------------------------------------

extern "C" void *component_getFactory(const sal_Char *aImplementationName,
                                      void *aServiceManager,
                                      void *aRegistryKey)
{
    return cppu::component_getFactoryHelper(
        aImplementationName,
        aServiceManager,
        aRegistryKey,
        kImplementations_entries) ;
}
//------------------------------------------------------------------------------
<|endoftext|>


<commit_before><commit_msg>WW8DocumentImpl::utext: Call delegates utext instead of text<commit_after><|endoftext|>


<commit_before>#include "astutil.h"
#include "bb.h"
#include "expr.h"
#include "passes.h"
#include "stmt.h"
#include "symbol.h"
#include "symscope.h"

static Map<Type*,FnSymbol*> freeMap;  // map of types to _free functions
static Map<Type*,FnSymbol*> touchMap; // map of types to _touch functions

//
// insertGCTemps inserts two sets of temporaries: (1) temporary
// variables (_gc_ret_tmp) to capture the return results of all
// functions that return a value other than void but that are not
// captured; this is necessary because the symbol that is returned is
// not freed, relying instead on the free of the symbol at the call
// site that captures this value, and (2) temporary variables
// (_gc_norm_tmp) to capture the rhs of a move if the symbol on the
// lhs is part of the rhs since otherwise a free of the lhs symbol
// would potentially free it before it is used on the rhs
//
static void
insertMissingReturnTemps() {
  forv_Vec(BaseAST, ast, gAsts) {
    if (CallExpr* call = dynamic_cast<CallExpr*>(ast)) {
      if (FnSymbol* fn = call->isResolved()) {
        if (fn->retType != dtVoid) {
          CallExpr* parent = dynamic_cast<CallExpr*>(call->parentExpr);
          if (!parent) { // no move
            VarSymbol* tmp = new VarSymbol("_gc_ret_tmp", fn->retType);
            DefExpr* def = new DefExpr(tmp);
            call->insertBefore(def);
            def->insertAfter(new CallExpr(PRIMITIVE_MOVE, tmp, call->remove()));
          }
        }
      } else if (call->isPrimitive(PRIMITIVE_MOVE)) {
        if (Symbol* lhs = dynamic_cast<SymExpr*>(call->get(1))->var) {
          if (CallExpr* rhs = dynamic_cast<CallExpr*>(call->get(2))) {
            bool requires_temp = false;
            for_actuals(actual, rhs) {
              if (SymExpr* sym = dynamic_cast<SymExpr*>(actual)) {
                if (sym->var == lhs) {
                  requires_temp = true;
                }
              }
            }
            if (requires_temp) {
              VarSymbol* tmp = new VarSymbol("_gc_norm_tmp", lhs->type);
              DefExpr* def = new DefExpr(tmp);
              call->insertBefore(def);
              call->insertBefore(new CallExpr(PRIMITIVE_MOVE, tmp, rhs->remove()));
              call->insertAtTail(new SymExpr(tmp));
            }
          }
        }
      }
    }
  }
}

static bool
disableReferences(Symbol* sym) {
  if (VarSymbol* var = dynamic_cast<VarSymbol*>(sym))
    if (var->is_ref || var->on_heap)
      return true;
  return false;
}

//
// isReferenceCounted(type) returns true if the type uses reference
// counting to free its associated dynamic memory
//
static bool
isReferenceCounted(Type* t) {
  if (ClassType* ct = dynamic_cast<ClassType*>(t))
    if (ct->classTag == CLASS_CLASS)
      return true;
  return false;
}

//
// buildFreeFunctions() builds _free functions for all structured
// types
//
static void
insertSubclassFrees(ClassType* ct, FnSymbol* fn, ArgSymbol* arg, Symbol* ret) {
  forv_Vec(Type, t, ct->dispatchChildren) {
    if (ClassType* sct = dynamic_cast<ClassType*>(t)) {
      BlockStmt* block = new BlockStmt();
      VarSymbol* tmp = new VarSymbol("tmp", sct);
      block->insertAtTail(new DefExpr(tmp));
      block->insertAtTail(new CallExpr(PRIMITIVE_MOVE, tmp, new CallExpr(PRIMITIVE_CAST, sct->symbol, arg)));
      block->insertAtTail(new CallExpr(freeMap.get(sct), tmp));
      block->insertAtTail(new GotoStmt(goto_normal, ret));
      fn->body->body->head->insertAfter(new CondStmt(new CallExpr(PRIMITIVE_GETCID, arg, new_IntSymbol(sct->id)), block));
    }
  }
}

static void
buildFreeFunctions() {
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      FnSymbol* fn = new FnSymbol("_free");
      fn->retType = dtVoid;
      ArgSymbol* arg = new ArgSymbol(INTENT_REF, "a", ct);
      fn->insertFormalAtTail(arg);
      if (isReferenceCounted(ct)) {
        fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_CLASS_NULL, arg),
                                      new ReturnStmt()));
        fn->insertAtTail(new CallExpr(PRIMITIVE_GC_FREE, arg));
        fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_GC_ISPOS, arg),
                                      new ReturnStmt()));
        fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_GC_ISNEG, arg),
                                      new CallExpr(PRIMITIVE_INT_ERROR)));
      }
      type->defPoint->getModule()->stmts->insertAtTail(new DefExpr(fn));
      normalize(fn);
      freeMap.put(ct, fn);
    }
  }
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      FnSymbol* fn = freeMap.get(ct);
      ArgSymbol* arg = fn->getFormal(1);
      Symbol* ret = fn->getReturnLabel();
      if (ct->classTag == CLASS_CLASS)
        insertSubclassFrees(ct, fn, arg, ret);
      for_fields(field, ct) {
        if (!disableReferences(field))
          if (FnSymbol* fieldFree = freeMap.get(field->type))
            fn->insertBeforeReturn(
              new CallExpr(fieldFree,
                new CallExpr(PRIMITIVE_GET_MEMBER_VALUE, arg, field)));
      }
      if (ct->symbol->hasPragma("data class"))
        fn->insertBeforeReturn(new CallExpr(PRIMITIVE_ARRAY_FREE, arg));
      if (isReferenceCounted(ct))
        fn->insertBeforeReturn(new CallExpr(PRIMITIVE_CHPL_FREE, arg));
    }
  }
}

//
// buildTouchFunctions() builds _touch functions for all structured
// types
//
static void
buildTouchFunctions() {
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      FnSymbol* fn = new FnSymbol("_touch");
      fn->retType = dtVoid;
      ArgSymbol* arg = new ArgSymbol(INTENT_REF, "a", ct);
      fn->insertFormalAtTail(arg);
      if (ct->classTag == CLASS_CLASS) {
        fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_CLASS_NULL, arg),
                                      new ReturnStmt()));
        fn->insertAtTail(new CallExpr(PRIMITIVE_GC_TOUCH, arg));
      }
      type->defPoint->getModule()->stmts->insertAtTail(new DefExpr(fn));
      normalize(fn);
      touchMap.put(ct, fn);
    }
  }
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      if (!isReferenceCounted(ct)) {
        FnSymbol* fn = touchMap.get(ct);
        ArgSymbol* arg = fn->getFormal(1);
        for_fields(field, ct) {
          if (FnSymbol* fieldTouch = touchMap.get(field->type))
            fn->insertBeforeReturn(
              new CallExpr(fieldTouch,
                new CallExpr(PRIMITIVE_GET_MEMBER_VALUE, arg, field)));
        }
      }
    }
  }
}

static bool
requiresTouch(Expr* expr) {
  if (CallExpr* call = dynamic_cast<CallExpr*>(expr)) {
    if (FnSymbol* fn = call->isResolved()) {
      if (!fn->getReturnSymbol()->isReference)
        return false;
    }
  }
  return true;
}

static void
insertGCInits(void) {
  forv_Vec(BaseAST, ast, gAsts) {
    if (CallExpr* call = dynamic_cast<CallExpr*>(ast)) {
      if (call->isPrimitive(PRIMITIVE_CHPL_ALLOC)) {
        if (CallExpr* parent = dynamic_cast<CallExpr*>(call->parentExpr)) {
          if (parent->isPrimitive(PRIMITIVE_MOVE)) {
            if (SymExpr* sym = dynamic_cast<SymExpr*>(parent->get(1))) {
              if (isReferenceCounted(sym->var->type)) {
                parent->insertAfter(new CallExpr(PRIMITIVE_GC_INIT, sym->copy()));
              }
            }
          }
        }
      }
    }
  }
}

void memoryManage(void) {
  if (!free_memory)
    return;
  insertMissingReturnTemps();
  buildFreeFunctions();
  buildTouchFunctions();

  forv_Vec(FnSymbol, fn, gFns) {
    Vec<BaseAST*> asts;
    collect_asts(&asts, fn->body);
    forv_Vec(BaseAST, ast, asts) {
      if (CallExpr* call = dynamic_cast<CallExpr*>(ast)) {
        if (call->isPrimitive(PRIMITIVE_MOVE)) {
          if (Symbol* lhs = dynamic_cast<SymExpr*>(call->get(1))->var) {
            if (!disableReferences(lhs)) // disable on_heap/is_ref
              if (FnSymbol* _free = freeMap.get(lhs->type))
                call->insertBefore(new CallExpr(_free, lhs));
            if (FnSymbol* _touch = touchMap.get(lhs->type))
              if (!disableReferences(lhs)) // disable on_heap/is_ref
                if (requiresTouch(call->get(2)))
                  call->insertAfter(new CallExpr(_touch, lhs));
          }
        } else if (call->isPrimitive(PRIMITIVE_SET_MEMBER)) {
          if (Symbol* lhs = dynamic_cast<SymExpr*>(call->get(3))->var) {
            if (FnSymbol* _free = freeMap.get(lhs->type))
              if (fn->fnClass != FN_CONSTRUCTOR) // first set
                call->insertBefore(
                  new CallExpr(_free,
                    new CallExpr(PRIMITIVE_GET_MEMBER_VALUE,
                                 call->get(1)->copy(),
                                 call->get(2)->copy())));
            if (FnSymbol* _touch = touchMap.get(lhs->type))
              call->insertAfter(
                new CallExpr(_touch,
                  new CallExpr(PRIMITIVE_GET_MEMBER_VALUE,
                               call->get(1)->copy(),
                               call->get(2)->copy())));
          }
        }
      }
    }

    // Insert _free call on all local variables except the returned one
    if (fn->getModule()->initFn != fn) {
      forv_Vec(BaseAST, ast, asts) {
        if (DefExpr* def = dynamic_cast<DefExpr*>(ast))
          if (VarSymbol* var = dynamic_cast<VarSymbol*>(def->sym))
            if (!disableReferences(var)) // disable on_heap/is_ref
              if (!var->isReference) // do not free aliases
                if (FnSymbol* _free = freeMap.get(var->type))
                  if (fn->getReturnSymbol() != var)
                    fn->insertBeforeReturnAfterLabel(new CallExpr(_free, var));
      }
    }
  }
  freeMap.clear();
  touchMap.clear();
  insertGCInits();
}
<commit_msg>Added code so that we only build _free and _touch functions on types that require them.  Previously we built these functions on all classes and records.  We now build them on all classes but not on all records. We only build them on records if some field in the record is a type that has a _free function.<commit_after>#include "astutil.h"
#include "bb.h"
#include "expr.h"
#include "passes.h"
#include "stmt.h"
#include "symbol.h"
#include "symscope.h"

static Map<Type*,FnSymbol*> freeMap;  // map of types to _free functions
static Map<Type*,FnSymbol*> touchMap; // map of types to _touch functions

//
// insertGCTemps inserts two sets of temporaries: (1) temporary
// variables (_gc_ret_tmp) to capture the return results of all
// functions that return a value other than void but that are not
// captured; this is necessary because the symbol that is returned is
// not freed, relying instead on the free of the symbol at the call
// site that captures this value, and (2) temporary variables
// (_gc_norm_tmp) to capture the rhs of a move if the symbol on the
// lhs is part of the rhs since otherwise a free of the lhs symbol
// would potentially free it before it is used on the rhs
//
static void
insertMissingReturnTemps() {
  forv_Vec(BaseAST, ast, gAsts) {
    if (CallExpr* call = dynamic_cast<CallExpr*>(ast)) {
      if (FnSymbol* fn = call->isResolved()) {
        if (fn->retType != dtVoid) {
          CallExpr* parent = dynamic_cast<CallExpr*>(call->parentExpr);
          if (!parent) { // no move
            VarSymbol* tmp = new VarSymbol("_gc_ret_tmp", fn->retType);
            DefExpr* def = new DefExpr(tmp);
            call->insertBefore(def);
            def->insertAfter(new CallExpr(PRIMITIVE_MOVE, tmp, call->remove()));
          }
        }
      } else if (call->isPrimitive(PRIMITIVE_MOVE)) {
        if (Symbol* lhs = dynamic_cast<SymExpr*>(call->get(1))->var) {
          if (CallExpr* rhs = dynamic_cast<CallExpr*>(call->get(2))) {
            bool requires_temp = false;
            for_actuals(actual, rhs) {
              if (SymExpr* sym = dynamic_cast<SymExpr*>(actual)) {
                if (sym->var == lhs) {
                  requires_temp = true;
                }
              }
            }
            if (requires_temp) {
              VarSymbol* tmp = new VarSymbol("_gc_norm_tmp", lhs->type);
              DefExpr* def = new DefExpr(tmp);
              call->insertBefore(def);
              call->insertBefore(new CallExpr(PRIMITIVE_MOVE, tmp, rhs->remove()));
              call->insertAtTail(new SymExpr(tmp));
            }
          }
        }
      }
    }
  }
}

static bool
disableReferences(Symbol* sym) {
  if (VarSymbol* var = dynamic_cast<VarSymbol*>(sym))
    if (var->is_ref || var->on_heap)
      return true;
  return false;
}

//
// isReferenceCounted(type) returns true if the type uses reference
// counting to free its associated dynamic memory
//
static bool
isReferenceCounted(Type* t) {
  if (ClassType* ct = dynamic_cast<ClassType*>(t))
    if (ct->classTag == CLASS_CLASS)
      return true;
  return false;
}

//
// buildFreeFunctions() builds _free functions for all structured
// types
//
static void
insertSubclassFrees(ClassType* ct, FnSymbol* fn, ArgSymbol* arg, Symbol* ret) {
  forv_Vec(Type, t, ct->dispatchChildren) {
    if (ClassType* sct = dynamic_cast<ClassType*>(t)) {
      BlockStmt* block = new BlockStmt();
      VarSymbol* tmp = new VarSymbol("tmp", sct);
      block->insertAtTail(new DefExpr(tmp));
      block->insertAtTail(new CallExpr(PRIMITIVE_MOVE, tmp, new CallExpr(PRIMITIVE_CAST, sct->symbol, arg)));
      block->insertAtTail(new CallExpr(freeMap.get(sct), tmp));
      block->insertAtTail(new GotoStmt(goto_normal, ret));
      fn->body->body->head->insertAfter(new CondStmt(new CallExpr(PRIMITIVE_GETCID, arg, new_IntSymbol(sct->id)), block));
    }
  }
}

static bool
requiresFreeFunction(ClassType* ct) {
  if (freeMap.get(ct))
    return false;
  if (ct->classTag == CLASS_CLASS)
    return true;
  for_fields(field, ct) {
    if (freeMap.get(field->type))
      return true;
  }
  return false;
}

static void
buildFreeFunctions() {
  bool change = true;
  while (change) {
    change = false;
    forv_Vec(TypeSymbol, type, gTypes) {
      if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
        if (requiresFreeFunction(ct)) {
          FnSymbol* fn = new FnSymbol("_free");
          fn->retType = dtVoid;
          ArgSymbol* arg = new ArgSymbol(INTENT_REF, "a", ct);
          fn->insertFormalAtTail(arg);
          if (isReferenceCounted(ct)) {
            fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_CLASS_NULL, arg),
                                          new ReturnStmt()));
            fn->insertAtTail(new CallExpr(PRIMITIVE_GC_FREE, arg));
            fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_GC_ISPOS, arg),
                                          new ReturnStmt()));
            fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_GC_ISNEG, arg),
                                          new CallExpr(PRIMITIVE_INT_ERROR)));
          }
          type->defPoint->getModule()->stmts->insertAtTail(new DefExpr(fn));
          normalize(fn);
          freeMap.put(ct, fn);
          change = true;
        }
      }
    }
  }
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      if (FnSymbol* fn = freeMap.get(ct)) {
        ArgSymbol* arg = fn->getFormal(1);
        Symbol* ret = fn->getReturnLabel();
        if (ct->classTag == CLASS_CLASS)
          insertSubclassFrees(ct, fn, arg, ret);
        for_fields(field, ct) {
          if (!disableReferences(field))
            if (FnSymbol* fieldFree = freeMap.get(field->type))
              fn->insertBeforeReturn(
                new CallExpr(fieldFree,
                  new CallExpr(PRIMITIVE_GET_MEMBER_VALUE, arg, field)));
        }
        if (ct->symbol->hasPragma("data class"))
          fn->insertBeforeReturn(new CallExpr(PRIMITIVE_ARRAY_FREE, arg));
        if (isReferenceCounted(ct))
          fn->insertBeforeReturn(new CallExpr(PRIMITIVE_CHPL_FREE, arg));
      }
    }
  }
}

//
// buildTouchFunctions() builds _touch functions for all structured
// types
//
static void
buildTouchFunctions() {
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      if (freeMap.get(ct)) {
        FnSymbol* fn = new FnSymbol("_touch");
        fn->retType = dtVoid;
        ArgSymbol* arg = new ArgSymbol(INTENT_REF, "a", ct);
        fn->insertFormalAtTail(arg);
        if (ct->classTag == CLASS_CLASS) {
          fn->insertAtTail(new CondStmt(new CallExpr(PRIMITIVE_CLASS_NULL, arg),
                                        new ReturnStmt()));
          fn->insertAtTail(new CallExpr(PRIMITIVE_GC_TOUCH, arg));
        }
        type->defPoint->getModule()->stmts->insertAtTail(new DefExpr(fn));
        normalize(fn);
        touchMap.put(ct, fn);
      }
    }
  }
  forv_Vec(TypeSymbol, type, gTypes) {
    if (ClassType* ct = dynamic_cast<ClassType*>(type->type)) {
      if (!isReferenceCounted(ct)) {
        if (FnSymbol* fn = touchMap.get(ct)) {
          ArgSymbol* arg = fn->getFormal(1);
          for_fields(field, ct) {
            if (FnSymbol* fieldTouch = touchMap.get(field->type))
              fn->insertBeforeReturn(
                new CallExpr(fieldTouch,
                  new CallExpr(PRIMITIVE_GET_MEMBER_VALUE, arg, field)));
          }
        }
      }
    }
  }
}

static bool
requiresTouch(Expr* expr) {
  if (CallExpr* call = dynamic_cast<CallExpr*>(expr)) {
    if (FnSymbol* fn = call->isResolved()) {
      if (!fn->getReturnSymbol()->isReference)
        return false;
    }
  }
  return true;
}

static void
insertGCInits(void) {
  forv_Vec(BaseAST, ast, gAsts) {
    if (CallExpr* call = dynamic_cast<CallExpr*>(ast)) {
      if (call->isPrimitive(PRIMITIVE_CHPL_ALLOC)) {
        if (CallExpr* parent = dynamic_cast<CallExpr*>(call->parentExpr)) {
          if (parent->isPrimitive(PRIMITIVE_MOVE)) {
            if (SymExpr* sym = dynamic_cast<SymExpr*>(parent->get(1))) {
              if (isReferenceCounted(sym->var->type)) {
                parent->insertAfter(new CallExpr(PRIMITIVE_GC_INIT, sym->copy()));
              }
            }
          }
        }
      }
    }
  }
}

void memoryManage(void) {
  if (!free_memory)
    return;
  insertMissingReturnTemps();
  buildFreeFunctions();
  buildTouchFunctions();

  forv_Vec(FnSymbol, fn, gFns) {
    Vec<BaseAST*> asts;
    collect_asts(&asts, fn->body);
    forv_Vec(BaseAST, ast, asts) {
      if (CallExpr* call = dynamic_cast<CallExpr*>(ast)) {
        if (call->isPrimitive(PRIMITIVE_MOVE)) {
          if (Symbol* lhs = dynamic_cast<SymExpr*>(call->get(1))->var) {
            if (!disableReferences(lhs)) // disable on_heap/is_ref
              if (FnSymbol* _free = freeMap.get(lhs->type))
                call->insertBefore(new CallExpr(_free, lhs));
            if (FnSymbol* _touch = touchMap.get(lhs->type))
              if (!disableReferences(lhs)) // disable on_heap/is_ref
                if (requiresTouch(call->get(2)))
                  call->insertAfter(new CallExpr(_touch, lhs));
          }
        } else if (call->isPrimitive(PRIMITIVE_SET_MEMBER)) {
          if (Symbol* lhs = dynamic_cast<SymExpr*>(call->get(3))->var) {
            if (FnSymbol* _free = freeMap.get(lhs->type))
              if (fn->fnClass != FN_CONSTRUCTOR) // first set
                call->insertBefore(
                  new CallExpr(_free,
                    new CallExpr(PRIMITIVE_GET_MEMBER_VALUE,
                                 call->get(1)->copy(),
                                 call->get(2)->copy())));
            if (FnSymbol* _touch = touchMap.get(lhs->type))
              call->insertAfter(
                new CallExpr(_touch,
                  new CallExpr(PRIMITIVE_GET_MEMBER_VALUE,
                               call->get(1)->copy(),
                               call->get(2)->copy())));
          }
        }
      }
    }

    // Insert _free call on all local variables except the returned one
    if (fn->getModule()->initFn != fn) {
      forv_Vec(BaseAST, ast, asts) {
        if (DefExpr* def = dynamic_cast<DefExpr*>(ast))
          if (VarSymbol* var = dynamic_cast<VarSymbol*>(def->sym))
            if (!disableReferences(var)) // disable on_heap/is_ref
              if (!var->isReference) // do not free aliases
                if (FnSymbol* _free = freeMap.get(var->type))
                  if (fn->getReturnSymbol() != var)
                    fn->insertBeforeReturnAfterLabel(new CallExpr(_free, var));
      }
    }
  }
  freeMap.clear();
  touchMap.clear();
  insertGCInits();
}
<|endoftext|>


<commit_before>#include <mantella_bits/helper/geometry.hpp>

// C++ Standard Library
#include <stdexcept>
#include <cmath>

namespace mant {
  arma::Mat<double>::fixed<2, 2> get2DRotationMatrix(
      const double& angle) noexcept {
    double sinAngle = std::sin(angle);
    double cosAngle = std::cos(angle);

    return arma::Mat<double>::fixed<2, 2>({
      cosAngle, -sinAngle,
      sinAngle,  cosAngle
    });
  }

  // TODO Left or right hand side implementation?
  arma::Mat<double>::fixed<3, 3> get3DRotationMatrix(
      const double& rollAngle,
      const double& pitchAngle,
      const double& yawAngle) noexcept {
    double sinRollAngle = std::sin(rollAngle);
    double cosRollAngle = std::cos(rollAngle);
    double sinPitchAngle = std::sin(pitchAngle);
    double cosPitchAngle = std::cos(pitchAngle);
    double sinYawAngle = std::sin(yawAngle);
    double cosYawAngle = std::cos(yawAngle);

    // Avoids Rz*Ry*Rx, as this will suffer from singularities.
    return arma::Mat<double>::fixed<3, 3>({
      cosYawAngle * cosPitchAngle, cosYawAngle * sinPitchAngle * sinRollAngle - sinYawAngle * cosRollAngle, cosYawAngle * sinPitchAngle * cosRollAngle + sinYawAngle * sinRollAngle,
      sinYawAngle * cosPitchAngle, sinYawAngle * sinPitchAngle * sinRollAngle + cosYawAngle * cosRollAngle, sinYawAngle * sinPitchAngle * cosRollAngle - cosYawAngle * sinRollAngle,
                   -sinPitchAngle,                                            cosPitchAngle * sinRollAngle,                                            cosPitchAngle * cosRollAngle
    });
  }

  arma::Col<double>::fixed<2> getCircleCircleIntersection(
      const arma::Col<double>::fixed<2>& firstCenter,
      const double& firstRadius,
      const arma::Col<double>::fixed<2>& secondCenter,
      const double& secondRadius) {
    double distance = arma::norm(secondCenter - firstCenter);

    if (distance == 0 || distance >= firstRadius + secondRadius || distance <= std::max(firstRadius, secondRadius) - std::min(firstRadius, secondRadius)) {
      throw std::runtime_error("Only intersections with exactly two intersections are considered valid.");
    }

    double cosine = (std::pow(firstRadius, 2) - std::pow(secondRadius, 2) + std::pow(distance, 2)) / (2 * distance);
    double sine = std::sqrt(std::pow(firstRadius, 2) - std::pow(cosine, 2));

    arma::Col<double>::fixed<2> normal = arma::normalise(secondCenter - firstCenter);

    return firstCenter + arma::Col<double>::fixed<2>({
      normal.at(0) * cosine + normal.at(1) * sine,
      normal.at(1) * cosine - normal.at(0) * sine
    });
  }

  arma::Col<double>::fixed<3> getCircleSphereIntersection(
      const arma::Col<double>::fixed<3>& circleCenter,
      const double& circleRadius,
      const arma::Col<double>::fixed<3>& circleNormal,
      const arma::Col<double>::fixed<3>& sphereCenter,
      const double& sphereRadius) {
    // Distance between the spheres center and the intersection circle within the sphere
    double innerDistance = arma::dot(circleNormal, sphereCenter - circleCenter);

    if (std::abs(innerDistance) >= sphereRadius) {
      throw std::runtime_error("Only intersections with exactly two intersections are considered valid.");
    }

    arma::Col<double>::fixed<3> innerCenter = sphereCenter + innerDistance * circleNormal;
    double innerRadius = std::sqrt(std::pow(sphereRadius, 2) - std::pow(innerDistance, 2));
    arma::Col<double>::fixed<3> normal = arma::normalise(arma::cross(innerCenter - circleCenter, circleNormal));

    double distance = arma::norm(innerCenter - circleCenter);
    double intersectionDistance = (std::pow(circleRadius, 2) - std::pow(innerRadius, 2) + std::pow(distance, 2)) / (2 * distance);

    return circleCenter + intersectionDistance / distance * (innerCenter - circleCenter) + normal * std::sqrt(std::pow(circleRadius, 2) - std::pow(intersectionDistance, 2));
  }
}
<commit_msg>doc: This should be a left hand-side implementation<commit_after>#include <mantella_bits/helper/geometry.hpp>

// C++ Standard Library
#include <stdexcept>
#include <cmath>

namespace mant {
  arma::Mat<double>::fixed<2, 2> get2DRotationMatrix(
      const double& angle) noexcept {
    double sinAngle = std::sin(angle);
    double cosAngle = std::cos(angle);

    return arma::Mat<double>::fixed<2, 2>({
      cosAngle, -sinAngle,
      sinAngle,  cosAngle
    });
  }

  arma::Mat<double>::fixed<3, 3> get3DRotationMatrix(
      const double& rollAngle,
      const double& pitchAngle,
      const double& yawAngle) noexcept {
    double sinRollAngle = std::sin(rollAngle);
    double cosRollAngle = std::cos(rollAngle);
    double sinPitchAngle = std::sin(pitchAngle);
    double cosPitchAngle = std::cos(pitchAngle);
    double sinYawAngle = std::sin(yawAngle);
    double cosYawAngle = std::cos(yawAngle);

    // Avoids Rz*Ry*Rx, as this will suffer from singularities.
    return arma::Mat<double>::fixed<3, 3>({
      cosYawAngle * cosPitchAngle, cosYawAngle * sinPitchAngle * sinRollAngle - sinYawAngle * cosRollAngle, cosYawAngle * sinPitchAngle * cosRollAngle + sinYawAngle * sinRollAngle,
      sinYawAngle * cosPitchAngle, sinYawAngle * sinPitchAngle * sinRollAngle + cosYawAngle * cosRollAngle, sinYawAngle * sinPitchAngle * cosRollAngle - cosYawAngle * sinRollAngle,
                   -sinPitchAngle,                                            cosPitchAngle * sinRollAngle,                                            cosPitchAngle * cosRollAngle
    });
  }

  arma::Col<double>::fixed<2> getCircleCircleIntersection(
      const arma::Col<double>::fixed<2>& firstCenter,
      const double& firstRadius,
      const arma::Col<double>::fixed<2>& secondCenter,
      const double& secondRadius) {
    double distance = arma::norm(secondCenter - firstCenter);

    if (distance == 0 || distance >= firstRadius + secondRadius || distance <= std::max(firstRadius, secondRadius) - std::min(firstRadius, secondRadius)) {
      throw std::runtime_error("Only intersections with exactly two intersections are considered valid.");
    }

    double cosine = (std::pow(firstRadius, 2) - std::pow(secondRadius, 2) + std::pow(distance, 2)) / (2 * distance);
    double sine = std::sqrt(std::pow(firstRadius, 2) - std::pow(cosine, 2));

    arma::Col<double>::fixed<2> normal = arma::normalise(secondCenter - firstCenter);

    return firstCenter + arma::Col<double>::fixed<2>({
      normal.at(0) * cosine + normal.at(1) * sine,
      normal.at(1) * cosine - normal.at(0) * sine
    });
  }

  arma::Col<double>::fixed<3> getCircleSphereIntersection(
      const arma::Col<double>::fixed<3>& circleCenter,
      const double& circleRadius,
      const arma::Col<double>::fixed<3>& circleNormal,
      const arma::Col<double>::fixed<3>& sphereCenter,
      const double& sphereRadius) {
    // Distance between the spheres center and the intersection circle within the sphere
    double innerDistance = arma::dot(circleNormal, sphereCenter - circleCenter);

    if (std::abs(innerDistance) >= sphereRadius) {
      throw std::runtime_error("Only intersections with exactly two intersections are considered valid.");
    }

    arma::Col<double>::fixed<3> innerCenter = sphereCenter + innerDistance * circleNormal;
    double innerRadius = std::sqrt(std::pow(sphereRadius, 2) - std::pow(innerDistance, 2));
    arma::Col<double>::fixed<3> normal = arma::normalise(arma::cross(innerCenter - circleCenter, circleNormal));

    double distance = arma::norm(innerCenter - circleCenter);
    double intersectionDistance = (std::pow(circleRadius, 2) - std::pow(innerRadius, 2) + std::pow(distance, 2)) / (2 * distance);

    return circleCenter + intersectionDistance / distance * (innerCenter - circleCenter) + normal * std::sqrt(std::pow(circleRadius, 2) - std::pow(intersectionDistance, 2));
  }
}
<|endoftext|>


<commit_before>#include <QCoreApplication>

#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QStringList>
#include <QThread>

#include "PackageGenerator.h"

bool copyRecursive(const QDir& source,const QDir& target){
    auto list=source.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    for(auto i=list.constBegin();i!=list.constEnd();++i){
        QString sourceItem(source.filePath(*i));
        QString targetItem(target.filePath(*i));
        if(QFileInfo(sourceItem).isFile()){
            QFile oldFile(targetItem);
            if(oldFile.exists()){
                oldFile.remove();
            }
            if(!QFile::copy(sourceItem,targetItem)){
                return false;
            }
        }else{
            QDir oldDir(targetItem);
            if(oldDir.exists()){
                oldDir.removeRecursively();
            }
            if(!target.mkdir(*i)){
                return false;
            }
            return copyRecursive(QDir(sourceItem),QDir(targetItem));
        }
    }
    return true;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    a.setApplicationName("Imageset package generator");
    a.setApplicationVersion("1.2");

    const qint32 delay=3000;

    QCommandLineParser parser;
    parser.setApplicationDescription("This application proccess package.json file and build resources");
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption removeImages("clean","Clean resource build folder");
    QCommandLineOption addImages("add","Add and process (rescale & crop) missing images");
    QCommandLineOption qrc("qrc","Create package.qrc files");
    QCommandLineOption rcc("rcc","Create binary resources (run Qt resource compiler)");
    QCommandLineOption dir("dir","Run for nested folders (assume provided location of multiple packages)");
    QCommandLineOption runningDelay("d",QString("Wait %1 ms before execution").arg(QString::number(delay)));
    parser.addOption(removeImages);
    parser.addOption(addImages);
    parser.addOption(qrc);
    parser.addOption(rcc);
    parser.addOption(dir);
    parser.addOption(runningDelay);

    parser.addPositionalArgument("source","Project folder containing source images");
    parser.addPositionalArgument("target","Build folder containing resource build files");
    parser.addPositionalArgument("[deployFolder]","Folder to copy target files");

    parser.process(a);

    if(parser.isSet(runningDelay)){
        QThread::msleep(delay);
    }

    QStringList arguments(parser.positionalArguments());

    if(arguments.size()<2 || arguments.size()>3){
        return 1;
    }

    QString source(arguments.at(0));
    QString target(arguments.at(1));

    QString deployFolder;
    if(arguments.size()>2){
        deployFolder=arguments.at(2);
    }

    QStringList subfolders;
    if(parser.isSet(dir)){
        QDir sourceDir(source);
        subfolders=sourceDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    }else{
        subfolders<<".";
    }

    foreach(QString subfolder,subfolders){
        PackageGenerator generator(source+"/"+subfolder,target+"/img/"+subfolder);
        if(!generator.readSetting()){
            return 2;
        }

        if(parser.isSet(addImages)){
            if(!generator.cleanImages(!parser.isSet(removeImages))){
                return 3;
            }
            if(!generator.addImages()){
                return 4;
            }
        }else if(parser.isSet(removeImages)){
            if(!generator.cleanImages(false)){
                return 3;
            }
        }

        if(parser.isSet(qrc)){
            if(!generator.buildQRC()){
                return 5;
            }
        }

        if(parser.isSet(rcc)){
            if(!generator.buildRCC()){
                return 6;
            }
        }
    }

    if(!deployFolder.isEmpty()){
        QDir deployDir(deployFolder);
        if(!deployDir.exists()){
            if(!deployDir.mkpath(".")){
                return 7;
            }
        }
        if(!copyRecursive(QDir(target+"/bin/"),QDir(deployFolder))){

            return 8;
        }
    }

    return 0;
}

<commit_msg>fixed multipackage copy command<commit_after>#include <QCoreApplication>

#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QStringList>
#include <QThread>

#include "PackageGenerator.h"

bool copyRecursive(const QDir& source,const QDir& target){
    auto list=source.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    for(auto i=list.constBegin();i!=list.constEnd();++i){
        QString sourceItem(source.filePath(*i));
        QString targetItem(target.filePath(*i));
        if(QFileInfo(sourceItem).isFile()){
            QFile oldFile(targetItem);
            if(oldFile.exists()){
                oldFile.remove();
            }
            if(!QFile::copy(sourceItem,targetItem)){
                return false;
            }
        }else{
            QDir oldDir(targetItem);
            if(oldDir.exists()){
                oldDir.removeRecursively();
            }
            if(!target.mkdir(*i)){
                return false;
            }
            if(!copyRecursive(QDir(sourceItem),QDir(targetItem))){
                return false;
            }
        }
    }
    return true;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    a.setApplicationName("Imageset package generator");
    a.setApplicationVersion("1.2");

    const qint32 delay=3000;

    QCommandLineParser parser;
    parser.setApplicationDescription("This application proccess package.json file and build resources");
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption removeImages("clean","Clean resource build folder");
    QCommandLineOption addImages("add","Add and process (rescale & crop) missing images");
    QCommandLineOption qrc("qrc","Create package.qrc files");
    QCommandLineOption rcc("rcc","Create binary resources (run Qt resource compiler)");
    QCommandLineOption dir("dir","Run for nested folders (assume provided location of multiple packages)");
    QCommandLineOption runningDelay("d",QString("Wait %1 ms before execution").arg(QString::number(delay)));
    parser.addOption(removeImages);
    parser.addOption(addImages);
    parser.addOption(qrc);
    parser.addOption(rcc);
    parser.addOption(dir);
    parser.addOption(runningDelay);

    parser.addPositionalArgument("source","Project folder containing source images");
    parser.addPositionalArgument("target","Build folder containing resource build files");
    parser.addPositionalArgument("[deployFolder]","Folder to copy target files");

    parser.process(a);

    if(parser.isSet(runningDelay)){
        QThread::msleep(delay);
    }

    QStringList arguments(parser.positionalArguments());

    if(arguments.size()<2 || arguments.size()>3){
        return 1;
    }

    QString source(arguments.at(0));
    QString target(arguments.at(1));

    QString deployFolder;
    if(arguments.size()>2){
        deployFolder=arguments.at(2);
    }

    QStringList subfolders;
    if(parser.isSet(dir)){
        QDir sourceDir(source);
        subfolders=sourceDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    }else{
        subfolders<<".";
    }

    foreach(QString subfolder,subfolders){
        PackageGenerator generator(source+"/"+subfolder,target+"/img/"+subfolder);
        if(!generator.readSetting()){
            return 2;
        }

        if(parser.isSet(addImages)){
            if(!generator.cleanImages(!parser.isSet(removeImages))){
                return 3;
            }
            if(!generator.addImages()){
                return 4;
            }
        }else if(parser.isSet(removeImages)){
            if(!generator.cleanImages(false)){
                return 3;
            }
        }

        if(parser.isSet(qrc)){
            if(!generator.buildQRC()){
                return 5;
            }
        }

        if(parser.isSet(rcc)){
            if(!generator.buildRCC()){
                return 6;
            }
        }
    }

    if(!deployFolder.isEmpty()){
        QDir deployDir(deployFolder);
        if(!deployDir.exists()){
            if(!deployDir.mkpath(".")){
                return 7;
            }
        }
        if(!copyRecursive(QDir(target+"/bin/"),QDir(deployFolder))){

            return 8;
        }
    }

    return 0;
}

<|endoftext|>


<commit_before>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver 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 Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#include "World.hpp"

#include "Player.hpp"
#include "tuningConstants.hpp"

#include "netinterface/NetInterface.hpp"
#include "netinterface/protocol/ClientCommands.hpp"

#include "Statistics.hpp"

void Player::workoutCommands() {
    std::unique_lock<std::mutex> lock(commandMutex);
    while (!immediateCommands.empty()) {
	    ClientCommandPointer cmd = immediateCommands.front();
	    immediateCommands.pop();
	    lock.unlock();
	    cmd->performAction(this);
	    using namespace Statistic;
	    Statistics::getInstance().logTime("command_incoming_done", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - cmd->getIncomingTime()).count());
	    lock.lock();
    }

    while (!queuedCommands.empty() && queuedCommands.front()->getMinAP() <= getActionPoints()) {
	    ClientCommandPointer cmd = queuedCommands.front();
	    queuedCommands.pop();
	    lock.unlock();
	    cmd->performAction(this);
	    lock.lock();
    }
}

void Player::checkFightMode() {
    if (getAttackMode() && canFight()) {
	    //cp->ltAction->abortAction();
	    World::get()->characterAttacks(this);
    }
}

void Player::receiveCommand(ClientCommandPointer cmd) {
	bool notify = false;
	{
		std::unique_lock<std::mutex> lock(commandMutex);
		if (cmd->getMinAP() == 0) {
			immediateCommands.push(cmd);
			notify = true;
		} else {
			if (getActionPoints() > cmd->getMinAP() && queuedCommands.empty())
				notify = true;
			queuedCommands.push(cmd);
		}
	}

	if (notify) {
		World::get()->addPlayerImmediateActionQueue(this);
		World::get()->scheduler.signalNewPlayerAction();
	}
}

<commit_msg>log commands using ap to its own stats<commit_after>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver 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 Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#include "World.hpp"

#include "Player.hpp"
#include "tuningConstants.hpp"

#include "netinterface/NetInterface.hpp"
#include "netinterface/protocol/ClientCommands.hpp"

#include "Statistics.hpp"

void Player::workoutCommands() {
    std::unique_lock<std::mutex> lock(commandMutex);
    while (!immediateCommands.empty()) {
	    ClientCommandPointer cmd = immediateCommands.front();
	    immediateCommands.pop();
	    lock.unlock();
	    cmd->performAction(this);
	    using namespace Statistic;
	    Statistics::getInstance().logTime("command_incoming_done", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - cmd->getIncomingTime()).count());
	    lock.lock();
    }

    while (!queuedCommands.empty() && queuedCommands.front()->getMinAP() <= getActionPoints()) {
	    ClientCommandPointer cmd = queuedCommands.front();
	    queuedCommands.pop();
	    lock.unlock();
	    cmd->performAction(this);
	    using namespace Statistic;
	    Statistics::getInstance().logTime("command_incoming_done_ap", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - cmd->getIncomingTime()).count());
	    lock.lock();
    }
}

void Player::checkFightMode() {
    if (getAttackMode() && canFight()) {
	    //cp->ltAction->abortAction();
	    World::get()->characterAttacks(this);
    }
}

void Player::receiveCommand(ClientCommandPointer cmd) {
	bool notify = false;
	{
		std::unique_lock<std::mutex> lock(commandMutex);
		if (cmd->getMinAP() == 0) {
			immediateCommands.push(cmd);
			notify = true;
		} else {
			if (getActionPoints() > cmd->getMinAP() && queuedCommands.empty())
				notify = true;
			queuedCommands.push(cmd);
		}
	}

	if (notify) {
		World::get()->addPlayerImmediateActionQueue(this);
		World::get()->scheduler.signalNewPlayerAction();
	}
}

<|endoftext|>


<commit_before><commit_msg>coverity#1307697 Dereference null return value<commit_after><|endoftext|>


<commit_before>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow_lite_support/c/task/vision/image_classifier.h"

#include <string.h>

#include "tensorflow/lite/core/shims/cc/shims_test_util.h"
#include "tensorflow_lite_support/c/task/processor/classification_result.h"
#include "tensorflow_lite_support/c/task/vision/core/frame_buffer.h"
#include "tensorflow_lite_support/cc/port/gmock.h"
#include "tensorflow_lite_support/cc/port/gtest.h"
#include "tensorflow_lite_support/cc/port/status_matchers.h"
#include "tensorflow_lite_support/cc/test/test_utils.h"
#include "tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.h"

namespace tflite {
namespace task {
namespace vision {
namespace {

using ::tflite::support::StatusOr;
using ::tflite::task::JoinPath;

constexpr char kTestDataDirectory[] =
    "/tensorflow_lite_support/cc/test/testdata/task/"
    "vision/";
// Quantized model.
constexpr char kMobileNetQuantizedWithMetadata[] =
    "mobilenet_v1_0.25_224_quant.tflite";

StatusOr<ImageData> LoadImage(const char* image_name) {
  return DecodeImageFromFile(JoinPath("./" /*test src dir*/,
                                      kTestDataDirectory, image_name));
}

class ImageClassifierFromOptionsTest : public tflite_shims::testing::Test {};

TEST_F(ImageClassifierFromOptionsTest, FailsWithMissingModelPath) {
  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);
  EXPECT_EQ(image_classifier, nullptr);
}

TEST_F(ImageClassifierFromOptionsTest, SucceedsWithModelPath) {
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);
  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();
  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);

  EXPECT_NE(image_classifier, nullptr);
  TfLiteImageClassifierDelete(image_classifier);
}

TEST_F(ImageClassifierFromOptionsTest, SucceedsWithNumberOfThreads) {
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);
  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();
  options.base_options.compute_settings.cpu_settings.num_threads = 3;
  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);

  EXPECT_NE(image_classifier, nullptr);
  TfLiteImageClassifierDelete(image_classifier);
}

TEST_F(ImageClassifierFromOptionsTest,
       FailsWithClassNameDenyListAndClassNameAllowList) {
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);

  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();

  const char* label_denylist[] = {"brambling"};
  options.classification_options.label_denylist.list = label_denylist;
  options.classification_options.label_denylist.length = 1;

  const char* label_allowlist[] = {"cheeseburger"};
  options.classification_options.label_allowlist.list = label_allowlist;
  options.classification_options.label_allowlist.length = 1;

  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);

  EXPECT_EQ(image_classifier, nullptr);
  if (image_classifier) TfLiteImageClassifierDelete(image_classifier);
}

class ImageClassifierClassifyTest : public tflite_shims::testing::Test {
 protected:
  void SetUp() override {
    std::string model_path =
        JoinPath("./" /*test src dir*/, kTestDataDirectory,
                 kMobileNetQuantizedWithMetadata);

    TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
    options.base_options.model_file.file_path = model_path.data();
    image_classifier = TfLiteImageClassifierFromOptions(&options);

    ASSERT_NE(image_classifier, nullptr);
  }

  void TearDown() override { TfLiteImageClassifierDelete(image_classifier); }
  TfLiteImageClassifier* image_classifier;
};

TEST_F(ImageClassifierClassifyTest, SucceedsWithImageData) {
  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassify(image_classifier, &frame_buffer);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  // TODO(prianka): check score and labels`

  TfLiteClassificationResultDelete(classification_result);
}

TEST_F(ImageClassifierClassifyTest, SucceedsWithRoiWithinImageBounds) {
  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteBoundingBox bounding_box = {
      .origin_x = 0, .origin_y = 0, .width = 100, .height = 100};
  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassifyWithRoi(image_classifier, &frame_buffer,
                                           &bounding_box);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  // TODO(prianka): check score and labels`

  TfLiteClassificationResultDelete(classification_result);
}

TEST_F(ImageClassifierClassifyTest, FailsWithRoiOutsideImageBounds) {
  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteBoundingBox bounding_box = {
      .origin_x = 0, .origin_y = 0, .width = 250, .height = 250};
  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassifyWithRoi(image_classifier, &frame_buffer,
                                           &bounding_box);

  ImageDataFree(&image_data);

  EXPECT_EQ(classification_result, nullptr);

  if (classification_result != nullptr)
    TfLiteClassificationResultDelete(classification_result);
}

TEST(ImageClassifierWithUserDefinedOptionsClassifyTest,
     SucceedsWithClassNameDenyList) {
  const char* denylisted_label_name = "cheeseburger";
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);

  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();

  const char* label_denylist[] = {denylisted_label_name};
  options.classification_options.label_denylist.list = label_denylist;
  options.classification_options.label_denylist.length = 1;

  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);
  ASSERT_NE(image_classifier, nullptr);

  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassify(image_classifier, &frame_buffer);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  EXPECT_NE(strcmp(classification_result->classifications->categories[0].label,
                   denylisted_label_name),
            0);

  if (image_classifier) TfLiteImageClassifierDelete(image_classifier);

  TfLiteClassificationResultDelete(classification_result);
}

TEST(ImageClassifierWithUserDefinedOptionsClassifyTest,
     SucceedsWithClassNameAllowList) {
  const char* allowlisted_label_name = "cheeseburger";
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata)
          .data();

  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();

  const char* label_allowlist[] = {allowlisted_label_name};
  options.classification_options.label_allowlist.list = label_allowlist;
  options.classification_options.label_allowlist.length = 1;

  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);
  ASSERT_NE(image_classifier, nullptr);

  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassify(image_classifier, &frame_buffer);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  EXPECT_EQ(strcmp(classification_result->classifications->categories[0].label,
                   allowlisted_label_name),
            0);

  if (image_classifier) TfLiteImageClassifierDelete(image_classifier);

  TfLiteClassificationResultDelete(classification_result);
}

}  // namespace
}  // namespace vision
}  // namespace task
}  // namespace tflite
<commit_msg>Fix the Task Library C API test<commit_after>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow_lite_support/c/task/vision/image_classifier.h"

#include <string.h>

#include "tensorflow/lite/core/shims/cc/shims_test_util.h"
#include "tensorflow_lite_support/c/task/processor/classification_result.h"
#include "tensorflow_lite_support/c/task/vision/core/frame_buffer.h"
#include "tensorflow_lite_support/cc/port/gmock.h"
#include "tensorflow_lite_support/cc/port/gtest.h"
#include "tensorflow_lite_support/cc/port/status_matchers.h"
#include "tensorflow_lite_support/cc/test/test_utils.h"
#include "tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.h"

namespace tflite {
namespace task {
namespace vision {
namespace {

using ::tflite::support::StatusOr;
using ::tflite::task::JoinPath;

constexpr char kTestDataDirectory[] =
    "/tensorflow_lite_support/cc/test/testdata/task/"
    "vision/";
// Quantized model.
constexpr char kMobileNetQuantizedWithMetadata[] =
    "mobilenet_v1_0.25_224_quant.tflite";

StatusOr<ImageData> LoadImage(const char* image_name) {
  return DecodeImageFromFile(JoinPath("./" /*test src dir*/,
                                      kTestDataDirectory, image_name));
}

class ImageClassifierFromOptionsTest : public tflite_shims::testing::Test {};

TEST_F(ImageClassifierFromOptionsTest, FailsWithMissingModelPath) {
  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);
  EXPECT_EQ(image_classifier, nullptr);
}

TEST_F(ImageClassifierFromOptionsTest, SucceedsWithModelPath) {
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);
  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();
  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);

  EXPECT_NE(image_classifier, nullptr);
  TfLiteImageClassifierDelete(image_classifier);
}

TEST_F(ImageClassifierFromOptionsTest, SucceedsWithNumberOfThreads) {
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);
  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();
  options.base_options.compute_settings.cpu_settings.num_threads = 3;
  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);

  EXPECT_NE(image_classifier, nullptr);
  TfLiteImageClassifierDelete(image_classifier);
}

TEST_F(ImageClassifierFromOptionsTest,
       FailsWithClassNameDenyListAndClassNameAllowList) {
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);

  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();

  const char* label_denylist[] = {"brambling"};
  options.classification_options.label_denylist.list = label_denylist;
  options.classification_options.label_denylist.length = 1;

  const char* label_allowlist[] = {"cheeseburger"};
  options.classification_options.label_allowlist.list = label_allowlist;
  options.classification_options.label_allowlist.length = 1;

  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);

  EXPECT_EQ(image_classifier, nullptr);
  if (image_classifier) TfLiteImageClassifierDelete(image_classifier);
}

class ImageClassifierClassifyTest : public tflite_shims::testing::Test {
 protected:
  void SetUp() override {
    std::string model_path =
        JoinPath("./" /*test src dir*/, kTestDataDirectory,
                 kMobileNetQuantizedWithMetadata);

    TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
    options.base_options.model_file.file_path = model_path.data();
    image_classifier = TfLiteImageClassifierFromOptions(&options);

    ASSERT_NE(image_classifier, nullptr);
  }

  void TearDown() override { TfLiteImageClassifierDelete(image_classifier); }
  TfLiteImageClassifier* image_classifier;
};

TEST_F(ImageClassifierClassifyTest, SucceedsWithImageData) {
  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .orientation = kTopLeft,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassify(image_classifier, &frame_buffer);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  // TODO(prianka): check score and labels`

  TfLiteClassificationResultDelete(classification_result);
}

TEST_F(ImageClassifierClassifyTest, SucceedsWithRoiWithinImageBounds) {
  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .orientation = kTopLeft,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteBoundingBox bounding_box = {
      .origin_x = 0, .origin_y = 0, .width = 100, .height = 100};
  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassifyWithRoi(image_classifier, &frame_buffer,
                                           &bounding_box);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  // TODO(prianka): check score and labels`

  TfLiteClassificationResultDelete(classification_result);
}

TEST_F(ImageClassifierClassifyTest, FailsWithRoiOutsideImageBounds) {
  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .orientation = kTopLeft,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteBoundingBox bounding_box = {
      .origin_x = 0, .origin_y = 0, .width = 250, .height = 250};
  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassifyWithRoi(image_classifier, &frame_buffer,
                                           &bounding_box);

  ImageDataFree(&image_data);

  EXPECT_EQ(classification_result, nullptr);

  if (classification_result != nullptr)
    TfLiteClassificationResultDelete(classification_result);
}

TEST(ImageClassifierWithUserDefinedOptionsClassifyTest,
     SucceedsWithClassNameDenyList) {
  const char* denylisted_label_name = "cheeseburger";
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata);

  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();

  const char* label_denylist[] = {denylisted_label_name};
  options.classification_options.label_denylist.list = label_denylist;
  options.classification_options.label_denylist.length = 1;

  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);
  ASSERT_NE(image_classifier, nullptr);

  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .orientation = kTopLeft,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassify(image_classifier, &frame_buffer);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  EXPECT_NE(strcmp(classification_result->classifications->categories[0].label,
                   denylisted_label_name),
            0);

  if (image_classifier) TfLiteImageClassifierDelete(image_classifier);

  TfLiteClassificationResultDelete(classification_result);
}

TEST(ImageClassifierWithUserDefinedOptionsClassifyTest,
     SucceedsWithClassNameAllowList) {
  const char* allowlisted_label_name = "cheeseburger";
  std::string model_path =
      JoinPath("./" /*test src dir*/, kTestDataDirectory,
               kMobileNetQuantizedWithMetadata)
          .data();

  TfLiteImageClassifierOptions options = TfLiteImageClassifierOptionsCreate();
  options.base_options.model_file.file_path = model_path.data();

  const char* label_allowlist[] = {allowlisted_label_name};
  options.classification_options.label_allowlist.list = label_allowlist;
  options.classification_options.label_allowlist.length = 1;

  TfLiteImageClassifier* image_classifier =
      TfLiteImageClassifierFromOptions(&options);
  ASSERT_NE(image_classifier, nullptr);

  SUPPORT_ASSERT_OK_AND_ASSIGN(ImageData image_data, LoadImage("burger-224.png"));

  TfLiteFrameBuffer frame_buffer = {
      .format = kRGB,
      .orientation = kTopLeft,
      .dimension = {.width = image_data.width, .height = image_data.height},
      .buffer = image_data.pixel_data};

  TfLiteClassificationResult* classification_result =
      TfLiteImageClassifierClassify(image_classifier, &frame_buffer);

  ImageDataFree(&image_data);

  ASSERT_NE(classification_result, nullptr);
  EXPECT_GE(classification_result->size, 1);
  EXPECT_NE(classification_result->classifications, nullptr);
  EXPECT_GE(classification_result->classifications->size, 1);
  EXPECT_NE(classification_result->classifications->categories, nullptr);
  EXPECT_EQ(strcmp(classification_result->classifications->categories[0].label,
                   allowlisted_label_name),
            0);

  if (image_classifier) TfLiteImageClassifierDelete(image_classifier);

  TfLiteClassificationResultDelete(classification_result);
}

}  // namespace
}  // namespace vision
}  // namespace task
}  // namespace tflite
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * 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 copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __ARCH_GENERIC_LINUX_THREADINFO_HH__
#define __ARCH_GENERIC_LINUX_THREADINFO_HH__

#include "cpu/thread_context.hh"
#include "sim/system.hh"

namespace Linux {

class ThreadInfo
{
  private:
    ThreadContext *tc;
    System *sys;
    Addr pcbb;

    ByteOrder byteOrder;

    template <typename T>
    bool
    get_data(const char *symbol, T &data)
    {
        auto &symtab = sys->workload->symtab(tc);
        auto it = symtab.find(symbol);
        if (it == symtab.end()) {
            warn_once("Unable to find kernel symbol %s\n", symbol);
            warn_once("Kernel not compiled with task_struct info; can't get "
                      "currently executing task/process/thread name/ids!\n");
            return false;
        }

        data = tc->getVirtProxy().read<T>(it->address, byteOrder);

        return true;
    }

  public:
    ThreadInfo(ThreadContext *_tc, Addr _pcbb = 0)
        : tc(_tc), sys(tc->getSystemPtr()), pcbb(_pcbb),
        byteOrder(tc->getSystemPtr()->getGuestByteOrder())
    {

    }
    ~ThreadInfo()
    {}

    inline Addr
    curThreadInfo()
    {
        if (!TheISA::CurThreadInfoImplemented)
            panic("curThreadInfo() not implemented for this ISA");

        Addr addr = pcbb;
        Addr sp;

        if (!addr)
            addr = tc->readMiscRegNoEffect(TheISA::CurThreadInfoReg);

        PortProxy &p = tc->getPhysProxy();
        p.readBlob(addr, &sp, sizeof(Addr));

        return sp & ~ULL(0x3fff);
    }

    inline Addr
    curTaskInfo(Addr thread_info = 0)
    {
        // Note that in Linux 4.10 the thread_info struct will no longer have a
        // pointer to the task_struct for arm64. See:
        // https://patchwork.kernel.org/patch/9333699/
        int32_t offset = 0;
        if (!get_data("thread_info_task", offset))
            return 0;

        if (!thread_info)
            thread_info = curThreadInfo();

        return tc->getVirtProxy().read<Addr>(thread_info + offset);
    }

    int32_t
    curTaskPIDFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        if (!get_data("task_struct_pid", offset))
            return -1;

        return tc->getVirtProxy().read<int32_t>(task_struct + offset);
    }

    int32_t
    curTaskPID(Addr thread_info = 0)
    {
        return curTaskPIDFromTaskStruct(curTaskInfo(thread_info));
    }

    int32_t
    curTaskTGIDFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        if (!get_data("task_struct_tgid", offset))
            return -1;

        return tc->getVirtProxy().read<int32_t>(task_struct + offset);
    }

    int32_t
    curTaskTGID(Addr thread_info = 0)
    {
        return curTaskTGIDFromTaskStruct(curTaskInfo(thread_info));
    }

    int64_t
    curTaskStartFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        if (!get_data("task_struct_start_time", offset))
            return -1;

        // start_time is actually of type timespec, but if we just
        // grab the first long, we'll get the seconds out of it
        return tc->getVirtProxy().read<int64_t>(task_struct + offset);
    }

    int64_t
    curTaskStart(Addr thread_info = 0)
    {
        return curTaskStartFromTaskStruct(curTaskInfo(thread_info));
    }

    std::string
    curTaskNameFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        int32_t size = 0;

        if (!get_data("task_struct_comm", offset))
            return "FailureIn_curTaskName";

        if (!get_data("task_struct_comm_size", size))
            return "FailureIn_curTaskName";

        char buffer[size + 1];
        tc->getVirtProxy().readString(buffer, task_struct + offset, size);

        return buffer;
    }

    std::string
    curTaskName(Addr thread_info = 0)
    {
        return curTaskNameFromTaskStruct(curTaskInfo(thread_info));
    }

    int32_t
    curTaskMmFromTaskStruct(Addr task_struct)
    {
        int32_t offset;
        if (!get_data("task_struct_mm", offset))
            return -1;

        return tc->getVirtProxy().read<int32_t>(task_struct + offset);
    }

    int32_t
    curTaskMm(Addr thread_info = 0)
    {
        return curTaskMmFromTaskStruct(curTaskInfo(thread_info));
    }
};

} // namespace Linux

#endif // __ARCH_GENERIC_LINUX_THREADINFO_HH__
<commit_msg>arch: Remove the "inline" keyword in ThreadInfo.<commit_after>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * 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 copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __ARCH_GENERIC_LINUX_THREADINFO_HH__
#define __ARCH_GENERIC_LINUX_THREADINFO_HH__

#include "cpu/thread_context.hh"
#include "sim/system.hh"

namespace Linux {

class ThreadInfo
{
  private:
    ThreadContext *tc;
    System *sys;
    Addr pcbb;

    ByteOrder byteOrder;

    template <typename T>
    bool
    get_data(const char *symbol, T &data)
    {
        auto &symtab = sys->workload->symtab(tc);
        auto it = symtab.find(symbol);
        if (it == symtab.end()) {
            warn_once("Unable to find kernel symbol %s\n", symbol);
            warn_once("Kernel not compiled with task_struct info; can't get "
                      "currently executing task/process/thread name/ids!\n");
            return false;
        }

        data = tc->getVirtProxy().read<T>(it->address, byteOrder);

        return true;
    }

  public:
    ThreadInfo(ThreadContext *_tc, Addr _pcbb = 0)
        : tc(_tc), sys(tc->getSystemPtr()), pcbb(_pcbb),
        byteOrder(tc->getSystemPtr()->getGuestByteOrder())
    {

    }
    ~ThreadInfo()
    {}

    Addr
    curThreadInfo()
    {
        if (!TheISA::CurThreadInfoImplemented)
            panic("curThreadInfo() not implemented for this ISA");

        Addr addr = pcbb;
        Addr sp;

        if (!addr)
            addr = tc->readMiscRegNoEffect(TheISA::CurThreadInfoReg);

        PortProxy &p = tc->getPhysProxy();
        p.readBlob(addr, &sp, sizeof(Addr));

        return sp & ~ULL(0x3fff);
    }

    Addr
    curTaskInfo(Addr thread_info = 0)
    {
        // Note that in Linux 4.10 the thread_info struct will no longer have a
        // pointer to the task_struct for arm64. See:
        // https://patchwork.kernel.org/patch/9333699/
        int32_t offset = 0;
        if (!get_data("thread_info_task", offset))
            return 0;

        if (!thread_info)
            thread_info = curThreadInfo();

        return tc->getVirtProxy().read<Addr>(thread_info + offset);
    }

    int32_t
    curTaskPIDFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        if (!get_data("task_struct_pid", offset))
            return -1;

        return tc->getVirtProxy().read<int32_t>(task_struct + offset);
    }

    int32_t
    curTaskPID(Addr thread_info = 0)
    {
        return curTaskPIDFromTaskStruct(curTaskInfo(thread_info));
    }

    int32_t
    curTaskTGIDFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        if (!get_data("task_struct_tgid", offset))
            return -1;

        return tc->getVirtProxy().read<int32_t>(task_struct + offset);
    }

    int32_t
    curTaskTGID(Addr thread_info = 0)
    {
        return curTaskTGIDFromTaskStruct(curTaskInfo(thread_info));
    }

    int64_t
    curTaskStartFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        if (!get_data("task_struct_start_time", offset))
            return -1;

        // start_time is actually of type timespec, but if we just
        // grab the first long, we'll get the seconds out of it
        return tc->getVirtProxy().read<int64_t>(task_struct + offset);
    }

    int64_t
    curTaskStart(Addr thread_info = 0)
    {
        return curTaskStartFromTaskStruct(curTaskInfo(thread_info));
    }

    std::string
    curTaskNameFromTaskStruct(Addr task_struct)
    {
        int32_t offset = 0;
        int32_t size = 0;

        if (!get_data("task_struct_comm", offset))
            return "FailureIn_curTaskName";

        if (!get_data("task_struct_comm_size", size))
            return "FailureIn_curTaskName";

        char buffer[size + 1];
        tc->getVirtProxy().readString(buffer, task_struct + offset, size);

        return buffer;
    }

    std::string
    curTaskName(Addr thread_info = 0)
    {
        return curTaskNameFromTaskStruct(curTaskInfo(thread_info));
    }

    int32_t
    curTaskMmFromTaskStruct(Addr task_struct)
    {
        int32_t offset;
        if (!get_data("task_struct_mm", offset))
            return -1;

        return tc->getVirtProxy().read<int32_t>(task_struct + offset);
    }

    int32_t
    curTaskMm(Addr thread_info = 0)
    {
        return curTaskMmFromTaskStruct(curTaskInfo(thread_info));
    }
};

} // namespace Linux

#endif // __ARCH_GENERIC_LINUX_THREADINFO_HH__
<|endoftext|>