<commit_before>// @(#)root/base:$Name:  $:$Id: TVirtualProofMgr.cxx,v 1.7 2006/06/02 15:14:35 rdm Exp $
// Author: G. Ganis, Nov 2005

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVirtualProofMgr                                                     //
//                                                                      //
// Abstract interface to the manager for PROOF sessions.                //
// The PROOF manager interacts with the PROOF server coordinator to     //
// create or destroy a PROOF session, attach to or detach from          //
// existing one, and to monitor any client activity on the cluster.     //
// At most one manager instance per server is allowed.                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG
#include "config.h"
#endif
#include "TError.h"
#include "TInetAddress.h"
#include "TList.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TVirtualMutex.h"
#include "TVirtualProof.h"
#include "TVirtualProofMgr.h"

ClassImp(TVirtualProofMgr)

// Sub-list of TROOT::fProofs with managers
TList TVirtualProofMgr::fgListOfManagers;
TVirtualProofMgr_t TVirtualProofMgr::fgTProofMgrHook[2] = { 0, 0 };

//______________________________________________________________________________
TVirtualProofMgr::TVirtualProofMgr(const char *url, Int_t, const char *)
                 : TNamed("",""), fRemoteProtocol(-1),
                   fServType(kXProofd), fSessions(0)
{
   // Constructor

   // AVoid problems with empty URLs
   fUrl = (!url || strlen(url) <= 0) ? TUrl("proof://localhost") : TUrl(url);
}

//______________________________________________________________________________
TVirtualProofMgr::~TVirtualProofMgr()
{
   // Destroy a TVirtualProofMgr instance

   SafeDelete(fSessions);

   fgListOfManagers.Remove(this);
   gROOT->GetListOfProofs()->Remove(this);
}

//______________________________________________________________________________
void TVirtualProofMgr::ShowWorkers()
{
   // Show available workers

   AbstractMethod("ShowWorkers");
}

//______________________________________________________________________________
TVirtualProofDesc *TVirtualProofMgr::GetProofDesc(Int_t id)
{
   // Get TVirtualProof instance corresponding to 'id'.

   if (id > 0) {
      TVirtualProofDesc *d = 0;
      // Retrieve an updated list
      QuerySessions("");
      if (fSessions) {
         TIter nxd(fSessions);
         while ((d = (TVirtualProofDesc *)nxd())) {
            if (d->MatchId(id))
               return d;
         }
      }
   }

   return 0;
}

//______________________________________________________________________________
void TVirtualProofMgr::ShutdownSession(TVirtualProof *p)
{
   // Discard PROOF session 'p'

   if (p) {
      TVirtualProofDesc *d = 0;
      if (fSessions) {
         TIter nxd(fSessions);
         while ((d = (TVirtualProofDesc *)nxd())) {
            if (p == d->GetProof()) {
               fSessions->Remove(d);
               delete d;
               break;
            }
         }
      }
   }
}

//______________________________________________________________________________
TVirtualProof *TVirtualProofMgr::CreateSession(const char *cfg,
                                               const char *cfgdir, Int_t loglevel)
{
   // Create a new remote session (master and associated workers).

   // Create
   if (IsProofd())
      fUrl.SetOptions("std");

   TProof_t proofhook = TVirtualProof::GetTProofHook();
   if (!proofhook) {

      // Load the library containing TProof ...
#ifdef ROOTLIBDIR
      TString prooflib = TString(ROOTLIBDIR) + "/libProof";
#else
#ifndef WIN32
      TString prooflib = TString(gRootDir) + "/lib/libProof";
#else
      TString prooflib = TString(gRootDir) + "/bin/libProof";
#endif
#endif
      char *p = 0;
      if ((p = gSystem->DynamicPathName(prooflib, kTRUE))) {
         delete[] p;
         if (gSystem->Load(prooflib) == -1)
            Error("CreateSession", "can't load %s", prooflib.Data());
         proofhook = TVirtualProof::GetTProofHook();
      } else
         Error("CreateSession", "can't locate %s", prooflib.Data());
   }
   if (!proofhook) {
      Error("CreateSession", "hook for TVirtualProof could not be loaded");
      return 0;
   }
   // Create the instance
   TVirtualProof *p =
     (TVirtualProof*) (*proofhook)(fUrl.GetUrl(), cfg, cfgdir, loglevel, 0);

   if (p && p->IsValid()) {

      // Set reference manager
      p->SetManager(this);

      // Save record about this session
      Int_t ns = 1;
      if (fSessions) {
         // To avoid ambiguities in case of removal of some elements
         if (fSessions->Last())
            ns = ((TVirtualProofDesc *)(fSessions->Last()))->GetLocalId() + 1;
      } else {
         // Create the list
         fSessions = new TList;
      }

      // Create the description class
      Int_t st = (p->IsIdle()) ? TVirtualProofDesc::kIdle : TVirtualProofDesc::kRunning ;
      TVirtualProofDesc *d =
         new TVirtualProofDesc(p->GetName(), p->GetTitle(), p->GetUrl(),
                               ns, p->GetSessionID(), st, p);
      fSessions->Add(d);

   } else {
      // Session creation failed
      Error("CreateSession", "creating PROOF session");
      SafeDelete(p);
   }

   // We are done
   return p;
}

//______________________________________________________________________________
Bool_t TVirtualProofMgr::MatchUrl(const char *url)
{
   // Checks if 'url' refers to the same 'user@host:port' entity as the URL
   // in memory

   TUrl u(url);

   // Correct URL protocol
   if (!strcmp(u.GetProtocol(), TUrl("a").GetProtocol()))
      u.SetProtocol("proof");

   // Correct port
   if (u.GetPort() == TUrl("a").GetPort()) {
      Int_t port = gSystem->GetServiceByName("rootd");
      if (port < 0)
         port = 1094;
      u.SetPort(port);
   }

   // Now we can check
   if (!strcmp(u.GetHostFQDN(), fUrl.GetHostFQDN()))
      if (u.GetPort() == fUrl.GetPort())
         if (strlen(u.GetUser()) <= 0 || !strcmp(u.GetUser(),fUrl.GetUser()))
            return kTRUE;

   // Match failed
   return kFALSE;
}

//________________________________________________________________________
TList *TVirtualProofMgr::GetListOfManagers()
{
   // Extract pointers to PROOF managers from TROOT::fProofs.

   // Update the list with new entries
   if (gROOT->GetListOfProofs()) {
      TIter nxp(gROOT->GetListOfProofs());
      TVirtualProofMgr *p = 0;
      while ((p = dynamic_cast<TVirtualProofMgr *> (nxp())))
         if (!fgListOfManagers.FindObject(p))
            fgListOfManagers.Add(p);
   }

   // Get rid of invalid entries and notify
   if (fgListOfManagers.GetSize() > 0) {
      TIter nxp(&fgListOfManagers);
      TObject *o = 0;
      Int_t nm = 0;
      while ((o = nxp())) {
         if (!(gROOT->GetListOfProofs()->FindObject(o))) {
            fgListOfManagers.Remove(o);
         } else {
            TVirtualProofMgr *p = (TVirtualProofMgr *)o;
            Printf("// #%d: \"%s\" (%s)", ++nm, p->GetName(), p->GetTitle());
         }
      }
   } else {
      if (gDebug > 0)
         Printf("No managers found");
   }

   // We are done
   return &fgListOfManagers;
}

//______________________________________________________________________________
TVirtualProofMgr *TVirtualProofMgr::Create(const char *url, Int_t loglevel,
                                           const char *alias, Bool_t xpd)
{
   // Static method returning the appropriate TProofMgr object using
   // the plugin manager.
   TVirtualProofMgr *m= 0;

   // Make sure we do not have already a manager for this URL
   TList *lm = TVirtualProofMgr::GetListOfManagers();
   if (lm) {
      TIter nxm(lm);
      while ((m = (TVirtualProofMgr *)nxm()))
         if (m->MatchUrl(url))
            if (m->IsValid()) {
               return m;
            } else {
               fgListOfManagers.Remove(m);
               SafeDelete(m);
               break;
            }
   }

   m = 0;
   Bool_t trystd = kTRUE;

   // If required, we assume first that the remote server is based on XrdProofd
   if (xpd) {
      TVirtualProofMgr_t cm = TVirtualProofMgr::GetProofMgrHook("xpd");
      if (cm) {
         m = (TVirtualProofMgr *) (*cm)(url, loglevel, alias);
         // Update trystd flag
         trystd = (m && !(m->IsValid()) && m->IsProofd()) ? kTRUE : kFALSE;
      }
   }

   // If the first attempt failed, we instantiate an old interface
   if (trystd) {
      SafeDelete(m);
      TVirtualProofMgr_t cm = TVirtualProofMgr::GetProofMgrHook("std");
      if (cm)
         m = (TVirtualProofMgr *) (*cm)(url, loglevel, alias);
   }

   // Record the new manager, if any
   if (m) {
      fgListOfManagers.Add(m);
      if (m->IsValid() && !(m->IsProofd())) {
         R__LOCKGUARD2(gROOTMutex);
         gROOT->GetListOfProofs()->Add(m);
         gROOT->GetListOfSockets()->Add(m);
      }
   }

   // We are done
   return m;
}

//________________________________________________________________________
TVirtualProofMgr_t TVirtualProofMgr::GetProofMgrHook(const char *type)
{
   // Get the specified constructor hook.
   // We do this without the plugin manager because it blocks the
   // CINT mutex breaking the parallel startup.

   static const char *libs[] = { "/libProof", "/libProofx" };

   // Find index (default: classic)
   Int_t idx = (type && !strncmp(type,"xpd",3)) ? 1 : 0;

   if (!fgTProofMgrHook[idx]) {
      // Load the appropriate library ...
#ifdef ROOTLIBDIR
      TString prooflib = TString(ROOTLIBDIR);
#else
#ifndef WIN32
      TString prooflib = TString(gRootDir) + "/lib";
#else
      TString prooflib = TString(gRootDir) + "/bin";
#endif
#endif
      prooflib += libs[idx];
      char *p = 0;
      if ((p = gSystem->DynamicPathName(prooflib, kTRUE))) {
         delete[] p;
         if (gSystem->Load(prooflib) == -1)
            ::Error("TVirtualProofMgr::GetProofMgrCtor",
                       "can't load %s", prooflib.Data());
      } else
         ::Error("TVirtualProofMgr::GetProofMgrCtor",
                 "can't locate %s", prooflib.Data());
   }

   // Done
   return fgTProofMgrHook[idx];
}

//_____________________________________________________________________________
void TVirtualProofMgr::SetTProofMgrHook(TVirtualProofMgr_t pmh, const char *t)
{
   // Set hook to TProofMgr ctor

   // Find index (default: classic)
   Int_t idx = (t && !strncmp(t,"xpd",3)) ? 1 : 0;

   fgTProofMgrHook[idx] = pmh;
}

ClassImp(TVirtualProofDesc)

//________________________________________________________________________
void TVirtualProofDesc::Print(Option_t *) const
{
   // Dump the content to the screen.
   const char *st[] = { "unknown", "idle", "processsing", "shutting down"};

   Printf("// # %d", fLocalId);
   Printf("// alias: %s, url: \"%s\"", GetTitle(), GetUrl());
   Printf("// tag: %s", GetName());
   Printf("// status: %s, attached: %s (remote ID: %d)",
          st[fStatus+1], (fProof ? "YES" : "NO"), fRemoteId);
}
<commit_msg>Fix coding convention violation<commit_after>// @(#)root/base:$Name:  $:$Id: TVirtualProofMgr.cxx,v 1.8 2006/06/21 16:18:26 rdm Exp $
// Author: G. Ganis, Nov 2005

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVirtualProofMgr                                                     //
//                                                                      //
// Abstract interface to the manager for PROOF sessions.                //
// The PROOF manager interacts with the PROOF server coordinator to     //
// create or destroy a PROOF session, attach to or detach from          //
// existing one, and to monitor any client activity on the cluster.     //
// At most one manager instance per server is allowed.                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG
#include "config.h"
#endif
#include "TError.h"
#include "TInetAddress.h"
#include "TList.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TVirtualMutex.h"
#include "TVirtualProof.h"
#include "TVirtualProofMgr.h"

ClassImp(TVirtualProofMgr)

// Sub-list of TROOT::fProofs with managers
TList TVirtualProofMgr::fgListOfManagers;
TVirtualProofMgr_t TVirtualProofMgr::fgTProofMgrHook[2] = { 0, 0 };

//______________________________________________________________________________
TVirtualProofMgr::TVirtualProofMgr(const char *url, Int_t, const char *)
                 : TNamed("",""), fRemoteProtocol(-1),
                   fServType(kXProofd), fSessions(0)
{
   // Constructor

   // AVoid problems with empty URLs
   fUrl = (!url || strlen(url) <= 0) ? TUrl("proof://localhost") : TUrl(url);
}

//______________________________________________________________________________
TVirtualProofMgr::~TVirtualProofMgr()
{
   // Destroy a TVirtualProofMgr instance

   SafeDelete(fSessions);

   fgListOfManagers.Remove(this);
   gROOT->GetListOfProofs()->Remove(this);
}

//______________________________________________________________________________
void TVirtualProofMgr::ShowWorkers()
{
   // Show available workers

   AbstractMethod("ShowWorkers");
}

//______________________________________________________________________________
TVirtualProofDesc *TVirtualProofMgr::GetProofDesc(Int_t id)
{
   // Get TVirtualProof instance corresponding to 'id'.

   if (id > 0) {
      TVirtualProofDesc *d = 0;
      // Retrieve an updated list
      QuerySessions("");
      if (fSessions) {
         TIter nxd(fSessions);
         while ((d = (TVirtualProofDesc *)nxd())) {
            if (d->MatchId(id))
               return d;
         }
      }
   }

   return 0;
}

//______________________________________________________________________________
void TVirtualProofMgr::ShutdownSession(TVirtualProof *p)
{
   // Discard PROOF session 'p'

   if (p) {
      TVirtualProofDesc *d = 0;
      if (fSessions) {
         TIter nxd(fSessions);
         while ((d = (TVirtualProofDesc *)nxd())) {
            if (p == d->GetProof()) {
               fSessions->Remove(d);
               delete d;
               break;
            }
         }
      }
   }
}

//______________________________________________________________________________
TVirtualProof *TVirtualProofMgr::CreateSession(const char *cfg,
                                               const char *cfgdir, Int_t loglevel)
{
   // Create a new remote session (master and associated workers).

   // Create
   if (IsProofd())
      fUrl.SetOptions("std");

   TProof_t proofhook = TVirtualProof::GetTProofHook();
   if (!proofhook) {

      // Load the library containing TProof ...
#ifdef ROOTLIBDIR
      TString prooflib = TString(ROOTLIBDIR) + "/libProof";
#else
#ifndef WIN32
      TString prooflib = TString(gRootDir) + "/lib/libProof";
#else
      TString prooflib = TString(gRootDir) + "/bin/libProof";
#endif
#endif
      char *p = 0;
      if ((p = gSystem->DynamicPathName(prooflib, kTRUE))) {
         delete[] p;
         if (gSystem->Load(prooflib) == -1)
            Error("CreateSession", "can't load %s", prooflib.Data());
         proofhook = TVirtualProof::GetTProofHook();
      } else
         Error("CreateSession", "can't locate %s", prooflib.Data());
   }
   if (!proofhook) {
      Error("CreateSession", "hook for TVirtualProof could not be loaded");
      return 0;
   }
   // Create the instance
   TVirtualProof *p =
     (TVirtualProof*) (*proofhook)(fUrl.GetUrl(), cfg, cfgdir, loglevel, 0);

   if (p && p->IsValid()) {

      // Set reference manager
      p->SetManager(this);

      // Save record about this session
      Int_t ns = 1;
      if (fSessions) {
         // To avoid ambiguities in case of removal of some elements
         if (fSessions->Last())
            ns = ((TVirtualProofDesc *)(fSessions->Last()))->GetLocalId() + 1;
      } else {
         // Create the list
         fSessions = new TList;
      }

      // Create the description class
      Int_t st = (p->IsIdle()) ? TVirtualProofDesc::kIdle : TVirtualProofDesc::kRunning ;
      TVirtualProofDesc *d =
         new TVirtualProofDesc(p->GetName(), p->GetTitle(), p->GetUrl(),
                               ns, p->GetSessionID(), st, p);
      fSessions->Add(d);

   } else {
      // Session creation failed
      Error("CreateSession", "creating PROOF session");
      SafeDelete(p);
   }

   // We are done
   return p;
}

//______________________________________________________________________________
Bool_t TVirtualProofMgr::MatchUrl(const char *url)
{
   // Checks if 'url' refers to the same 'user@host:port' entity as the URL
   // in memory

   TUrl u(url);

   // Correct URL protocol
   if (!strcmp(u.GetProtocol(), TUrl("a").GetProtocol()))
      u.SetProtocol("proof");

   // Correct port
   if (u.GetPort() == TUrl("a").GetPort()) {
      Int_t port = gSystem->GetServiceByName("rootd");
      if (port < 0)
         port = 1094;
      u.SetPort(port);
   }

   // Now we can check
   if (!strcmp(u.GetHostFQDN(), fUrl.GetHostFQDN()))
      if (u.GetPort() == fUrl.GetPort())
         if (strlen(u.GetUser()) <= 0 || !strcmp(u.GetUser(),fUrl.GetUser()))
            return kTRUE;

   // Match failed
   return kFALSE;
}

//________________________________________________________________________
TList *TVirtualProofMgr::GetListOfManagers()
{
   // Extract pointers to PROOF managers from TROOT::fProofs.

   // Update the list with new entries
   if (gROOT->GetListOfProofs()) {
      TIter nxp(gROOT->GetListOfProofs());
      TVirtualProofMgr *p = 0;
      while ((p = dynamic_cast<TVirtualProofMgr *> (nxp())))
         if (!fgListOfManagers.FindObject(p))
            fgListOfManagers.Add(p);
   }

   // Get rid of invalid entries and notify
   if (fgListOfManagers.GetSize() > 0) {
      TIter nxp(&fgListOfManagers);
      TObject *o = 0;
      Int_t nm = 0;
      while ((o = nxp())) {
         if (!(gROOT->GetListOfProofs()->FindObject(o))) {
            fgListOfManagers.Remove(o);
         } else {
            TVirtualProofMgr *p = (TVirtualProofMgr *)o;
            Printf("// #%d: \"%s\" (%s)", ++nm, p->GetName(), p->GetTitle());
         }
      }
   } else {
      if (gDebug > 0)
         Printf("No managers found");
   }

   // We are done
   return &fgListOfManagers;
}

//______________________________________________________________________________
TVirtualProofMgr *TVirtualProofMgr::Create(const char *url, Int_t loglevel,
                                           const char *alias, Bool_t xpd)
{
   // Static method returning the appropriate TProofMgr object using
   // the plugin manager.
   TVirtualProofMgr *m= 0;

   // Make sure we do not have already a manager for this URL
   TList *lm = TVirtualProofMgr::GetListOfManagers();
   if (lm) {
      TIter nxm(lm);
      while ((m = (TVirtualProofMgr *)nxm()))
         if (m->MatchUrl(url))
            if (m->IsValid()) {
               return m;
            } else {
               fgListOfManagers.Remove(m);
               SafeDelete(m);
               break;
            }
   }

   m = 0;
   Bool_t trystd = kTRUE;

   // If required, we assume first that the remote server is based on XrdProofd
   if (xpd) {
      TVirtualProofMgr_t cm = TVirtualProofMgr::GetProofMgrHook("xpd");
      if (cm) {
         m = (TVirtualProofMgr *) (*cm)(url, loglevel, alias);
         // Update trystd flag
         trystd = (m && !(m->IsValid()) && m->IsProofd()) ? kTRUE : kFALSE;
      }
   }

   // If the first attempt failed, we instantiate an old interface
   if (trystd) {
      SafeDelete(m);
      TVirtualProofMgr_t cm = TVirtualProofMgr::GetProofMgrHook("std");
      if (cm)
         m = (TVirtualProofMgr *) (*cm)(url, loglevel, alias);
   }

   // Record the new manager, if any
   if (m) {
      fgListOfManagers.Add(m);
      if (m->IsValid() && !(m->IsProofd())) {
         R__LOCKGUARD2(gROOTMutex);
         gROOT->GetListOfProofs()->Add(m);
         gROOT->GetListOfSockets()->Add(m);
      }
   }

   // We are done
   return m;
}

//________________________________________________________________________
TVirtualProofMgr_t TVirtualProofMgr::GetProofMgrHook(const char *type)
{
   // Get the specified constructor hook.
   // We do this without the plugin manager because it blocks the
   // CINT mutex breaking the parallel startup.

   static const char *libs[] = { "/libProof", "/libProofx" };

   // Find index (default: classic)
   Int_t idx = (type && !strncmp(type,"xpd",3)) ? 1 : 0;

   if (!fgTProofMgrHook[idx]) {
      // Load the appropriate library ...
#ifdef ROOTLIBDIR
      TString prooflib = TString(ROOTLIBDIR);
#else
#ifndef WIN32
      TString prooflib = TString(gRootDir) + "/lib";
#else
      TString prooflib = TString(gRootDir) + "/bin";
#endif
#endif
      prooflib += libs[idx];
      char *p = 0;
      if ((p = gSystem->DynamicPathName(prooflib, kTRUE))) {
         delete[] p;
         if (gSystem->Load(prooflib) == -1)
            ::Error("TVirtualProofMgr::GetProofMgrCtor",
                       "can't load %s", prooflib.Data());
      } else
         ::Error("TVirtualProofMgr::GetProofMgrCtor",
                 "can't locate %s", prooflib.Data());
   }

   // Done
   return fgTProofMgrHook[idx];
}

//_____________________________________________________________________________
void TVirtualProofMgr::SetTProofMgrHook(TVirtualProofMgr_t pmh, const char *t)
{
   // Set hook to TProofMgr ctor

   // Find index (default: classic)
   Int_t idx = (t && !strncmp(t,"xpd",3)) ? 1 : 0;

   fgTProofMgrHook[idx] = pmh;
}

ClassImp(TVirtualProofDesc)

//________________________________________________________________________
void TVirtualProofDesc::Print(Option_t *) const
{
   // Dump the content to the screen.
   const char *st[] = { "unknown", "idle", "processsing", "shutting down"};

   Printf("// # %d", fLocalId);
   Printf("// alias: %s, url: \"%s\"", GetTitle(), GetUrl());
   Printf("// tag: %s", GetName());
   Printf("// status: %s, attached: %s (remote ID: %d)",st[fStatus+1], (fProof ? "YES" : "NO"), fRemoteId);
}
<|endoftext|>


<commit_before>/**
 * @file gfx.cpp
 * @brief Platform-independent bitmap graphics transformation functionality
 *
 * (c) 2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"
#include "mega/gfx.h"

namespace mega {
const int GfxProc::dimensions[][2] = {
    { 200, 0 },     // THUMBNAIL: square thumbnail, cropped from near center
    { 1000, 1000 }  // PREVIEW: scaled version inside 1000x1000 bounding square
};

const int GfxProc::dimensionsavatar[][2] = {
    { 250, 0 }      // AVATAR250X250: square thumbnail, cropped from near center
};

bool GfxProc::isgfx(string* localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedformats()))
    {
        return false;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

bool GfxProc::isvideo(string *localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedvideoformats()))
    {
        return false;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

const char* GfxProc::supportedformats()
{
    return NULL;
}

const char* GfxProc::supportedvideoformats()
{
    return NULL;
}

void GfxProc::transform(int& w, int& h, int& rw, int& rh, int& px, int& py)
{
    if (rh)
    {
        // rectangular rw*rh bounding box
        if (h*rw > w*rh)
        {
            w = w * rh / h;
            h = rh;
        }
        else
        {
            h = h * rw / w;
            w = rw;
        }

        px = 0;
        py = 0;

        rw = w;
        rh = h;
    }
    else
    {
        // square rw*rw crop thumbnail
        if (w < h)
        {
            h = h * rw / w;
            w = rw;
        }
        else
        {
            w = w * rw / h;
            h = rw;
        }

        px = (w - rw) / 2;
        py = (h - rw) / 3;

        rh = rw;
    }
}

// load bitmap image, generate all designated sizes, attach to specified upload/node handle
// FIXME: move to a worker thread to keep the engine nonblocking
int GfxProc::gendimensionsputfa(FileAccess* fa, string* localfilename, handle th, SymmCipher* key, int missing, bool checkAccess)
{
    int numputs = 0;

    if (SimpleLogger::logCurrentLevel >= logDebug)
    {
        string utf8path;
        client->fsaccess->local2path(localfilename, &utf8path);
        LOG_debug << "Creating thumb/preview for " << utf8path;
    }

    // (this assumes that the width of the largest dimension is max)
    if (readbitmap(fa, localfilename, dimensions[sizeof dimensions/sizeof dimensions[0]-1][0]))
    {
        string* jpeg = NULL;

        // successively downscale the original image
        for (int i = sizeof dimensions/sizeof dimensions[0]; i--; )
        {
            if (!jpeg)
            {
                jpeg = new string;
            }

            int w = dimensions[i][0];
            int h = dimensions[i][1];
            if (i == (sizeof dimensions/sizeof dimensions[0] - 1)
                    && this->w < w && this->h < h )
            {
                LOG_debug << "Skipping upsizing of preview";
                w = this->w;
                h = this->h;
            }

            if (missing & (1 << i) && resizebitmap(w, h, jpeg))
            {
                // store the file attribute data - it will be attached to the file
                // immediately if the upload has already completed; otherwise, once
                // the upload completes
                int creqtag = client->reqtag;
                client->reqtag = 0;
                client->putfa(th, (meta_t)i, key, jpeg, checkAccess);
                client->reqtag = creqtag;
                numputs++;

                jpeg = NULL;
            }
        }

        if (jpeg)
        {
            delete jpeg;
        }

        freebitmap();
    }

    return numputs;
}

bool GfxProc::savefa(string *localfilepath, int width, int height, string *localdstpath)
{
    if (!isgfx(localfilepath)
            // (this assumes that the width of the largest dimension is max)
        || !readbitmap(NULL, localfilepath, width > height ? width : height))
    {
        return false;
    }

    int w = width;
    int h = height;
    if (this->w < w && this->h < h)
    {
        LOG_debug << "Skipping upsizing of local preview";
        w = this->w;
        h = this->h;
    }

    string jpeg;
    bool success = resizebitmap(w, h, &jpeg);
    freebitmap();

    if (!success)
    {
        return false;
    }

    FileAccess *f = client->fsaccess->newfileaccess();
    client->fsaccess->unlinklocal(localdstpath);
    if (!f->fopen(localdstpath, false, true))
    {
        delete f;
        return false;
    }

    if (!f->fwrite((const byte*)jpeg.data(), jpeg.size(), 0))
    {
        delete f;
        return false;
    }

    delete f;
    return true;
}

GfxProc::GfxProc()
{
    client = NULL;
}
} // namespace
<commit_msg>Do not change the previous way of managing images<commit_after>/**
 * @file gfx.cpp
 * @brief Platform-independent bitmap graphics transformation functionality
 *
 * (c) 2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"
#include "mega/gfx.h"

namespace mega {
const int GfxProc::dimensions[][2] = {
    { 200, 0 },     // THUMBNAIL: square thumbnail, cropped from near center
    { 1000, 1000 }  // PREVIEW: scaled version inside 1000x1000 bounding square
};

const int GfxProc::dimensionsavatar[][2] = {
    { 250, 0 }      // AVATAR250X250: square thumbnail, cropped from near center
};

bool GfxProc::isgfx(string* localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedformats()))
    {
        return true;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

bool GfxProc::isvideo(string *localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedvideoformats()))
    {
        return false;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

const char* GfxProc::supportedformats()
{
    return NULL;
}

const char* GfxProc::supportedvideoformats()
{
    return NULL;
}

void GfxProc::transform(int& w, int& h, int& rw, int& rh, int& px, int& py)
{
    if (rh)
    {
        // rectangular rw*rh bounding box
        if (h*rw > w*rh)
        {
            w = w * rh / h;
            h = rh;
        }
        else
        {
            h = h * rw / w;
            w = rw;
        }

        px = 0;
        py = 0;

        rw = w;
        rh = h;
    }
    else
    {
        // square rw*rw crop thumbnail
        if (w < h)
        {
            h = h * rw / w;
            w = rw;
        }
        else
        {
            w = w * rw / h;
            h = rw;
        }

        px = (w - rw) / 2;
        py = (h - rw) / 3;

        rh = rw;
    }
}

// load bitmap image, generate all designated sizes, attach to specified upload/node handle
// FIXME: move to a worker thread to keep the engine nonblocking
int GfxProc::gendimensionsputfa(FileAccess* fa, string* localfilename, handle th, SymmCipher* key, int missing, bool checkAccess)
{
    int numputs = 0;

    if (SimpleLogger::logCurrentLevel >= logDebug)
    {
        string utf8path;
        client->fsaccess->local2path(localfilename, &utf8path);
        LOG_debug << "Creating thumb/preview for " << utf8path;
    }

    // (this assumes that the width of the largest dimension is max)
    if (readbitmap(fa, localfilename, dimensions[sizeof dimensions/sizeof dimensions[0]-1][0]))
    {
        string* jpeg = NULL;

        // successively downscale the original image
        for (int i = sizeof dimensions/sizeof dimensions[0]; i--; )
        {
            if (!jpeg)
            {
                jpeg = new string;
            }

            int w = dimensions[i][0];
            int h = dimensions[i][1];
            if (i == (sizeof dimensions/sizeof dimensions[0] - 1)
                    && this->w < w && this->h < h )
            {
                LOG_debug << "Skipping upsizing of preview";
                w = this->w;
                h = this->h;
            }

            if (missing & (1 << i) && resizebitmap(w, h, jpeg))
            {
                // store the file attribute data - it will be attached to the file
                // immediately if the upload has already completed; otherwise, once
                // the upload completes
                int creqtag = client->reqtag;
                client->reqtag = 0;
                client->putfa(th, (meta_t)i, key, jpeg, checkAccess);
                client->reqtag = creqtag;
                numputs++;

                jpeg = NULL;
            }
        }

        if (jpeg)
        {
            delete jpeg;
        }

        freebitmap();
    }

    return numputs;
}

bool GfxProc::savefa(string *localfilepath, int width, int height, string *localdstpath)
{
    if (!isgfx(localfilepath)
            // (this assumes that the width of the largest dimension is max)
        || !readbitmap(NULL, localfilepath, width > height ? width : height))
    {
        return false;
    }

    int w = width;
    int h = height;
    if (this->w < w && this->h < h)
    {
        LOG_debug << "Skipping upsizing of local preview";
        w = this->w;
        h = this->h;
    }

    string jpeg;
    bool success = resizebitmap(w, h, &jpeg);
    freebitmap();

    if (!success)
    {
        return false;
    }

    FileAccess *f = client->fsaccess->newfileaccess();
    client->fsaccess->unlinklocal(localdstpath);
    if (!f->fopen(localdstpath, false, true))
    {
        delete f;
        return false;
    }

    if (!f->fwrite((const byte*)jpeg.data(), jpeg.size(), 0))
    {
        delete f;
        return false;
    }

    delete f;
    return true;
}

GfxProc::GfxProc()
{
    client = NULL;
}
} // namespace
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ClassMergingPass.h"

#include "ClassMerging.h"
#include "DexUtil.h"

namespace {

DexType* get_type(const std::string& type_s) {
  auto type = DexType::get_type(type_s.c_str());
  if (type == nullptr) {
    TRACE(CLMG, 2, "[ClassMerging] Warning: No type found for target type %s",
          type_s.c_str());
  }
  return type;
}

std::vector<DexType*> get_types(const std::vector<std::string>& target_types) {
  std::vector<DexType*> types;
  for (const auto& type_s : target_types) {
    auto target_type = get_type(type_s);
    if (target_type == nullptr) continue;
    types.push_back(target_type);
  }
  return types;
}

void load_types_and_prefixes(const std::vector<std::string>& type_names,
                             std::unordered_set<DexType*>& types,
                             std::unordered_set<std::string>& prefixes) {
  for (const auto& type_s : type_names) {
    auto target_type = get_type(type_s);
    if (target_type == nullptr) {
      prefixes.insert(type_s);
    } else {
      types.insert(target_type);
    }
  }
}

template <typename Types>
void load_types(const std::vector<std::string>& type_names, Types& types) {
  std::vector<DexType*> ts = get_types(type_names);
  for (const auto& t : ts) {
    const auto& cls = type_class(t);
    if (cls == nullptr) {
      TRACE(CLMG, 2, "Missing definition for type %s", SHOW(t));
      types.clear();
      return;
    }
    types.insert(t);
  }
}

/**
 * Verify model specs are consistent
 */
bool verify_model_spec(const ModelSpec& model_spec) {
  always_assert_log(
      !model_spec.name.empty(),
      "[ClassMerging] Wrong specification: model must have \"name\"");
  always_assert_log(!model_spec.class_name_prefix.empty(),
                    "[ClassMerging] Wrong specification: model %s must have "
                    "\"class_name_prefix\"",
                    model_spec.name.c_str());

  if (model_spec.roots.empty()) {
    TRACE(CLMG, 2,
          "[ClassMerging] Wrong specification: model %s must have \"roots\"",
          model_spec.name.c_str());
    return false;
  }

  for (const auto root : model_spec.roots) {
    always_assert_log(
        root,
        "[ClassMerging] Wrong specification: model %s must have \"roots\"",
        model_spec.name.c_str());
  }

  return true;
}

InterDexGroupingType get_merge_per_interdex_type(
    const std::string& merge_per_interdex_set) {

  const static std::unordered_map<std::string, InterDexGroupingType>
      string_to_grouping = {{"disabled", InterDexGroupingType::DISABLED},
                            {"non-hot-set", InterDexGroupingType::NON_HOT_SET},
                            {"full", InterDexGroupingType::FULL}};

  always_assert_log(string_to_grouping.count(merge_per_interdex_set) > 0,
                    "InterDex Grouping Type %s not found. Please check the list"
                    " of accepted values.",
                    merge_per_interdex_set.c_str());
  return string_to_grouping.at(merge_per_interdex_set);
}

TypeTagConfig get_type_tag_config(const std::string& type_tag_config) {
  const static std::unordered_map<std::string, TypeTagConfig> string_to_config =
      {{"none", TypeTagConfig::NONE},
       {"generate", TypeTagConfig::GENERATE},
       {"input-pass-type-tag-to-ctor",
        TypeTagConfig::INPUT_PASS_TYPE_TAG_TO_CTOR},
       {"input-handled", TypeTagConfig::INPUT_HANDLED}};
  always_assert_log(string_to_config.count(type_tag_config) > 0,
                    "Type tag config type %s not found. Please check the list"
                    " of accepted values.",
                    type_tag_config.c_str());
  TRACE(CLMG, 5, "type tag config %s %d", type_tag_config.c_str(),
        string_to_config.at(type_tag_config));
  return string_to_config.at(type_tag_config);
}

} // namespace

void ClassMergingPass::bind_config() {
  bool process_method_meta;
  bind("process_method_meta", false, process_method_meta);
  int64_t max_num_dispatch_target;
  bind("max_num_dispatch_target", {0}, max_num_dispatch_target);
  bool merge_static_methods_within_shape;
  bind("merge_static_methods_within_shape", false,
       merge_static_methods_within_shape);
  bool merge_direct_methods_within_shape;
  bind("merge_direct_methods_within_shape", false,
       merge_direct_methods_within_shape);
  bool merge_nonvirt_methods_within_shape;
  bind("merge_nonvirt_methods_within_shape", false,
       merge_nonvirt_methods_within_shape);

  // load model specifications
  std::vector<Json::Value> models;
  bind("models", {}, models);

  after_configuration([=] {
    if (max_num_dispatch_target > 0) {
      m_max_num_dispatch_target =
          boost::optional<size_t>(static_cast<size_t>(max_num_dispatch_target));
    }

    if (models.empty()) return;

    // load each model spec for erasure
    for (auto it = models.begin(); it != models.end(); ++it) {
      const auto& value = *it;
      always_assert_log(
          value.isObject(),
          "[ClassMerging] Wrong specification: model in array not an object");
      JsonWrapper model_spec = JsonWrapper(value);
      ModelSpec model;
      model_spec.get("enabled", true, model.enabled);
      std::string type_tag_config;
      model_spec.get("type_tag_config", "generate", type_tag_config);
      model.type_tag_config = get_type_tag_config(type_tag_config);
      size_t min_count;
      model_spec.get("min_count", 2, min_count);
      model.min_count = min_count > 0 ? min_count : 0;
      model_spec.get("name", "", model.name);
      std::vector<std::string> root_names;
      model_spec.get("roots", {}, root_names);
      load_types(root_names, model.roots);
      std::vector<std::string> excl_names;
      model_spec.get("exclude", {}, excl_names);
      load_types_and_prefixes(excl_names, model.exclude_types,
                              model.exclude_prefixes);
      model_spec.get("class_name_prefix", "", model.class_name_prefix);
      Json::Value generated;
      model_spec.get("generated", Json::Value(), generated);
      if (!generated.isNull()) {
        if (!generated.isObject()) {
          fprintf(stderr,
                  "[ClassMerging] Wrong specification: model in array not an "
                  "object\n");
          m_model_specs.clear();
          return;
        }
        JsonWrapper gen_spec = JsonWrapper(generated);
        std::vector<std::string> gen_names;
        gen_spec.get("other_roots", {}, gen_names);
        load_types(gen_names, model.gen_types);

        std::vector<std::string> gen_anno_names;
        gen_spec.get("annos", {}, gen_anno_names);
        load_types(gen_anno_names, model.gen_annos);
      }
      model_spec.get("include_primary_dex", false, model.include_primary_dex);

      std::string merge_per_interdex_set;
      model_spec.get("merge_per_interdex_set", "disabled",
                     merge_per_interdex_set);
      model.merge_per_interdex_set =
          get_merge_per_interdex_type(merge_per_interdex_set);

      always_assert_log(!model.merge_per_interdex_set ||
                            (model.type_tag_config != TypeTagConfig::NONE),
                        "Cannot group when type tag is not needed.");

      size_t max_count;
      model_spec.get("max_count", 0, max_count);
      Json::Value approximate_shaping;
      model_spec.get("approximate_shape_merging", Json::Value(),
                     model.approximate_shape_merging);
      model_spec.get("merge_types_with_static_fields", false,
                     model.merge_types_with_static_fields);
      model_spec.get("keep_debug_info", false, model.keep_debug_info);
      model_spec.get("replace_type_like_const_strings", true,
                     model.replace_type_like_const_strings);
      if (max_count > 0) {
        model.max_count = boost::optional<size_t>(max_count);
      }
      model.process_method_meta = process_method_meta;
      model.merge_static_methods_within_shape =
          merge_static_methods_within_shape;
      model.merge_direct_methods_within_shape =
          merge_direct_methods_within_shape;
      model.merge_nonvirt_methods_within_shape =
          merge_nonvirt_methods_within_shape;
      model.max_num_dispatch_target = m_max_num_dispatch_target;

      if (!verify_model_spec(model)) {
        continue;
      }

      m_model_specs.emplace_back(std::move(model));
    }

    TRACE(CLMG, 2, "[ClassMerging] valid model specs %ld",
          m_model_specs.size());
  });
}

void ClassMergingPass::run_pass(DexStoresVector& stores,
                                ConfigFiles& conf,
                                PassManager& mgr) {
  if (m_model_specs.empty()) {
    return;
  }
  auto scope = build_class_scope(stores);
  for (ModelSpec& model_spec : m_model_specs) {
    if (!model_spec.enabled) {
      continue;
    }
    class_merging::merge_model(scope, conf, mgr, stores, model_spec);
  }
  post_dexen_changes(scope, stores);
}

static ClassMergingPass s_pass;
<commit_msg>Apply unique constraint to the pass<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ClassMergingPass.h"

#include "ClassMerging.h"
#include "DexUtil.h"

namespace {

DexType* get_type(const std::string& type_s) {
  auto type = DexType::get_type(type_s.c_str());
  if (type == nullptr) {
    TRACE(CLMG, 2, "[ClassMerging] Warning: No type found for target type %s",
          type_s.c_str());
  }
  return type;
}

std::vector<DexType*> get_types(const std::vector<std::string>& target_types) {
  std::vector<DexType*> types;
  for (const auto& type_s : target_types) {
    auto target_type = get_type(type_s);
    if (target_type == nullptr) continue;
    types.push_back(target_type);
  }
  return types;
}

void load_types_and_prefixes(const std::vector<std::string>& type_names,
                             std::unordered_set<DexType*>& types,
                             std::unordered_set<std::string>& prefixes) {
  for (const auto& type_s : type_names) {
    auto target_type = get_type(type_s);
    if (target_type == nullptr) {
      prefixes.insert(type_s);
    } else {
      types.insert(target_type);
    }
  }
}

template <typename Types>
void load_types(const std::vector<std::string>& type_names, Types& types) {
  std::vector<DexType*> ts = get_types(type_names);
  for (const auto& t : ts) {
    const auto& cls = type_class(t);
    if (cls == nullptr) {
      TRACE(CLMG, 2, "Missing definition for type %s", SHOW(t));
      types.clear();
      return;
    }
    types.insert(t);
  }
}

/**
 * Verify model specs are consistent
 */
bool verify_model_spec(const ModelSpec& model_spec) {
  always_assert_log(
      !model_spec.name.empty(),
      "[ClassMerging] Wrong specification: model must have \"name\"");
  always_assert_log(!model_spec.class_name_prefix.empty(),
                    "[ClassMerging] Wrong specification: model %s must have "
                    "\"class_name_prefix\"",
                    model_spec.name.c_str());

  if (model_spec.roots.empty()) {
    TRACE(CLMG, 2,
          "[ClassMerging] Wrong specification: model %s must have \"roots\"",
          model_spec.name.c_str());
    return false;
  }

  for (const auto root : model_spec.roots) {
    always_assert_log(
        root,
        "[ClassMerging] Wrong specification: model %s must have \"roots\"",
        model_spec.name.c_str());
  }

  return true;
}

InterDexGroupingType get_merge_per_interdex_type(
    const std::string& merge_per_interdex_set) {

  const static std::unordered_map<std::string, InterDexGroupingType>
      string_to_grouping = {{"disabled", InterDexGroupingType::DISABLED},
                            {"non-hot-set", InterDexGroupingType::NON_HOT_SET},
                            {"full", InterDexGroupingType::FULL}};

  always_assert_log(string_to_grouping.count(merge_per_interdex_set) > 0,
                    "InterDex Grouping Type %s not found. Please check the list"
                    " of accepted values.",
                    merge_per_interdex_set.c_str());
  return string_to_grouping.at(merge_per_interdex_set);
}

TypeTagConfig get_type_tag_config(const std::string& type_tag_config) {
  const static std::unordered_map<std::string, TypeTagConfig> string_to_config =
      {{"none", TypeTagConfig::NONE},
       {"generate", TypeTagConfig::GENERATE},
       {"input-pass-type-tag-to-ctor",
        TypeTagConfig::INPUT_PASS_TYPE_TAG_TO_CTOR},
       {"input-handled", TypeTagConfig::INPUT_HANDLED}};
  always_assert_log(string_to_config.count(type_tag_config) > 0,
                    "Type tag config type %s not found. Please check the list"
                    " of accepted values.",
                    type_tag_config.c_str());
  TRACE(CLMG, 5, "type tag config %s %d", type_tag_config.c_str(),
        string_to_config.at(type_tag_config));
  return string_to_config.at(type_tag_config);
}

} // namespace

void ClassMergingPass::bind_config() {
  bool process_method_meta;
  bind("process_method_meta", false, process_method_meta);
  int64_t max_num_dispatch_target;
  bind("max_num_dispatch_target", {0}, max_num_dispatch_target);
  bool merge_static_methods_within_shape;
  bind("merge_static_methods_within_shape", false,
       merge_static_methods_within_shape);
  bool merge_direct_methods_within_shape;
  bind("merge_direct_methods_within_shape", false,
       merge_direct_methods_within_shape);
  bool merge_nonvirt_methods_within_shape;
  bind("merge_nonvirt_methods_within_shape", false,
       merge_nonvirt_methods_within_shape);
  trait(Traits::Pass::unique, true);

  // load model specifications
  std::vector<Json::Value> models;
  bind("models", {}, models);

  after_configuration([=] {
    if (max_num_dispatch_target > 0) {
      m_max_num_dispatch_target =
          boost::optional<size_t>(static_cast<size_t>(max_num_dispatch_target));
    }

    if (models.empty()) return;

    // load each model spec for erasure
    for (auto it = models.begin(); it != models.end(); ++it) {
      const auto& value = *it;
      always_assert_log(
          value.isObject(),
          "[ClassMerging] Wrong specification: model in array not an object");
      JsonWrapper model_spec = JsonWrapper(value);
      ModelSpec model;
      model_spec.get("enabled", true, model.enabled);
      std::string type_tag_config;
      model_spec.get("type_tag_config", "generate", type_tag_config);
      model.type_tag_config = get_type_tag_config(type_tag_config);
      size_t min_count;
      model_spec.get("min_count", 2, min_count);
      model.min_count = min_count > 0 ? min_count : 0;
      model_spec.get("name", "", model.name);
      std::vector<std::string> root_names;
      model_spec.get("roots", {}, root_names);
      load_types(root_names, model.roots);
      std::vector<std::string> excl_names;
      model_spec.get("exclude", {}, excl_names);
      load_types_and_prefixes(excl_names, model.exclude_types,
                              model.exclude_prefixes);
      model_spec.get("class_name_prefix", "", model.class_name_prefix);
      Json::Value generated;
      model_spec.get("generated", Json::Value(), generated);
      if (!generated.isNull()) {
        if (!generated.isObject()) {
          fprintf(stderr,
                  "[ClassMerging] Wrong specification: model in array not an "
                  "object\n");
          m_model_specs.clear();
          return;
        }
        JsonWrapper gen_spec = JsonWrapper(generated);
        std::vector<std::string> gen_names;
        gen_spec.get("other_roots", {}, gen_names);
        load_types(gen_names, model.gen_types);

        std::vector<std::string> gen_anno_names;
        gen_spec.get("annos", {}, gen_anno_names);
        load_types(gen_anno_names, model.gen_annos);
      }
      model_spec.get("include_primary_dex", false, model.include_primary_dex);

      std::string merge_per_interdex_set;
      model_spec.get("merge_per_interdex_set", "disabled",
                     merge_per_interdex_set);
      model.merge_per_interdex_set =
          get_merge_per_interdex_type(merge_per_interdex_set);

      always_assert_log(!model.merge_per_interdex_set ||
                            (model.type_tag_config != TypeTagConfig::NONE),
                        "Cannot group when type tag is not needed.");

      size_t max_count;
      model_spec.get("max_count", 0, max_count);
      Json::Value approximate_shaping;
      model_spec.get("approximate_shape_merging", Json::Value(),
                     model.approximate_shape_merging);
      model_spec.get("merge_types_with_static_fields", false,
                     model.merge_types_with_static_fields);
      model_spec.get("keep_debug_info", false, model.keep_debug_info);
      model_spec.get("replace_type_like_const_strings", true,
                     model.replace_type_like_const_strings);
      if (max_count > 0) {
        model.max_count = boost::optional<size_t>(max_count);
      }
      model.process_method_meta = process_method_meta;
      model.merge_static_methods_within_shape =
          merge_static_methods_within_shape;
      model.merge_direct_methods_within_shape =
          merge_direct_methods_within_shape;
      model.merge_nonvirt_methods_within_shape =
          merge_nonvirt_methods_within_shape;
      model.max_num_dispatch_target = m_max_num_dispatch_target;

      if (!verify_model_spec(model)) {
        continue;
      }

      m_model_specs.emplace_back(std::move(model));
    }

    TRACE(CLMG, 2, "[ClassMerging] valid model specs %ld",
          m_model_specs.size());
  });
}

void ClassMergingPass::run_pass(DexStoresVector& stores,
                                ConfigFiles& conf,
                                PassManager& mgr) {
  if (m_model_specs.empty()) {
    return;
  }
  auto scope = build_class_scope(stores);
  for (ModelSpec& model_spec : m_model_specs) {
    if (!model_spec.enabled) {
      continue;
    }
    class_merging::merge_model(scope, conf, mgr, stores, model_spec);
  }
  post_dexen_changes(scope, stores);
}

static ClassMergingPass s_pass;
<|endoftext|>


<commit_before>#include "Variant.h"
#include "split.h"
#include "cdflib.hpp"
#include "pdflib.hpp"
#include "var.hpp"

#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <getopt.h>

using namespace std;
using namespace vcf;
void printVersion(void){
	    cerr << "INFO: version 1.1.0 ; date: April 2014 ; author: Zev Kronenberg; email : zev.kronenberg@utah.edu " << endl;
	    exit(1);

}

void printHelp(void){
  cerr << endl << endl;
  cerr << "INFO: help" << endl;
  cerr << "INFO: description:" << endl;
  cerr << "     iHS calculates the integrated ratio of haplotype decay between the reference and non-reference allele. " << endl;
  cerr << "     This implementation of iHS integrates over a SNP index, NOT a physical distance or genetic distance.   " << endl << endl;

  cerr << "Output : 4 columns :                  "    << endl;
  cerr << "     1. seqid                         "    << endl;
  cerr << "     2. position                      "    << endl;
  cerr << "     3. target allele frequency       "    << endl;
  cerr << "     4. integrated EHH (alternative)  "    << endl;
  cerr << "     5. integrated EHH (reference)    "    << endl;
  cerr << "     6. iHS log(iEHHalt/iEHHref)      "    << endl  << endl;

  cerr << "INFO: iHS  --target 0,1,2,3,4,5,6,7 --file my.phased.vcf  --region chr1:1-1000 " << endl << endl;

  cerr << "INFO: required: t,target  -- argument: a zero base comma separated list of target individuals corrisponding to VCF columns " << endl;
  cerr << "INFO: required: f,file    -- argument: proper formatted and phased VCF.                                                    " << endl;
  cerr << "INFO: required: y,type    -- argument: genotype likelihood format: PL,GL,GP                                                " << endl;
  cerr << "INFO: optional: r,region  -- argument: a tabix compliant genomic range : \"seqid:start-end\" or \"seqid\"                  " << endl;
  cerr << endl;

  printVersion();

  exit(1);
}

void clearHaplotypes(string haplotypes[][2], int ntarget){
  for(int i= 0; i < ntarget; i++){
    haplotypes[i][0].clear();
    haplotypes[i][1].clear();
  }
}

void loadIndices(map<int, int> & index, string set){

  vector<string>  indviduals = split(set, ",");
  vector<string>::iterator it = indviduals.begin();

  for(; it != indviduals.end(); it++){
    index[ atoi( (*it).c_str() ) ] = 1;
  }
}

void calc(string haplotypes[][2], int nhaps, vector<double> afs, vector<long int> pos, vector<int> & target, vector<int> & background, string seqid){

  for(int snp = 0; snp < haplotypes[0][0].length(); snp++){

    double ehhA = 1;
    double ehhR = 1;

    double iHSA = 1;
    double iHSR = 1;

    int start = snp;
    int end   = snp;
    int core  = snp;

    while( ehhA > 0.05 && ehhR > 0.05 ) {

      start -= 1;
      end   += 1;

      if(start == -1){
	break;
      }
      if(end == haplotypes[0][0].length() - 1){
	break;
      }

      map<string , int> targetH;

      double sumrT = 0;
      double sumaT = 0;
      double nrefT = 0;
      double naltT = 0;

      for(int i = 0; i < nhaps; i++){
	targetH[ haplotypes[i][0].substr(start, (end - start)) ]++;
	targetH[ haplotypes[i][1].substr(start, (end - start)) ]++;
      }
      for( map<string, int>::iterator th = targetH.begin(); th != targetH.end(); th++){
	if( (*th).first.substr((end-start)/2, 1) == "1"){
	   sumaT += r8_choose(th->second, 2);
	   naltT += th->second;
	}
	else{
	  sumrT += r8_choose(th->second, 2);
	  nrefT += th->second;
	}
      }

      ehhA = sumaT / (r8_choose(naltT, 2));
      ehhR = sumrT / (r8_choose(nrefT, 2));

      iHSA += ehhA;
      iHSR += ehhR;
    }
    if(isnan(iHSA) || isnan(iHSR)){
      continue;
    }
    cout << seqid << "\t" << pos[snp] << "\t" << afs[snp] << "\t" << iHSA << "\t" << iHSR << "\t" << log(iHSA/iHSR) << endl;
  }
}

double EHH(string haplotypes[][2], int nhaps){

  map<string , int> hapcounts;

  for(int i = 0; i < nhaps; i++){
    hapcounts[ haplotypes[i][0] ]++;
    hapcounts[ haplotypes[i][1] ]++;
  }

  double sum = 0;
  double nh  = 0;

  for( map<string, int>::iterator it = hapcounts.begin(); it != hapcounts.end(); it++){
    nh  += it->second;
    sum += r8_choose(it->second, 2);
  }

  double max = (sum /  r8_choose(nh, 2));

  return max;

}

void loadPhased(string haplotypes[][2], genotype * pop, int ntarget){

  int indIndex = 0;

  for(vector<string>::iterator ind = pop->gts.begin(); ind != pop->gts.end(); ind++){
    string g = (*ind);
    vector< string > gs = split(g, "|");
    haplotypes[indIndex][0].append(gs[0]);
    haplotypes[indIndex][1].append(gs[1]);
    indIndex += 1;
  }
}

int main(int argc, char** argv) {

  // set the random seed for MCMC

  srand((unsigned)time(NULL));

  // the filename

  string filename = "NA";

  // set region to scaffold

  string region = "NA";

  // using vcflib; thanks to Erik Garrison

  VariantCallFile variantFile;

  // zero based index for the target and background indivudals

  map<int, int> it, ib;

  // deltaaf is the difference of allele frequency we bother to look at

  // ancestral state is set to zero by default

  int counts = 0;

  // phased

  int phased = 0;

  string type = "NA";

    const struct option longopts[] =
      {
	{"version"   , 0, 0, 'v'},
	{"help"      , 0, 0, 'h'},
        {"file"      , 1, 0, 'f'},
	{"target"    , 1, 0, 't'},
	{"region"    , 1, 0, 'r'},
	{"type"      , 1, 0, 'y'},
	{0,0,0,0}
      };

    int findex;
    int iarg=0;

    while(iarg != -1)
      {
	iarg = getopt_long(argc, argv, "y:r:d:t:b:f:hv", longopts, &findex);

	switch (iarg)
	  {
	  case 'h':
	    printHelp();
	  case 'v':
	    printVersion();
	  case 'y':
	    type = optarg;
	    break;
	  case 't':
	    loadIndices(it, optarg);
	    cerr << "INFO: there are " << it.size() << " individuals in the target" << endl;
	    cerr << "INFO: target ids: " << optarg << endl;
	    break;
	  case 'f':
	    cerr << "INFO: file: " << optarg  <<  endl;
	    filename = optarg;
	    break;
	  case 'r':
            cerr << "INFO: set seqid region to : " << optarg << endl;
	    region = optarg;
	    break;
	  default:
	    break;
	  }
      }

    map<string, int> okayGenotypeLikelihoods;
    okayGenotypeLikelihoods["PL"] = 1;
    okayGenotypeLikelihoods["GL"] = 1;
    okayGenotypeLikelihoods["GP"] = 1;
    okayGenotypeLikelihoods["GT"] = 1;

    if(type == "NA"){
      cerr << "FATAL: failed to specify genotype likelihood format : PL or GL" << endl;
      printHelp();
      return 1;
    }
    if(okayGenotypeLikelihoods.find(type) == okayGenotypeLikelihoods.end()){
      cerr << "FATAL: genotype likelihood is incorrectly formatted, only use: PL or GL" << endl;
      printHelp();
      return 1;
    }

    if(filename == "NA"){
      cerr << "FATAL: did not specify a file" << endl;
      printHelp();
      return(1);
    }

    if(it.size() < 2){
      cerr << "FATAL: target option is required -- or -- less than two individuals in target\n";
      printHelp();
      return(1);
    }

    variantFile.open(filename);

    if(region != "NA"){
      if(! variantFile.setRegion(region)){
	cerr <<"FATAL: unable to set region" << endl;
	return 1;
      }
    }

    if (!variantFile.is_open()) {
        return 1;
    }

    Variant var(variantFile);

    vector<int> target_h, background_h;

    int index, indexi = 0;

    vector<string> samples = variantFile.sampleNames;
    int nsamples = samples.size();

    for(vector<string>::iterator samp = samples.begin(); samp != samples.end(); samp++){

      string sampleName = (*samp);

      if(it.find(index) != it.end() ){
	target_h.push_back(indexi);
	indexi++;
      }
      index++;
    }

    vector<long int> positions;

    vector<double> afs;

    string haplotypes [target_h.size()][2];

    string currentSeqid = "NA";

    while (variantFile.getNextVariant(var)) {

      if(!var.isPhased()){
	cerr << "FATAL: Found an unphased variant. All genotypes must be phased!" << endl;
	return(1);
      }

      if(var.alt.size() > 1){
	continue;
      }

      if(currentSeqid != var.sequenceName){
	if(haplotypes[0][0].length() > 10){
	  calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);
	}
	clearHaplotypes(haplotypes, target_h.size());
	positions.clear();
	currentSeqid = var.sequenceName;
	afs.clear();
      }

      vector < map< string, vector<string> > > target, background, total;

      int sindex = 0;

      for(int nsamp = 0; nsamp < nsamples; nsamp++){

	map<string, vector<string> > sample = var.samples[ samples[nsamp]];

	if(it.find(sindex) != it.end() ){
	  target.push_back(sample);
	}
	sindex += 1;
      }

      genotype * populationTarget    ;

      if(type == "PL"){
	populationTarget     = new pl();
      }
      if(type == "GL"){
	populationTarget     = new gl();
      }
      if(type == "GP"){
	populationTarget     = new gp();
      }
      if(type == "GT"){
	populationTarget     = new gt();
      }

      populationTarget->loadPop(target, var.sequenceName, var.position);

      if(populationTarget->af == 1 || populationTarget->af == 0){
	continue;
      }
      positions.push_back(var.position);
      afs.push_back(populationTarget->af);
      loadPhased(haplotypes, populationTarget, populationTarget->gts.size());

      populationTarget = NULL;
      delete populationTarget;
    }

    calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);

    return 0;
}
<commit_msg>double int assignment did not work correctly<commit_after>#include "Variant.h"
#include "split.h"
#include "cdflib.hpp"
#include "pdflib.hpp"
#include "var.hpp"

#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <getopt.h>

using namespace std;
using namespace vcf;
void printVersion(void){
	    cerr << "INFO: version 1.1.0 ; date: April 2014 ; author: Zev Kronenberg; email : zev.kronenberg@utah.edu " << endl;
	    exit(1);

}

void printHelp(void){
  cerr << endl << endl;
  cerr << "INFO: help" << endl;
  cerr << "INFO: description:" << endl;
  cerr << "     iHS calculates the integrated ratio of haplotype decay between the reference and non-reference allele. " << endl;
  cerr << "     This implementation of iHS integrates over a SNP index, NOT a physical distance or genetic distance.   " << endl << endl;

  cerr << "Output : 4 columns :                  "    << endl;
  cerr << "     1. seqid                         "    << endl;
  cerr << "     2. position                      "    << endl;
  cerr << "     3. target allele frequency       "    << endl;
  cerr << "     4. integrated EHH (alternative)  "    << endl;
  cerr << "     5. integrated EHH (reference)    "    << endl;
  cerr << "     6. iHS log(iEHHalt/iEHHref)      "    << endl  << endl;

  cerr << "INFO: iHS  --target 0,1,2,3,4,5,6,7 --file my.phased.vcf  --region chr1:1-1000 " << endl << endl;

  cerr << "INFO: required: t,target  -- argument: a zero base comma separated list of target individuals corrisponding to VCF columns " << endl;
  cerr << "INFO: required: f,file    -- argument: proper formatted and phased VCF.                                                    " << endl;
  cerr << "INFO: required: y,type    -- argument: genotype likelihood format: PL,GL,GP                                                " << endl;
  cerr << "INFO: optional: r,region  -- argument: a tabix compliant genomic range : \"seqid:start-end\" or \"seqid\"                  " << endl;
  cerr << endl;

  printVersion();

  exit(1);
}

void clearHaplotypes(string haplotypes[][2], int ntarget){
  for(int i= 0; i < ntarget; i++){
    haplotypes[i][0].clear();
    haplotypes[i][1].clear();
  }
}

void loadIndices(map<int, int> & index, string set){

  vector<string>  indviduals = split(set, ",");
  vector<string>::iterator it = indviduals.begin();

  for(; it != indviduals.end(); it++){
    index[ atoi( (*it).c_str() ) ] = 1;
  }
}

void calc(string haplotypes[][2], int nhaps, vector<double> afs, vector<long int> pos, vector<int> & target, vector<int> & background, string seqid){

   //cerr << "about to calc" << endl;
   //cerr << "nhap:        " << nhaps << endl;

  for(int snp = 0; snp < haplotypes[0][0].length(); snp++){

    double ehhA = 1;
    double ehhR = 1;

    double iHSA = 1;
    double iHSR = 1;

    int start = snp;
    int end   = snp;
    int core  = snp;

    while( ehhA > 0.05 && ehhR > 0.05 ) {

      start -= 1;
      end   += 1;

      if(start == -1){
	break;
      }
      if(end == haplotypes[0][0].length() - 1){
	break;
      }

      map<string , int> targetH;

      double sumrT = 0;
      double sumaT = 0;
      double nrefT = 0;
      double naltT = 0;

      for(int i = 0; i < nhaps; i++){
	targetH[ haplotypes[i][0].substr(start, (end - start)) ]++;
	targetH[ haplotypes[i][1].substr(start, (end - start)) ]++;
      }
      for( map<string, int>::iterator th = targetH.begin(); th != targetH.end(); th++){
	if( (*th).first.substr((end-start)/2, 1) == "1"){
	   sumaT += r8_choose(th->second, 2);
	   naltT += th->second;
	}
	else{
	  sumrT += r8_choose(th->second, 2);
	  nrefT += th->second;
	}
      }

      ehhA = sumaT / (r8_choose(naltT, 2));
      ehhR = sumrT / (r8_choose(nrefT, 2));

      iHSA += ehhA;
      iHSR += ehhR;
    }
    if(isnan(iHSA) || isnan(iHSR)){
      continue;
    }
    cout << seqid << "\t" << pos[snp] << "\t" << afs[snp] << "\t" << iHSA << "\t" << iHSR << "\t" << log(iHSA/iHSR) << endl;
  }
}

double EHH(string haplotypes[][2], int nhaps){

  map<string , int> hapcounts;

  for(int i = 0; i < nhaps; i++){
    hapcounts[ haplotypes[i][0] ]++;
    hapcounts[ haplotypes[i][1] ]++;
  }

  double sum = 0;
  double nh  = 0;

  for( map<string, int>::iterator it = hapcounts.begin(); it != hapcounts.end(); it++){
    nh  += it->second;
    sum += r8_choose(it->second, 2);
  }

  double max = (sum /  r8_choose(nh, 2));

  return max;

}

void loadPhased(string haplotypes[][2], genotype * pop, int ntarget){

  int indIndex = 0;

  for(vector<string>::iterator ind = pop->gts.begin(); ind != pop->gts.end(); ind++){
    string g = (*ind);
    vector< string > gs = split(g, "|");
    haplotypes[indIndex][0].append(gs[0]);
    haplotypes[indIndex][1].append(gs[1]);
    indIndex += 1;
  }
}

int main(int argc, char** argv) {

  // set the random seed for MCMC

  srand((unsigned)time(NULL));

  // the filename

  string filename = "NA";

  // set region to scaffold

  string region = "NA";

  // using vcflib; thanks to Erik Garrison

  VariantCallFile variantFile;

  // zero based index for the target and background indivudals

  map<int, int> it, ib;

  // deltaaf is the difference of allele frequency we bother to look at

  // ancestral state is set to zero by default

  int counts = 0;

  // phased

  int phased = 0;

  string type = "NA";

    const struct option longopts[] =
      {
	{"version"   , 0, 0, 'v'},
	{"help"      , 0, 0, 'h'},
        {"file"      , 1, 0, 'f'},
	{"target"    , 1, 0, 't'},
	{"region"    , 1, 0, 'r'},
	{"type"      , 1, 0, 'y'},
	{0,0,0,0}
      };

    int findex;
    int iarg=0;

    while(iarg != -1)
      {
	iarg = getopt_long(argc, argv, "y:r:d:t:b:f:hv", longopts, &findex);

	switch (iarg)
	  {
	  case 'h':
	    printHelp();
	  case 'v':
	    printVersion();
	  case 'y':
	    type = optarg;
	    break;
	  case 't':
	    loadIndices(it, optarg);
	    cerr << "INFO: there are " << it.size() << " individuals in the target" << endl;
	    cerr << "INFO: target ids: " << optarg << endl;
	    break;
	  case 'f':
	    cerr << "INFO: file: " << optarg  <<  endl;
	    filename = optarg;
	    break;
	  case 'r':
            cerr << "INFO: set seqid region to : " << optarg << endl;
	    region = optarg;
	    break;
	  default:
	    break;
	  }
      }

    map<string, int> okayGenotypeLikelihoods;
    okayGenotypeLikelihoods["PL"] = 1;
    okayGenotypeLikelihoods["GL"] = 1;
    okayGenotypeLikelihoods["GP"] = 1;
    okayGenotypeLikelihoods["GT"] = 1;

    if(type == "NA"){
      cerr << "FATAL: failed to specify genotype likelihood format : PL or GL" << endl;
      printHelp();
      return 1;
    }
    if(okayGenotypeLikelihoods.find(type) == okayGenotypeLikelihoods.end()){
      cerr << "FATAL: genotype likelihood is incorrectly formatted, only use: PL or GL" << endl;
      printHelp();
      return 1;
    }

    if(filename == "NA"){
      cerr << "FATAL: did not specify a file" << endl;
      printHelp();
      return(1);
    }

    if(it.size() < 2){
      cerr << "FATAL: target option is required -- or -- less than two individuals in target\n";
      printHelp();
      return(1);
    }

    variantFile.open(filename);

    if(region != "NA"){
      if(! variantFile.setRegion(region)){
	cerr <<"FATAL: unable to set region" << endl;
	return 1;
      }
    }

    if (!variantFile.is_open()) {
        return 1;
    }

    Variant var(variantFile);

    vector<int> target_h, background_h;

    int index   = 0;
    int  indexi = 0;

    vector<string> samples = variantFile.sampleNames;
    int nsamples = samples.size();

    for(vector<string>::iterator samp = samples.begin(); samp != samples.end(); samp++){

      string sampleName = (*samp);

      if(it.find(index) != it.end() ){
	target_h.push_back(indexi);
	indexi++;
      }
      index++;
    }

    // cerr << "n in target : " << target_h.size() << endl;

    vector<long int> positions;

    vector<double> afs;

    string haplotypes [target_h.size()][2];

    string currentSeqid = "NA";

    // cerr << "about to loop variants" << endl;

    while (variantFile.getNextVariant(var)) {

      if(!var.isPhased()){
	cerr << "FATAL: Found an unphased variant. All genotypes must be phased!" << endl;
	return(1);
      }

      if(var.alt.size() > 1){
	continue;
      }

      if(currentSeqid != var.sequenceName){
	if(haplotypes[0][0].length() > 10){
	  calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);
	}
	clearHaplotypes(haplotypes, target_h.size());
	positions.clear();
	currentSeqid = var.sequenceName;
	afs.clear();
      }

      vector < map< string, vector<string> > > target, background, total;

      int sindex = 0;

      for(int nsamp = 0; nsamp < nsamples; nsamp++){

	map<string, vector<string> > sample = var.samples[ samples[nsamp]];

	if(it.find(sindex) != it.end() ){
	  target.push_back(sample);
	}
	sindex += 1;
      }

      genotype * populationTarget    ;

      if(type == "PL"){
	populationTarget     = new pl();
      }
      if(type == "GL"){
	populationTarget     = new gl();
      }
      if(type == "GP"){
	populationTarget     = new gp();
      }
      if(type == "GT"){
	populationTarget     = new gt();
      }

      populationTarget->loadPop(target, var.sequenceName, var.position);

      if(populationTarget->af == 1 || populationTarget->af == 0){
	delete populationTarget;
	continue;
      }
      positions.push_back(var.position);
      afs.push_back(populationTarget->af);
      loadPhased(haplotypes, populationTarget, populationTarget->gts.size());

      populationTarget = NULL;
      delete populationTarget;
    }

    calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);

    return 0;
}
<|endoftext|>


<commit_before>//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"

#include "lldb/Utility/Log.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Utility/DataExtractor.h"

using namespace lldb;
using namespace lldb_private;

namespace {
enum class ProcessState {
  Unknown,
  DiskSleep,
  Paging,
  Running,
  Sleeping,
  TracedOrStopped,
  Zombie,
};
}

namespace lldb_private {
class ProcessLaunchInfo;
}

static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
                          ProcessState &State, ::pid_t &TracerPid) {
  auto BufferOrError = getProcFile(Pid, "status");
  if (!BufferOrError)
    return false;

  llvm::StringRef Rest = BufferOrError.get()->getBuffer();
  while(!Rest.empty()) {
    llvm::StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');

    if (Line.consume_front("Gid:")) {
      // Real, effective, saved set, and file system GIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RGid, EGid;
      Line.consumeInteger(10, RGid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EGid);

      ProcessInfo.SetGroupID(RGid);
      ProcessInfo.SetEffectiveGroupID(EGid);
    } else if (Line.consume_front("Uid:")) {
      // Real, effective, saved set, and file system UIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RUid, EUid;
      Line.consumeInteger(10, RUid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EUid);

      ProcessInfo.SetUserID(RUid);
      ProcessInfo.SetEffectiveUserID(EUid);
    } else if (Line.consume_front("PPid:")) {
      ::pid_t PPid;
      Line.ltrim().consumeInteger(10, PPid);
      ProcessInfo.SetParentProcessID(PPid);
    } else if (Line.consume_front("State:")) {
      char S = Line.ltrim().front();
      switch (S) {
      case 'R':
        State = ProcessState::Running;
        break;
      case 'S':
        State = ProcessState::Sleeping;
        break;
      case 'D':
        State = ProcessState::DiskSleep;
        break;
      case 'Z':
        State = ProcessState::Zombie;
        break;
      case 'T':
        State = ProcessState::TracedOrStopped;
        break;
      case 'W':
        State = ProcessState::Paging;
        break;
      }
    } else if (Line.consume_front("TracerPid:")) {
      Line = Line.ltrim();
      Line.consumeInteger(10, TracerPid);
    }
  }
  return true;
}

static bool IsDirNumeric(const char *dname) {
  for (; *dname; dname++) {
    if (!isdigit(*dname))
      return false;
  }
  return true;
}

static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);

  auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
  if (!buffer_sp)
    return ArchSpec();

  uint8_t exe_class =
      llvm::object::getElfArchType(
          {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
          .first;

  switch (exe_class) {
  case llvm::ELF::ELFCLASS32:
    return HostInfo::GetArchitecture(HostInfo::eArchKind32);
  case llvm::ELF::ELFCLASS64:
    return HostInfo::GetArchitecture(HostInfo::eArchKind64);
  default:
    LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
    return ArchSpec();
  }
}

static bool GetProcessAndStatInfo(::pid_t pid,
                                  ProcessInstanceInfo &process_info,
                                  ProcessState &State, ::pid_t &tracerpid) {
  tracerpid = 0;
  process_info.Clear();

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
  llvm::SmallString<64> ProcExe;
  (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);
  std::string ExePath(PATH_MAX, '\0');

  ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
  if (len <= 0) {
    LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
             Status(errno, eErrorTypePOSIX));
    return false;
  }
  ExePath.resize(len);

  // If the binary has been deleted, the link name has " (deleted)" appended.
  // Remove if there.
  llvm::StringRef PathRef = ExePath;
  PathRef.consume_back(" (deleted)");

  process_info.SetArchitecture(GetELFProcessCPUType(PathRef));

  // Get the process environment.
  auto BufferOrError = getProcFile(pid, "environ");
  if (!BufferOrError)
    return false;
  std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);

  // Get the command line used to start the process.
  BufferOrError = getProcFile(pid, "cmdline");
  if (!BufferOrError)
    return false;
  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);

  // Get User and Group IDs and get tracer pid.
  if (!GetStatusInfo(pid, process_info, State, tracerpid))
    return false;

  process_info.SetProcessID(pid);
  process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);

  llvm::StringRef Rest = Environ->getBuffer();
  while (!Rest.empty()) {
    llvm::StringRef Var;
    std::tie(Var, Rest) = Rest.split('\0');
    process_info.GetEnvironment().insert(Var);
  }

  llvm::StringRef Arg0;
  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
  process_info.SetArg0(Arg0);
  while (!Rest.empty()) {
    llvm::StringRef Arg;
    std::tie(Arg, Rest) = Rest.split('\0');
    process_info.GetArguments().AppendArgument(Arg);
  }

  return true;
}

uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                             ProcessInstanceInfoList &process_infos) {
  static const char procdir[] = "/proc/";

  DIR *dirproc = opendir(procdir);
  if (dirproc) {
    struct dirent *direntry = nullptr;
    const uid_t our_uid = getuid();
    const lldb::pid_t our_pid = getpid();
    bool all_users = match_info.GetMatchAllUsers();

    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::pid_t pid = atoi(direntry->d_name);

      // Skip this process.
      if (pid == our_pid)
        continue;

      ::pid_t tracerpid;
      ProcessState State;
      ProcessInstanceInfo process_info;

      if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
        continue;

      // Skip if process is being debugged.
      if (tracerpid != 0)
        continue;

      if (State == ProcessState::Zombie)
        continue;

      // Check for user match if we're not matching all users and not running
      // as root.
      if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
        continue;

      if (match_info.Matches(process_info)) {
        process_infos.Append(process_info);
      }
    }

    closedir(dirproc);
  }

  return process_infos.GetSize();
}

bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
  bool tids_changed = false;
  static const char procdir[] = "/proc/";
  static const char taskdir[] = "/task/";
  std::string process_task_dir = procdir + llvm::to_string(pid) + taskdir;
  DIR *dirproc = opendir(process_task_dir.c_str());

  if (dirproc) {
    struct dirent *direntry = nullptr;
    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::tid_t tid = atoi(direntry->d_name);
      TidMap::iterator it = tids_to_attach.find(tid);
      if (it == tids_to_attach.end()) {
        tids_to_attach.insert(TidPair(tid, false));
        tids_changed = true;
      }
    }
    closedir(dirproc);
  }

  return tids_changed;
}

bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  ::pid_t tracerpid;
  ProcessState State;
  return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}

Environment Host::GetEnvironment() { return Environment(environ); }

Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
  return Status("unimplemented");
}
<commit_msg>fix<commit_after>//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"

#include "lldb/Utility/Log.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Utility/DataExtractor.h"

using namespace lldb;
using namespace lldb_private;

namespace {
enum class ProcessState {
  Unknown,
  DiskSleep,
  Paging,
  Running,
  Sleeping,
  TracedOrStopped,
  Zombie,
};
}

namespace lldb_private {
class ProcessLaunchInfo;
}

static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
                          ProcessState &State, ::pid_t &TracerPid) {
  auto BufferOrError = getProcFile(Pid, "status");
  if (!BufferOrError)
    return false;

  llvm::StringRef Rest = BufferOrError.get()->getBuffer();
  while(!Rest.empty()) {
    llvm::StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');

    if (Line.consume_front("Gid:")) {
      // Real, effective, saved set, and file system GIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RGid, EGid;
      Line.consumeInteger(10, RGid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EGid);

      ProcessInfo.SetGroupID(RGid);
      ProcessInfo.SetEffectiveGroupID(EGid);
    } else if (Line.consume_front("Uid:")) {
      // Real, effective, saved set, and file system UIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RUid, EUid;
      Line.consumeInteger(10, RUid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EUid);

      ProcessInfo.SetUserID(RUid);
      ProcessInfo.SetEffectiveUserID(EUid);
    } else if (Line.consume_front("PPid:")) {
      ::pid_t PPid;
      Line.ltrim().consumeInteger(10, PPid);
      ProcessInfo.SetParentProcessID(PPid);
    } else if (Line.consume_front("State:")) {
      char S = Line.ltrim().front();
      switch (S) {
      case 'R':
        State = ProcessState::Running;
        break;
      case 'S':
        State = ProcessState::Sleeping;
        break;
      case 'D':
        State = ProcessState::DiskSleep;
        break;
      case 'Z':
        State = ProcessState::Zombie;
        break;
      case 'T':
        State = ProcessState::TracedOrStopped;
        break;
      case 'W':
        State = ProcessState::Paging;
        break;
      }
    } else if (Line.consume_front("TracerPid:")) {
      Line = Line.ltrim();
      Line.consumeInteger(10, TracerPid);
    }
  }
  return true;
}

static bool IsDirNumeric(const char *dname) {
  for (; *dname; dname++) {
    if (!isdigit(*dname))
      return false;
  }
  return true;
}

static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);

  auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
  if (!buffer_sp)
    return ArchSpec();

  uint8_t exe_class =
      llvm::object::getElfArchType(
          {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
          .first;

  switch (exe_class) {
  case llvm::ELF::ELFCLASS32:
    return HostInfo::GetArchitecture(HostInfo::eArchKind32);
  case llvm::ELF::ELFCLASS64:
    return HostInfo::GetArchitecture(HostInfo::eArchKind64);
  default:
    LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
    return ArchSpec();
  }
}

static void GetProcessArgs(::pid_t pid, ProcessInstanceInfo &process_info) {
  auto BufferOrError = getProcFile(pid, "cmdline");
  if (!BufferOrError)
    return;
  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);

  llvm::StringRef Arg0, Rest;
  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
  process_info.SetArg0(Arg0);
  while (!Rest.empty()) {
    llvm::StringRef Arg;
    std::tie(Arg, Rest) = Rest.split('\0');
    process_info.GetArguments().AppendArgument(Arg);
  }
}

static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  std::string ExePath(PATH_MAX, '\0');

  // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
  llvm::SmallString<64> ProcExe;
  (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);

  ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
  if (len > 0) {
    ExePath.resize(len);
  } else {
    LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
             Status(errno, eErrorTypePOSIX));
    ExePath.resize(0);
  }
  // If the binary has been deleted, the link name has " (deleted)" appended.
  // Remove if there.
  llvm::StringRef PathRef = ExePath;
  PathRef.consume_back(" (deleted)");

  if (!PathRef.empty()) {
    process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
    process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
  }
}

static void GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) {
  // Get the process environment.
  auto BufferOrError = getProcFile(pid, "environ");
  if (!BufferOrError)
    return;

  std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
  llvm::StringRef Rest = Environ->getBuffer();
  while (!Rest.empty()) {
    llvm::StringRef Var;
    std::tie(Var, Rest) = Rest.split('\0');
    process_info.GetEnvironment().insert(Var);
  }
}

static bool GetProcessAndStatInfo(::pid_t pid,
                                  ProcessInstanceInfo &process_info,
                                  ProcessState &State, ::pid_t &tracerpid) {
  tracerpid = 0;
  process_info.Clear();

  process_info.SetProcessID(pid);

  GetExePathAndArch(pid, process_info);
  GetProcessArgs(pid, process_info);
  GetProcessEnviron(pid, process_info);

  // Get User and Group IDs and get tracer pid.
  if (!GetStatusInfo(pid, process_info, State, tracerpid))
    return false;

  return true;
}

uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                             ProcessInstanceInfoList &process_infos) {
  static const char procdir[] = "/proc/";

  DIR *dirproc = opendir(procdir);
  if (dirproc) {
    struct dirent *direntry = nullptr;
    const uid_t our_uid = getuid();
    const lldb::pid_t our_pid = getpid();
    bool all_users = match_info.GetMatchAllUsers();

    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::pid_t pid = atoi(direntry->d_name);

      // Skip this process.
      if (pid == our_pid)
        continue;

      ::pid_t tracerpid;
      ProcessState State;
      ProcessInstanceInfo process_info;

      if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
        continue;

      // Skip if process is being debugged.
      if (tracerpid != 0)
        continue;

      if (State == ProcessState::Zombie)
        continue;

      // Check for user match if we're not matching all users and not running
      // as root.
      if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
        continue;

      if (match_info.Matches(process_info)) {
        process_infos.Append(process_info);
      }
    }

    closedir(dirproc);
  }

  return process_infos.GetSize();
}

bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
  bool tids_changed = false;
  static const char procdir[] = "/proc/";
  static const char taskdir[] = "/task/";
  std::string process_task_dir = procdir + llvm::to_string(pid) + taskdir;
  DIR *dirproc = opendir(process_task_dir.c_str());

  if (dirproc) {
    struct dirent *direntry = nullptr;
    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::tid_t tid = atoi(direntry->d_name);
      TidMap::iterator it = tids_to_attach.find(tid);
      if (it == tids_to_attach.end()) {
        tids_to_attach.insert(TidPair(tid, false));
        tids_changed = true;
      }
    }
    closedir(dirproc);
  }

  return tids_changed;
}

bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  ::pid_t tracerpid;
  ProcessState State;
  return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}

Environment Host::GetEnvironment() { return Environment(environ); }

Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
  return Status("unimplemented");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: textedit.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 17:38:10 $
 *
 *  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 _TEXTEDIT_HXX
#define _TEXTEDIT_HXX

class AppEdit;
class TextEngine;
class TextView;
class TextEdit;
class BreakpointWindow;

#ifndef _SV_TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif
#ifndef _TOOLS_TABLE_HXX //autogen
#include <tools/table.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _SFXLSTNER_HXX //autogen
#include <svtools/lstner.hxx>
#endif
#include <svtools/svmedit.hxx>

#include "dataedit.hxx"

//#include <xtextedt.hxx>

class TextEditImp : public Window, public SfxListener
{
using Window::Notify;

protected:
    void            DoSyntaxHighlight( ULONG nPara );

private:
    AppEdit *pAppEdit;
    Link ModifyHdl;

    Timer           aSyntaxIdleTimer;
    Timer           aImplSyntaxIdleTimer;
    DECL_LINK( SyntaxTimerHdl, Timer * );
    Table           aSyntaxLineTable;

    void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    void            ImpDoHighlight( const String& rSource, ULONG nLineOff );
    BOOL            bHighlightning;
    BOOL            bDoSyntaxHighlight;
    BOOL            bDelayHighlight;

    SbxBase* GetSbxAtMousePos( String &aWord );
    virtual void MouseMove( const MouseEvent& rMEvt );
    DECL_LINK( HideVarContents, void* );
    DECL_LINK( ShowVarContents, void* );
    Point aTipPos;
    String aTipWord;
    ULONG nTipId;

    Timer HideTipTimer;
    Timer ShowTipTimer;

    BOOL bViewMoved;

public:
    TextEditImp( AppEdit *pParent, const WinBits& aBits );
    ~TextEditImp();

    TextEngine *pTextEngine;
    TextView *pTextView;

    void SetFont( const Font& rNewFont );
    BOOL IsModified();
    void SetModifyHdl( Link l ){ ModifyHdl = l; }

    void                KeyInput( const KeyEvent& rKeyEvent );
    void                Paint( const Rectangle& rRect );
    void                MouseButtonUp( const MouseEvent& rMouseEvent );
    void                MouseButtonDown( const MouseEvent& rMouseEvent );
//  void                MouseMove( const MouseEvent& rMouseEvent );
    void                Command( const CommandEvent& rCEvt );
    //BOOL              Drop( const DropEvent& rEvt );
    //BOOL              QueryDrop( DropEvent& rEvt );

    BOOL                ViewMoved();

    void DoDelayedSyntaxHighlight( xub_StrLen nPara );
    void InvalidateSyntaxHighlight();
    void SyntaxHighlight( BOOL bNew );
    void BuildKontextMenu( PopupMenu *&pMenu );
};

DBG_NAMEEX(TextEdit)
class TextEdit : public DataEdit {

    BreakpointWindow    *pBreakpointWindow;
    BOOL bFileWasUTF8;
    BOOL bSaveAsUTF8;

public:
    TextEdit( AppEdit*, const WinBits& );
    ~TextEdit();
    void Highlight( ULONG nLine, xub_StrLen nCol1, xub_StrLen nCol2 );
    TextEditImp& GetTextEditImp() { return aEdit; }

    void                SetBreakpointWindow( BreakpointWindow *pBPWindow ){ pBreakpointWindow = pBPWindow; }
    BreakpointWindow    *GetBreakpointWindow(){ return pBreakpointWindow; }

    DATA_FUNC_DEF( aEdit, TextEditImp )

    virtual void BuildKontextMenu( PopupMenu *&pMenu );

    void SaveAsUTF8( BOOL bUTF8 ) { bSaveAsUTF8 = bUTF8; }
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.8.192); FILE MERGED 2008/04/01 15:01:49 thb 1.8.192.2: #i85898# Stripping all external header guards 2008/03/28 16:07:06 rt 1.8.192.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textedit.hxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _TEXTEDIT_HXX
#define _TEXTEDIT_HXX

class AppEdit;
class TextEngine;
class TextView;
class TextEdit;
class BreakpointWindow;

#include <vcl/timer.hxx>
#include <tools/table.hxx>
#include <tools/debug.hxx>
#include <svtools/lstner.hxx>
#include <svtools/svmedit.hxx>

#include "dataedit.hxx"

//#include <xtextedt.hxx>

class TextEditImp : public Window, public SfxListener
{
using Window::Notify;

protected:
    void            DoSyntaxHighlight( ULONG nPara );

private:
    AppEdit *pAppEdit;
    Link ModifyHdl;

    Timer           aSyntaxIdleTimer;
    Timer           aImplSyntaxIdleTimer;
    DECL_LINK( SyntaxTimerHdl, Timer * );
    Table           aSyntaxLineTable;

    void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    void            ImpDoHighlight( const String& rSource, ULONG nLineOff );
    BOOL            bHighlightning;
    BOOL            bDoSyntaxHighlight;
    BOOL            bDelayHighlight;

    SbxBase* GetSbxAtMousePos( String &aWord );
    virtual void MouseMove( const MouseEvent& rMEvt );
    DECL_LINK( HideVarContents, void* );
    DECL_LINK( ShowVarContents, void* );
    Point aTipPos;
    String aTipWord;
    ULONG nTipId;

    Timer HideTipTimer;
    Timer ShowTipTimer;

    BOOL bViewMoved;

public:
    TextEditImp( AppEdit *pParent, const WinBits& aBits );
    ~TextEditImp();

    TextEngine *pTextEngine;
    TextView *pTextView;

    void SetFont( const Font& rNewFont );
    BOOL IsModified();
    void SetModifyHdl( Link l ){ ModifyHdl = l; }

    void                KeyInput( const KeyEvent& rKeyEvent );
    void                Paint( const Rectangle& rRect );
    void                MouseButtonUp( const MouseEvent& rMouseEvent );
    void                MouseButtonDown( const MouseEvent& rMouseEvent );
//  void                MouseMove( const MouseEvent& rMouseEvent );
    void                Command( const CommandEvent& rCEvt );
    //BOOL              Drop( const DropEvent& rEvt );
    //BOOL              QueryDrop( DropEvent& rEvt );

    BOOL                ViewMoved();

    void DoDelayedSyntaxHighlight( xub_StrLen nPara );
    void InvalidateSyntaxHighlight();
    void SyntaxHighlight( BOOL bNew );
    void BuildKontextMenu( PopupMenu *&pMenu );
};

DBG_NAMEEX(TextEdit)
class TextEdit : public DataEdit {

    BreakpointWindow    *pBreakpointWindow;
    BOOL bFileWasUTF8;
    BOOL bSaveAsUTF8;

public:
    TextEdit( AppEdit*, const WinBits& );
    ~TextEdit();
    void Highlight( ULONG nLine, xub_StrLen nCol1, xub_StrLen nCol2 );
    TextEditImp& GetTextEditImp() { return aEdit; }

    void                SetBreakpointWindow( BreakpointWindow *pBPWindow ){ pBreakpointWindow = pBPWindow; }
    BreakpointWindow    *GetBreakpointWindow(){ return pBreakpointWindow; }

    DATA_FUNC_DEF( aEdit, TextEditImp )

    virtual void BuildKontextMenu( PopupMenu *&pMenu );

    void SaveAsUTF8( BOOL bUTF8 ) { bSaveAsUTF8 = bUTF8; }
};

#endif
<|endoftext|>