<commit_before>#include "Endpoint.h"
#include "System/Buffers/Buffer.h"
#include "System/Threading/Mutex.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _WIN32
#include <winsock2.h>
#define s_addr S_un.S_addr
#define in_addr_t unsigned long
#undef SetPort
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif

// global mutex for gethostbyname
static Mutex    mutex;

#ifdef _WIN32
int inet_aton(const char *cp, struct in_addr *in)
{
    // TODO: IPv6
    if (strcmp(cp, "255.255.255.255") == 0)
    {
        in->s_addr = (u_long) 0xFFFFFFFF;
        return 1;
    }

    in->s_addr = inet_addr(cp);
    if (in->s_addr == INADDR_NONE)
        return 0;

    return 1;
}

int inet_pton(int /*af*/, const char* src, void* dst)
{
	// HACK: inet_pton is only supported from Vista
	return inet_aton(src, (struct in_addr*) dst);
}

#endif

// TODO this is temporary, we need a real DNS resolver
static bool DNS_ResolveIpv4(const char* name, struct in_addr* addr)
{
    // FIXME gethostbyname is not multithread-safe!
    struct hostent* hostent;

    MutexGuard      mutexGuard(mutex);

    hostent = gethostbyname(name);
    if (!hostent)
        return false;

    if (hostent->h_addrtype != AF_INET)
        return false;

    addr->s_addr = *(in_addr_t *) hostent->h_addr_list[0];

    // TODO: getaddrinfo doesn't work with "localhost"
#ifdef DNS_RESOLVE_GETADDRINFO
    struct addrinfo     hints;
    struct addrinfo*    res;

    memset((void*) &hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    if (!getaddrinfo(name, NULL, &hints, &res))
    {
        freeaddrinfo(res);
        return false;
    }

    addr->s_addr = *(u_long *) res->ai_addr;

    freeaddrinfo(res);
#endif

    return true;
}

Endpoint::Endpoint()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    memset((char *) sa, 0, sizeof(sa));
    sa->sin_family = 0; sa->sin_port = 0;
    sa->sin_addr.s_addr = 0; sa->sin_zero[0] = 0;
    buffer[0] = 0;
}

bool Endpoint::operator==(const Endpoint &other) const
{
    struct sockaddr_in *sa = (struct sockaddr_in *) &saBuffer;
    struct sockaddr_in *other_sa = (struct sockaddr_in *) &other.saBuffer;

    return  sa->sin_family == other_sa->sin_family &&
            sa->sin_port == other_sa->sin_port &&
            sa->sin_addr.s_addr == other_sa->sin_addr.s_addr;
}

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

bool Endpoint::Set(const char* ip, int port, bool resolv)
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    memset((char *) sa, 0, sizeof(sa));
    sa->sin_family = AF_INET;
    sa->sin_port = htons((uint16_t)port);
    if (inet_pton(AF_INET, ip, &sa->sin_addr) == 0)
    {
        if (resolv)
        {
            if (!DNS_ResolveIpv4(ip, &sa->sin_addr))
            {
                Log_Trace("DNS resolv failed");
                return false;
            }
            else
                return true;
        }

        Log_Trace("inet_aton() failed");
        return false;
    }
    return true;
}

bool Endpoint::Set(const char* ip_port, bool resolv)
{
    const char*     p;
    int             port;
    bool            ret;
    Buffer          ipbuf;

    p = ip_port;

    if (!IsValidEndpoint(ReadBuffer(ip_port)))
        return false;

    p = strrchr(ip_port, ':');
    if (p == NULL)
    {
        Log_Trace("No ':' in host specification");
        return false;
    }

    ipbuf.Append(ip_port, p - ip_port);
    ipbuf.NullTerminate();
    p++;

    port = -1;
    port = atoi(p);
    if (port < 1 || port > 65535)
    {
        Log_Trace("atoi() failed to produce a sensible value");
        return false;
    }

    ret = Set(ipbuf.GetBuffer(), port, resolv);

    return ret;
}

bool Endpoint::Set(ReadBuffer ip_port, bool resolv)
{
    const char*     p;
    const char*     start;
    int             port;
    bool            ret;
    Buffer          ipbuf;
    Buffer          portbuf;

    if (!IsValidEndpoint(ReadBuffer(ip_port)))
        return false;

    start = p = ip_port.GetBuffer();

    p = RevFindInBuffer(ip_port.GetBuffer(), ip_port.GetLength(), ':');
    if (p == NULL)
    {
        Log_Trace("No ':' in host specification");
        return false;
    }

    ipbuf.Append(start, p - start);
    ipbuf.NullTerminate();

    p++;
    portbuf.Append(p, ip_port.GetLength() - (p - start));
    portbuf.NullTerminate();

    port = -1;
    port = atoi(portbuf.GetBuffer());
    if (port < 1 || port > 65535)
    {
        Log_Trace("atoi() failed to produce a sensible value");
        return false;
    }

    ret = Set(ipbuf.GetBuffer(), port, resolv);

    return ret;
}

bool Endpoint::SetPort(int port)
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;
    sa->sin_port = htons((uint16_t)port);

    return true;
}

int Endpoint::GetPort()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    return ntohs(sa->sin_port);
}

Address Endpoint::GetAddress()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    return ntohl(sa->sin_addr.s_addr);
}

char* Endpoint::GetSockAddr()
{
    return saBuffer;
}

const char* Endpoint::ToString()
{
    return ToString(buffer);
}

const char* Endpoint::ToString(char s[ENDPOINT_STRING_SIZE])
{
    struct sockaddr_in *sa = (struct sockaddr_in *) &saBuffer;
    unsigned long addr;

    // inet_ntoa is not thread-safe and have a memory-leak issue on Linux
    addr = ntohl(sa->sin_addr.s_addr);
    snprintf(s, ENDPOINT_STRING_SIZE, "%lu.%lu.%lu.%lu:%u",
        (addr & 0xFF000000UL) >> 24,
        (addr & 0x00FF0000UL) >> 16,
        (addr & 0x0000FF00UL) >> 8,
        (addr & 0x000000FFUL),
        ntohs(sa->sin_port));

    return s;
}

ReadBuffer Endpoint::ToReadBuffer()
{
    size_t len;

    // TODO: optimize out strlen by doing snprintf directly
    ToString();
    len = strlen(buffer);

    return ReadBuffer(buffer, len);
}

bool Endpoint::IsSet()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;
    if (sa->sin_port == 0)
        return false;
    return true;
}

Address Endpoint::GetLoopbackAddress()
{
    return INADDR_LOOPBACK;
}

bool Endpoint::IsValidEndpoint(ReadBuffer ip_port)
{
    // Valid endpoint is either <IPv4-Address>:<port> or <IPv6-Address>:<port> or <Domain-Name>:<port>
    // Valid IPv4-Address consists only from numbers and three dots between the numbers
    // Valid IPv6-Adresses: http://en.wikipedia.org/wiki/IPv6#Addressing
    // Valid domain names: http://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names

    const char  VALID_CHARS[] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    unsigned    i;
    bool        labelStart;
    bool        isNumeric;
    bool        isHexnum;
    bool        isPort;
    bool        isIPv6;
    unsigned    numCommas;
    unsigned    numPortChars;
    char        c;
    char        prev;
    char        sep;
    char*       lastColon;

    // assuming fully numeric names
    isNumeric = true;
    isHexnum = true;
    isPort = false;
    numCommas = 0;
    numPortChars = 0;
    labelStart = true;
    isIPv6 = false;
    prev = ' ';
    sep = ' ';
    lastColon = NULL;
    for (i = 0; i < ip_port.GetLength(); i++)
    {
        c = ip_port.GetCharAt(i);

        if (c == '.' || c == ':')
        {
            if (i == 0)
            {
                // IPv4 and DNS must not start with comma or colon
                if (c == '.')
                    return false;

                isIPv6 = true;
                isHexnum = true;
            }

            // labels must not end with hyphens
            if (prev == VALID_CHARS[0])
                return false;

            if (c == '.')
            {
                labelStart = true;
                numCommas++;
                sep = c;
            }

            if (c == ':')
            {
                // cannot mix IPv4 and IPv6 addresses this way
                // this however is legal in IPv6: ::ffff:192.0.2.128
                if (isHexnum && sep != '.')
                {
                    isIPv6 = true;
                    sep = ':';
                    isPort = true;
                    numPortChars = 0;
                }
                else
                {
                    if (isPort && !isIPv6)
                        return false;
                    isPort = true;
                    numPortChars = 0;
                }

                lastColon = ip_port.GetBuffer() + i;
            }
        }
        else
        {
            // labels must not start with hyphens
            if (labelStart && c == VALID_CHARS[0])
                return false;

            if (isPort)
            {
                if (!isdigit(c))
                {
                    if (isIPv6)
                        isPort = false;
                    else
                        return false;
                }
                else
                    numPortChars++;
            }

            if (isNumeric && !isdigit(c))
                isNumeric = false;

            if (isHexnum && !isxdigit(c))
            {
                if (isIPv6)
                    return false;
                isHexnum = false;
            }

            if (strchr(VALID_CHARS, c) == NULL)
                return false;

            labelStart = false;
        }

        prev = c;
    }

    if (isNumeric && numCommas != 3)
        return false;
    if (isIPv6 && numCommas != 0 && numCommas != 3)
        return false;
    if (numPortChars < 1 || numPortChars > 5)
        return false;

    return true;
}

Mutex& Endpoint::GetMutex()
{
    return mutex;
}
<commit_msg>Cosmetic.<commit_after>#include "Endpoint.h"
#include "System/Buffers/Buffer.h"
#include "System/Threading/Mutex.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _WIN32
#include <winsock2.h>
#define s_addr S_un.S_addr
#define in_addr_t unsigned long
#undef SetPort
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif

// global mutex for gethostbyname
static Mutex    mutex;

#ifdef _WIN32
int inet_aton(const char *cp, struct in_addr *in)
{
    // TODO: IPv6
    if (strcmp(cp, "255.255.255.255") == 0)
    {
        in->s_addr = (u_long) 0xFFFFFFFF;
        return 1;
    }

    in->s_addr = inet_addr(cp);
    if (in->s_addr == INADDR_NONE)
        return 0;

    return 1;
}

int inet_pton(int /*af*/, const char* src, void* dst)
{
    // HACK: inet_pton is only supported from Vista
    return inet_aton(src, (struct in_addr*) dst);
}

#endif

// TODO this is temporary, we need a real DNS resolver
static bool DNS_ResolveIpv4(const char* name, struct in_addr* addr)
{
    // FIXME gethostbyname is not multithread-safe!
    struct hostent* hostent;

    MutexGuard      mutexGuard(mutex);

    hostent = gethostbyname(name);
    if (!hostent)
        return false;

    if (hostent->h_addrtype != AF_INET)
        return false;

    addr->s_addr = *(in_addr_t *) hostent->h_addr_list[0];

    // TODO: getaddrinfo doesn't work with "localhost"
#ifdef DNS_RESOLVE_GETADDRINFO
    struct addrinfo     hints;
    struct addrinfo*    res;

    memset((void*) &hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    if (!getaddrinfo(name, NULL, &hints, &res))
    {
        freeaddrinfo(res);
        return false;
    }

    addr->s_addr = *(u_long *) res->ai_addr;

    freeaddrinfo(res);
#endif

    return true;
}

Endpoint::Endpoint()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    memset((char *) sa, 0, sizeof(sa));
    sa->sin_family = 0; sa->sin_port = 0;
    sa->sin_addr.s_addr = 0; sa->sin_zero[0] = 0;
    buffer[0] = 0;
}

bool Endpoint::operator==(const Endpoint &other) const
{
    struct sockaddr_in *sa = (struct sockaddr_in *) &saBuffer;
    struct sockaddr_in *other_sa = (struct sockaddr_in *) &other.saBuffer;

    return  sa->sin_family == other_sa->sin_family &&
            sa->sin_port == other_sa->sin_port &&
            sa->sin_addr.s_addr == other_sa->sin_addr.s_addr;
}

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

bool Endpoint::Set(const char* ip, int port, bool resolv)
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    memset((char *) sa, 0, sizeof(sa));
    sa->sin_family = AF_INET;
    sa->sin_port = htons((uint16_t)port);
    if (inet_pton(AF_INET, ip, &sa->sin_addr) == 0)
    {
        if (resolv)
        {
            if (!DNS_ResolveIpv4(ip, &sa->sin_addr))
            {
                Log_Trace("DNS resolv failed");
                return false;
            }
            else
                return true;
        }

        Log_Trace("inet_aton() failed");
        return false;
    }
    return true;
}

bool Endpoint::Set(const char* ip_port, bool resolv)
{
    const char*     p;
    int             port;
    bool            ret;
    Buffer          ipbuf;

    p = ip_port;

    if (!IsValidEndpoint(ReadBuffer(ip_port)))
        return false;

    p = strrchr(ip_port, ':');
    if (p == NULL)
    {
        Log_Trace("No ':' in host specification");
        return false;
    }

    ipbuf.Append(ip_port, p - ip_port);
    ipbuf.NullTerminate();
    p++;

    port = -1;
    port = atoi(p);
    if (port < 1 || port > 65535)
    {
        Log_Trace("atoi() failed to produce a sensible value");
        return false;
    }

    ret = Set(ipbuf.GetBuffer(), port, resolv);

    return ret;
}

bool Endpoint::Set(ReadBuffer ip_port, bool resolv)
{
    const char*     p;
    const char*     start;
    int             port;
    bool            ret;
    Buffer          ipbuf;
    Buffer          portbuf;

    if (!IsValidEndpoint(ReadBuffer(ip_port)))
        return false;

    start = p = ip_port.GetBuffer();

    p = RevFindInBuffer(ip_port.GetBuffer(), ip_port.GetLength(), ':');
    if (p == NULL)
    {
        Log_Trace("No ':' in host specification");
        return false;
    }

    ipbuf.Append(start, p - start);
    ipbuf.NullTerminate();

    p++;
    portbuf.Append(p, ip_port.GetLength() - (p - start));
    portbuf.NullTerminate();

    port = -1;
    port = atoi(portbuf.GetBuffer());
    if (port < 1 || port > 65535)
    {
        Log_Trace("atoi() failed to produce a sensible value");
        return false;
    }

    ret = Set(ipbuf.GetBuffer(), port, resolv);

    return ret;
}

bool Endpoint::SetPort(int port)
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;
    sa->sin_port = htons((uint16_t)port);

    return true;
}

int Endpoint::GetPort()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    return ntohs(sa->sin_port);
}

Address Endpoint::GetAddress()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;

    return ntohl(sa->sin_addr.s_addr);
}

char* Endpoint::GetSockAddr()
{
    return saBuffer;
}

const char* Endpoint::ToString()
{
    return ToString(buffer);
}

const char* Endpoint::ToString(char s[ENDPOINT_STRING_SIZE])
{
    struct sockaddr_in *sa = (struct sockaddr_in *) &saBuffer;
    unsigned long addr;

    // inet_ntoa is not thread-safe and have a memory-leak issue on Linux
    addr = ntohl(sa->sin_addr.s_addr);
    snprintf(s, ENDPOINT_STRING_SIZE, "%lu.%lu.%lu.%lu:%u",
        (addr & 0xFF000000UL) >> 24,
        (addr & 0x00FF0000UL) >> 16,
        (addr & 0x0000FF00UL) >> 8,
        (addr & 0x000000FFUL),
        ntohs(sa->sin_port));

    return s;
}

ReadBuffer Endpoint::ToReadBuffer()
{
    size_t len;

    // TODO: optimize out strlen by doing snprintf directly
    ToString();
    len = strlen(buffer);

    return ReadBuffer(buffer, len);
}

bool Endpoint::IsSet()
{
    struct sockaddr_in *sa;

    sa = (struct sockaddr_in *) &saBuffer;
    if (sa->sin_port == 0)
        return false;
    return true;
}

Address Endpoint::GetLoopbackAddress()
{
    return INADDR_LOOPBACK;
}

bool Endpoint::IsValidEndpoint(ReadBuffer ip_port)
{
    // Valid endpoint is either <IPv4-Address>:<port> or <IPv6-Address>:<port> or <Domain-Name>:<port>
    // Valid IPv4-Address consists only from numbers and three dots between the numbers
    // Valid IPv6-Adresses: http://en.wikipedia.org/wiki/IPv6#Addressing
    // Valid domain names: http://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names

    const char  VALID_CHARS[] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    unsigned    i;
    bool        labelStart;
    bool        isNumeric;
    bool        isHexnum;
    bool        isPort;
    bool        isIPv6;
    unsigned    numCommas;
    unsigned    numPortChars;
    char        c;
    char        prev;
    char        sep;
    char*       lastColon;

    // assuming fully numeric names
    isNumeric = true;
    isHexnum = true;
    isPort = false;
    numCommas = 0;
    numPortChars = 0;
    labelStart = true;
    isIPv6 = false;
    prev = ' ';
    sep = ' ';
    lastColon = NULL;
    for (i = 0; i < ip_port.GetLength(); i++)
    {
        c = ip_port.GetCharAt(i);

        if (c == '.' || c == ':')
        {
            if (i == 0)
            {
                // IPv4 and DNS must not start with comma or colon
                if (c == '.')
                    return false;

                isIPv6 = true;
                isHexnum = true;
            }

            // labels must not end with hyphens
            if (prev == VALID_CHARS[0])
                return false;

            if (c == '.')
            {
                labelStart = true;
                numCommas++;
                sep = c;
            }

            if (c == ':')
            {
                // cannot mix IPv4 and IPv6 addresses this way
                // this however is legal in IPv6: ::ffff:192.0.2.128
                if (isHexnum && sep != '.')
                {
                    isIPv6 = true;
                    sep = ':';
                    isPort = true;
                    numPortChars = 0;
                }
                else
                {
                    if (isPort && !isIPv6)
                        return false;
                    isPort = true;
                    numPortChars = 0;
                }

                lastColon = ip_port.GetBuffer() + i;
            }
        }
        else
        {
            // labels must not start with hyphens
            if (labelStart && c == VALID_CHARS[0])
                return false;

            if (isPort)
            {
                if (!isdigit(c))
                {
                    if (isIPv6)
                        isPort = false;
                    else
                        return false;
                }
                else
                    numPortChars++;
            }

            if (isNumeric && !isdigit(c))
                isNumeric = false;

            if (isHexnum && !isxdigit(c))
            {
                if (isIPv6)
                    return false;
                isHexnum = false;
            }

            if (strchr(VALID_CHARS, c) == NULL)
                return false;

            labelStart = false;
        }

        prev = c;
    }

    if (isNumeric && numCommas != 3)
        return false;
    if (isIPv6 && numCommas != 0 && numCommas != 3)
        return false;
    if (numPortChars < 1 || numPortChars > 5)
        return false;

    return true;
}

Mutex& Endpoint::GetMutex()
{
    return mutex;
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Macro which loads and compiles the MUON macros:
//
// runSimulation.C               - ok, comp,  x;      Laurent
// runReconstruction.C           - ok, comp,  x;      Laurent
// fastMuonGen.C                 - ok, comp,  x;      Hermine, Alessandro
// fastMuonSim.C                 - ok, comp,  x;      Hermine, Alessandro
// DecodeRecoCocktail.C          - ok, comp,  README; Hermine, Alessandro
// ReadRecoCocktail.C            - ok, comp,  README; Hermine, Alessandro
// MergeMuonLight.C              - x,  comp,  README; Hermine, Alessandro
// MakeMUONFullMisAlignment.C    - ok, comp,  README; Javier, Ivana
// MakeMUONResMisAlignment.C     - ok, comp,  README; Javier, Ivana
// MakeMUONZeroMisAlignment.C    - ok, comp,  README; Javier, Ivana
// MUONAlignment.C               - ok, comp,  README; Javier
// MUONCheck.C                   - ok, comp,  x,      Frederic, in test
// MUONCheckDI.C                 - x,  !comp, x       Artur
// MUONCheckMisAligner.C         - ok, comp,  x,      Javier
// MUONdisplay.C                 - ok, comp,  deprecated
// MUONefficiency.C              - ok, comp,  README; Christophe, in test
// MUONGenerateBusPatch.C        - ok, comp,  x,      Christian
// MUONGenerateGeometryData.C    - ok, comp,  README; Ivana
// MUONGenerateTestGMS.C         - ok, comp,  READMEshuttle;  Ivana
// MUONmassPlot_ESD.C            - ok, comp,  README, Christian
// MUONplotefficiency.C          - ok, comp,  README; Christophe
// MUONRawStreamTracker.C        - x,  comp,  README; Christian
// MUONRawStreamTrigger.C        - x,  comp,  README; Christian
// MUONRecoCheck.C               - ok, comp,  README; Hermine, Alessandro
// MUONResoEffChamber.C          - ok, comp,  x,      Nicolas
// MUONStatusMap.C               - ok, comp,  x,      Laurent
// MUONTrigger.C                 - ok, comp,  README, Philippe C.
// MUONTriggerEfficiency.C       - ok, comp,  x,      Philippe C., in test
// MUONTriggerEfficiencyPt.C     - x,  comp,  README, Philippe C.
// MUONTriggerChamberEfficiency.C- x,  comp,  README, Diego
// TestMUONPreprocessor.C        - ok, comp,  READMEshuttle; Laurent
//
// 1st item:
// ok/fails/x - if the macro runs; x means that it was not tried either for lack
//              of documentation, or expertise
//
// 2nd item:
// comp/x     - if the macro can be compiled
//
// 3rd item:
// README*/x  - if it is documented in README, x means no doxumentation outside the
//              macro itself
//
// 4th item:  - author(s), responsible for macro maintenance
//
// eventually
// 5th item:  - if the macro is run within test scripts
//
// I. Hrivnacova

#if !defined(__CINT__) || defined(__MAKECINT__)

#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>

#endif

void loadmacros ()
{
  // Redefine include paths as some macros need
  // to see more than what is define in rootlogon.C
  //
  TString includePath = "-I${ALICE_ROOT}/include ";
  includePath        += "-I${ALICE_ROOT}/RAW ";
  includePath        += "-I${ALICE_ROOT}/FASTSIM ";
  includePath        += "-I${ALICE_ROOT}/EVGEN ";
  includePath        += "-I${ALICE_ROOT}/SHUTTLE/TestShuttle ";
  includePath        += "-I${ALICE_ROOT}/ITS ";
  includePath        += "-I${ALICE_ROOT}/MUON ";
  includePath        += "-I${ALICE_ROOT}/MUON/mapping";
  gSystem->SetIncludePath(includePath.Data());

  // Load libraries not linked with aliroot
  //
  gSystem->Load("$ALICE_ROOT/SHUTTLE/TestShuttle/libTestShuttle.so");
  gSystem->Load("libMUONshuttle.so");
  gSystem->Load("libMUONevaluation.so");

  // Load macros
  //
  gROOT->LoadMacro("$ALICE_ROOT/MUON/runSimulation.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/runReconstruction.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/fastMUONGen.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/fastMUONSim.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/DecodeRecoCocktail.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/ReadRecoCocktail.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MergeMuonLight.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MakeMUONFullMisAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MakeMUONResMisAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MakeMUONZeroMisAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONCheck.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONCheckDI.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONCheckMisAligner.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONefficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONGenerateBusPatch.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONGenerateGeometryData.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONGenerateTestGMS.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONmassPlot_ESD.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONplotefficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONRawStreamTracker.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONRawStreamTrigger.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONRecoCheck.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONResoEffChamber.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONStatusMap.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTrigger.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTriggerEfficiency.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTriggerEfficiencyPt.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTriggerChamberEfficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/TestMUONPreprocessor.C++");
}
<commit_msg>Uncommented MUONTriggerEfficiencyPt, migrated to data stores by Philippe C.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Macro which loads and compiles the MUON macros:
//
// runSimulation.C               - ok, comp,  x;      Laurent
// runReconstruction.C           - ok, comp,  x;      Laurent
// fastMuonGen.C                 - ok, comp,  x;      Hermine, Alessandro
// fastMuonSim.C                 - ok, comp,  x;      Hermine, Alessandro
// DecodeRecoCocktail.C          - ok, comp,  README; Hermine, Alessandro
// ReadRecoCocktail.C            - ok, comp,  README; Hermine, Alessandro
// MergeMuonLight.C              - x,  comp,  README; Hermine, Alessandro
// MakeMUONFullMisAlignment.C    - ok, comp,  README; Javier, Ivana
// MakeMUONResMisAlignment.C     - ok, comp,  README; Javier, Ivana
// MakeMUONZeroMisAlignment.C    - ok, comp,  README; Javier, Ivana
// MUONAlignment.C               - ok, comp,  README; Javier
// MUONCheck.C                   - ok, comp,  x,      Frederic, in test
// MUONCheckDI.C                 - x,  !comp, x       Artur
// MUONCheckMisAligner.C         - ok, comp,  x,      Javier
// MUONdisplay.C                 - ok, comp,  deprecated
// MUONefficiency.C              - ok, comp,  README; Christophe, in test
// MUONGenerateBusPatch.C        - ok, comp,  x,      Christian
// MUONGenerateGeometryData.C    - ok, comp,  README; Ivana
// MUONGenerateTestGMS.C         - ok, comp,  READMEshuttle;  Ivana
// MUONmassPlot_ESD.C            - ok, comp,  README, Christian
// MUONplotefficiency.C          - ok, comp,  README; Christophe
// MUONRawStreamTracker.C        - x,  comp,  README; Christian
// MUONRawStreamTrigger.C        - x,  comp,  README; Christian
// MUONRecoCheck.C               - ok, comp,  README; Hermine, Alessandro
// MUONResoEffChamber.C          - ok, comp,  x,      Nicolas
// MUONStatusMap.C               - ok, comp,  x,      Laurent
// MUONTrigger.C                 - ok, comp,  README, Philippe C.
// MUONTriggerEfficiency.C       - ok, comp,  x,      Philippe C., in test
// MUONTriggerEfficiencyPt.C     - x,  comp,  README, Philippe C.
// MUONTriggerChamberEfficiency.C- x,  comp,  README, Diego
// TestMUONPreprocessor.C        - ok, comp,  READMEshuttle; Laurent
//
// 1st item:
// ok/fails/x - if the macro runs; x means that it was not tried either for lack
//              of documentation, or expertise
//
// 2nd item:
// comp/x     - if the macro can be compiled
//
// 3rd item:
// README*/x  - if it is documented in README, x means no doxumentation outside the
//              macro itself
//
// 4th item:  - author(s), responsible for macro maintenance
//
// eventually
// 5th item:  - if the macro is run within test scripts
//
// I. Hrivnacova

#if !defined(__CINT__) || defined(__MAKECINT__)

#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>

#endif

void loadmacros ()
{
  // Redefine include paths as some macros need
  // to see more than what is define in rootlogon.C
  //
  TString includePath = "-I${ALICE_ROOT}/include ";
  includePath        += "-I${ALICE_ROOT}/RAW ";
  includePath        += "-I${ALICE_ROOT}/FASTSIM ";
  includePath        += "-I${ALICE_ROOT}/EVGEN ";
  includePath        += "-I${ALICE_ROOT}/SHUTTLE/TestShuttle ";
  includePath        += "-I${ALICE_ROOT}/ITS ";
  includePath        += "-I${ALICE_ROOT}/MUON ";
  includePath        += "-I${ALICE_ROOT}/MUON/mapping";
  gSystem->SetIncludePath(includePath.Data());

  // Load libraries not linked with aliroot
  //
  gSystem->Load("$ALICE_ROOT/SHUTTLE/TestShuttle/libTestShuttle.so");
  gSystem->Load("libMUONshuttle.so");
  gSystem->Load("libMUONevaluation.so");

  // Load macros
  //
  gROOT->LoadMacro("$ALICE_ROOT/MUON/runSimulation.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/runReconstruction.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/fastMUONGen.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/fastMUONSim.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/DecodeRecoCocktail.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/ReadRecoCocktail.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MergeMuonLight.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MakeMUONFullMisAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MakeMUONResMisAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MakeMUONZeroMisAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONAlignment.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONCheck.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONCheckDI.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONCheckMisAligner.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONefficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONGenerateBusPatch.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONGenerateGeometryData.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONGenerateTestGMS.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONmassPlot_ESD.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONplotefficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONRawStreamTracker.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONRawStreamTrigger.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONRecoCheck.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONResoEffChamber.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONStatusMap.C++");
  // gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTrigger.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTriggerEfficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTriggerEfficiencyPt.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/MUONTriggerChamberEfficiency.C++");
  gROOT->LoadMacro("$ALICE_ROOT/MUON/TestMUONPreprocessor.C++");
}
<|endoftext|>


<commit_before>#include <unistd.h>
#include <iostream>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include "config/config.h"
#include "helpers.h"

#include "utilities/aktualizr_version.h"

namespace bpo = boost::program_options;

static void log_info_target(const std::string &prefix, const Config &config, const Uptane::Target &t) {
  auto name = t.filename();
  if (t.custom_version().length() > 0) {
    name = t.custom_version();
  }
  LOG_INFO << prefix + name << "\tsha256:" << t.sha256Hash();
  if (config.pacman.type == PackageManager::kOstreeDockerApp) {
    bool shown = false;
    auto apps = t.custom_data()["docker_apps"];
    for (Json::ValueIterator i = apps.begin(); i != apps.end(); ++i) {
      if (!shown) {
        shown = true;
        LOG_INFO << "\tDocker Apps:";
      }
      if ((*i).isObject() && (*i).isMember("filename")) {
        LOG_INFO << "\t\t" << i.key().asString() << " -> " << (*i)["filename"].asString();
      } else {
        LOG_ERROR << "\t\tInvalid custom data for docker-app: " << i.key().asString();
      }
    }
  }
}

static int status_main(LiteClient &client, const bpo::variables_map &unused) {
  (void)unused;
  auto target = client.primary->getCurrent();

  if (target.MatchTarget(Uptane::Target::Unknown())) {
    LOG_INFO << "No active deployment found";
  } else {
    auto name = target.filename();
    if (target.custom_version().length() > 0) {
      name = target.custom_version();
    }
    log_info_target("Active image is: ", client.config, target);
  }
  return 0;
}

static int list_main(LiteClient &client, const bpo::variables_map &unused) {
  (void)unused;
  Uptane::HardwareIdentifier hwid(client.config.provision.primary_ecu_hardware_id);

  LOG_INFO << "Refreshing target metadata";
  if (!client.primary->updateImagesMeta()) {
    LOG_WARNING << "Unable to update latest metadata, using local copy";
    if (!client.primary->checkImagesMetaOffline()) {
      LOG_ERROR << "Unable to use local copy of TUF data";
      return 1;
    }
  }

  LOG_INFO << "Updates available to " << hwid << ":";
  for (auto &t : client.primary->allTargets()) {
    for (auto const &it : t.hardwareIds()) {
      if (it == hwid) {
        log_info_target("", client.config, t);
        break;
      }
    }
  }
  return 0;
}

static std::unique_ptr<Uptane::Target> find_target(const std::shared_ptr<SotaUptaneClient> &client,
                                                   Uptane::HardwareIdentifier &hwid, const std::string &version) {
  std::unique_ptr<Uptane::Target> rv;
  if (!client->updateImagesMeta()) {
    LOG_WARNING << "Unable to update latest metadata, using local copy";
    if (!client->checkImagesMetaOffline()) {
      LOG_ERROR << "Unable to use local copy of TUF data";
      throw std::runtime_error("Unable to find update");
    }
  }

  bool find_latest = (version == "latest");
  std::unique_ptr<Uptane::Target> latest = nullptr;
  for (auto &t : client->allTargets()) {
    for (auto const &it : t.hardwareIds()) {
      if (it == hwid) {
        if (find_latest) {
          if (latest == nullptr || Version(latest->custom_version()) < Version(t.custom_version())) {
            latest = std_::make_unique<Uptane::Target>(t);
          }
        } else if (version == t.filename() || version == t.custom_version()) {
          return std_::make_unique<Uptane::Target>(t);
        }
      }
    }
  }
  if (find_latest && latest != nullptr) {
    return latest;
  }
  throw std::runtime_error("Unable to find update");
}

static int do_update(LiteClient &client, Uptane::Target &target) {
  if (!client.primary->downloadImage(target).first) {
    return 1;
  }

  if (client.primary->VerifyTarget(target) != TargetStatus::kGood) {
    LOG_ERROR << "Downloaded target is invalid";
    return 1;
  }

  auto iresult = client.primary->PackageInstall(target);
  if (iresult.result_code.num_code == data::ResultCode::Numeric::kNeedCompletion) {
    LOG_INFO << "Update complete. Please reboot the device to activate";
    client.storage->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kPending);
  } else if (iresult.result_code.num_code == data::ResultCode::Numeric::kOk) {
    client.storage->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kCurrent);
  } else {
    LOG_ERROR << "Unable to install update: " << iresult.description;
    return 1;
  }
  LOG_INFO << iresult.description;
  return 0;
}

static int update_main(LiteClient &client, const bpo::variables_map &variables_map) {
  Uptane::HardwareIdentifier hwid(client.config.provision.primary_ecu_hardware_id);

  std::string version("latest");
  if (variables_map.count("update-name") > 0) {
    version = variables_map["update-name"].as<std::string>();
  }
  LOG_INFO << "Finding " << version << " to update to...";
  auto target = find_target(client.primary, hwid, version);
  LOG_INFO << "Updating to: " << *target;
  return do_update(client, *target);
}

struct SubCommand {
  const char *name;
  int (*main)(LiteClient &, const bpo::variables_map &);
};
static SubCommand commands[] = {
    {"status", status_main},
    {"list", list_main},
    {"update", update_main},
};

void check_info_options(const bpo::options_description &description, const bpo::variables_map &vm) {
  if (vm.count("help") != 0 || vm.count("command") == 0) {
    std::cout << description << '\n';
    exit(EXIT_SUCCESS);
  }
  if (vm.count("version") != 0) {
    std::cout << "Current aktualizr version is: " << aktualizr_version() << "\n";
    exit(EXIT_SUCCESS);
  }
}

bpo::variables_map parse_options(int argc, char *argv[]) {
  std::string subs("Command to execute: ");
  for (size_t i = 0; i < sizeof(commands) / sizeof(SubCommand); i++) {
    if (i != 0) {
      subs += ", ";
    }
    subs += commands[i].name;
  }
  bpo::options_description description("aktualizr-lite command line options");
  // clang-format off
  // Try to keep these options in the same order as Config::updateFromCommandLine().
  // The first three are commandline only.
  description.add_options()
      ("help,h", "print usage")
      ("version,v", "Current aktualizr version")
      ("config,c", bpo::value<std::vector<boost::filesystem::path> >()->composing(), "configuration file or directory")
      ("loglevel", bpo::value<int>(), "set log level 0-5 (trace, debug, info, warning, error, fatal)")
      ("repo-server", bpo::value<std::string>(), "url of the uptane repo repository")
      ("ostree-server", bpo::value<std::string>(), "url of the ostree repository")
      ("primary-ecu-hardware-id", bpo::value<std::string>(), "hardware ID of primary ecu")
      ("update-name", bpo::value<std::string>(), "optional name of the update when running \"update\". default=latest")
      ("command", bpo::value<std::string>(), subs.c_str());
  // clang-format on

  // consider the first positional argument as the aktualizr run mode
  bpo::positional_options_description pos;
  pos.add("command", 1);

  bpo::variables_map vm;
  std::vector<std::string> unregistered_options;
  try {
    bpo::basic_parsed_options<char> parsed_options =
        bpo::command_line_parser(argc, argv).options(description).positional(pos).allow_unregistered().run();
    bpo::store(parsed_options, vm);
    check_info_options(description, vm);
    bpo::notify(vm);
    unregistered_options = bpo::collect_unrecognized(parsed_options.options, bpo::exclude_positional);
    if (vm.count("help") == 0 && !unregistered_options.empty()) {
      std::cout << description << "\n";
      exit(EXIT_FAILURE);
    }
  } catch (const bpo::required_option &ex) {
    // print the error and append the default commandline option description
    std::cout << ex.what() << std::endl << description;
    exit(EXIT_FAILURE);
  } catch (const bpo::error &ex) {
    check_info_options(description, vm);

    // log boost error
    LOG_ERROR << "boost command line option error: " << ex.what();

    // print the error message to the standard output too, as the user provided
    // a non-supported commandline option
    std::cout << ex.what() << '\n';

    // set the returnValue, thereby ctest will recognize
    // that something went wrong
    exit(EXIT_FAILURE);
  }

  return vm;
}

int main(int argc, char *argv[]) {
  logger_init(isatty(1) == 1);
  logger_set_threshold(boost::log::trivial::info);

  bpo::variables_map commandline_map = parse_options(argc, argv);

  int r = EXIT_FAILURE;
  try {
    if (geteuid() != 0) {
      LOG_WARNING << "\033[31mRunning as non-root and may not work as expected!\033[0m\n";
    }

    Config config(commandline_map);
    config.storage.uptane_metadata_path = BasedPath(config.storage.path / "metadata");
    LOG_DEBUG << "Current directory: " << boost::filesystem::current_path().string();

    std::string cmd = commandline_map["command"].as<std::string>();
    for (size_t i = 0; i < sizeof(commands) / sizeof(SubCommand); i++) {
      if (cmd == commands[i].name) {
        LiteClient client(config);
        return commands[i].main(client, commandline_map);
      }
    }
    throw bpo::invalid_option_value(cmd);
    r = EXIT_SUCCESS;
  } catch (const std::exception &ex) {
    LOG_ERROR << ex.what();
  }
  return r;
}
<commit_msg>aktualizr-lite: version reporting<commit_after>#include <unistd.h>
#include <iostream>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include "config/config.h"
#include "helpers.h"

#include "utilities/aktualizr_version.h"

namespace bpo = boost::program_options;

static void log_info_target(const std::string &prefix, const Config &config, const Uptane::Target &t) {
  auto name = t.filename();
  if (t.custom_version().length() > 0) {
    name = t.custom_version();
  }
  LOG_INFO << prefix + name << "\tsha256:" << t.sha256Hash();
  if (config.pacman.type == PackageManager::kOstreeDockerApp) {
    bool shown = false;
    auto apps = t.custom_data()["docker_apps"];
    for (Json::ValueIterator i = apps.begin(); i != apps.end(); ++i) {
      if (!shown) {
        shown = true;
        LOG_INFO << "\tDocker Apps:";
      }
      if ((*i).isObject() && (*i).isMember("filename")) {
        LOG_INFO << "\t\t" << i.key().asString() << " -> " << (*i)["filename"].asString();
      } else {
        LOG_ERROR << "\t\tInvalid custom data for docker-app: " << i.key().asString();
      }
    }
  }
}

static int status_main(LiteClient &client, const bpo::variables_map &unused) {
  (void)unused;
  auto target = client.primary->getCurrent();

  if (target.MatchTarget(Uptane::Target::Unknown())) {
    LOG_INFO << "No active deployment found";
  } else {
    auto name = target.filename();
    if (target.custom_version().length() > 0) {
      name = target.custom_version();
    }
    log_info_target("Active image is: ", client.config, target);
  }
  return 0;
}

static int list_main(LiteClient &client, const bpo::variables_map &unused) {
  (void)unused;
  Uptane::HardwareIdentifier hwid(client.config.provision.primary_ecu_hardware_id);

  LOG_INFO << "Refreshing target metadata";
  if (!client.primary->updateImagesMeta()) {
    LOG_WARNING << "Unable to update latest metadata, using local copy";
    if (!client.primary->checkImagesMetaOffline()) {
      LOG_ERROR << "Unable to use local copy of TUF data";
      return 1;
    }
  }

  LOG_INFO << "Updates available to " << hwid << ":";
  for (auto &t : client.primary->allTargets()) {
    for (auto const &it : t.hardwareIds()) {
      if (it == hwid) {
        log_info_target("", client.config, t);
        break;
      }
    }
  }
  return 0;
}

static std::unique_ptr<Uptane::Target> find_target(const std::shared_ptr<SotaUptaneClient> &client,
                                                   Uptane::HardwareIdentifier &hwid, const std::string &version) {
  std::unique_ptr<Uptane::Target> rv;
  if (!client->updateImagesMeta()) {
    LOG_WARNING << "Unable to update latest metadata, using local copy";
    if (!client->checkImagesMetaOffline()) {
      LOG_ERROR << "Unable to use local copy of TUF data";
      throw std::runtime_error("Unable to find update");
    }
  }

  bool find_latest = (version == "latest");
  std::unique_ptr<Uptane::Target> latest = nullptr;
  for (auto &t : client->allTargets()) {
    for (auto const &it : t.hardwareIds()) {
      if (it == hwid) {
        if (find_latest) {
          if (latest == nullptr || Version(latest->custom_version()) < Version(t.custom_version())) {
            latest = std_::make_unique<Uptane::Target>(t);
          }
        } else if (version == t.filename() || version == t.custom_version()) {
          return std_::make_unique<Uptane::Target>(t);
        }
      }
    }
  }
  if (find_latest && latest != nullptr) {
    return latest;
  }
  throw std::runtime_error("Unable to find update");
}

static int do_update(LiteClient &client, Uptane::Target &target) {
  if (!client.primary->downloadImage(target).first) {
    return 1;
  }

  if (client.primary->VerifyTarget(target) != TargetStatus::kGood) {
    LOG_ERROR << "Downloaded target is invalid";
    return 1;
  }

  auto iresult = client.primary->PackageInstall(target);
  if (iresult.result_code.num_code == data::ResultCode::Numeric::kNeedCompletion) {
    LOG_INFO << "Update complete. Please reboot the device to activate";
    client.storage->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kPending);
  } else if (iresult.result_code.num_code == data::ResultCode::Numeric::kOk) {
    client.storage->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kCurrent);
  } else {
    LOG_ERROR << "Unable to install update: " << iresult.description;
    return 1;
  }
  LOG_INFO << iresult.description;
  return 0;
}

static int update_main(LiteClient &client, const bpo::variables_map &variables_map) {
  Uptane::HardwareIdentifier hwid(client.config.provision.primary_ecu_hardware_id);

  std::string version("latest");
  if (variables_map.count("update-name") > 0) {
    version = variables_map["update-name"].as<std::string>();
  }
  LOG_INFO << "Finding " << version << " to update to...";
  auto target = find_target(client.primary, hwid, version);
  LOG_INFO << "Updating to: " << *target;
  return do_update(client, *target);
}

struct SubCommand {
  const char *name;
  int (*main)(LiteClient &, const bpo::variables_map &);
};
static SubCommand commands[] = {
    {"status", status_main},
    {"list", list_main},
    {"update", update_main},
};

void check_info_options(const bpo::options_description &description, const bpo::variables_map &vm) {
  if (vm.count("help") != 0 || (vm.count("command") == 0 && vm.count("version") == 0)) {
    std::cout << description << '\n';
    exit(EXIT_SUCCESS);
  }
  if (vm.count("version") != 0) {
    std::cout << "Current aktualizr version is: " << aktualizr_version() << "\n";
    exit(EXIT_SUCCESS);
  }
}

bpo::variables_map parse_options(int argc, char *argv[]) {
  std::string subs("Command to execute: ");
  for (size_t i = 0; i < sizeof(commands) / sizeof(SubCommand); i++) {
    if (i != 0) {
      subs += ", ";
    }
    subs += commands[i].name;
  }
  bpo::options_description description("aktualizr-lite command line options");
  // clang-format off
  // Try to keep these options in the same order as Config::updateFromCommandLine().
  // The first three are commandline only.
  description.add_options()
      ("help,h", "print usage")
      ("version,v", "Current aktualizr version")
      ("config,c", bpo::value<std::vector<boost::filesystem::path> >()->composing(), "configuration file or directory")
      ("loglevel", bpo::value<int>(), "set log level 0-5 (trace, debug, info, warning, error, fatal)")
      ("repo-server", bpo::value<std::string>(), "url of the uptane repo repository")
      ("ostree-server", bpo::value<std::string>(), "url of the ostree repository")
      ("primary-ecu-hardware-id", bpo::value<std::string>(), "hardware ID of primary ecu")
      ("update-name", bpo::value<std::string>(), "optional name of the update when running \"update\". default=latest")
      ("command", bpo::value<std::string>(), subs.c_str());
  // clang-format on

  // consider the first positional argument as the aktualizr run mode
  bpo::positional_options_description pos;
  pos.add("command", 1);

  bpo::variables_map vm;
  std::vector<std::string> unregistered_options;
  try {
    bpo::basic_parsed_options<char> parsed_options =
        bpo::command_line_parser(argc, argv).options(description).positional(pos).allow_unregistered().run();
    bpo::store(parsed_options, vm);
    check_info_options(description, vm);
    bpo::notify(vm);
    unregistered_options = bpo::collect_unrecognized(parsed_options.options, bpo::exclude_positional);
    if (vm.count("help") == 0 && !unregistered_options.empty()) {
      std::cout << description << "\n";
      exit(EXIT_FAILURE);
    }
  } catch (const bpo::required_option &ex) {
    // print the error and append the default commandline option description
    std::cout << ex.what() << std::endl << description;
    exit(EXIT_FAILURE);
  } catch (const bpo::error &ex) {
    check_info_options(description, vm);

    // log boost error
    LOG_ERROR << "boost command line option error: " << ex.what();

    // print the error message to the standard output too, as the user provided
    // a non-supported commandline option
    std::cout << ex.what() << '\n';

    // set the returnValue, thereby ctest will recognize
    // that something went wrong
    exit(EXIT_FAILURE);
  }

  return vm;
}

int main(int argc, char *argv[]) {
  logger_init(isatty(1) == 1);
  logger_set_threshold(boost::log::trivial::info);

  bpo::variables_map commandline_map = parse_options(argc, argv);

  int r = EXIT_FAILURE;
  try {
    if (geteuid() != 0) {
      LOG_WARNING << "\033[31mRunning as non-root and may not work as expected!\033[0m\n";
    }

    Config config(commandline_map);
    config.storage.uptane_metadata_path = BasedPath(config.storage.path / "metadata");
    LOG_DEBUG << "Current directory: " << boost::filesystem::current_path().string();

    std::string cmd = commandline_map["command"].as<std::string>();
    for (size_t i = 0; i < sizeof(commands) / sizeof(SubCommand); i++) {
      if (cmd == commands[i].name) {
        LiteClient client(config);
        return commands[i].main(client, commandline_map);
      }
    }
    throw bpo::invalid_option_value(cmd);
    r = EXIT_SUCCESS;
  } catch (const std::exception &ex) {
    LOG_ERROR << ex.what();
  }
  return r;
}
<|endoftext|>


<commit_before>#include "Graphics.h"
using namespace std;

GraphicsInternals::GraphicsInternals(Bin* const bin, ThreadManager* const manager)
  : bin(bin), manager(manager) {}

GraphicsInternals::~GraphicsInternals() {}

void GraphicsInternals::openWindow(const string& name)
{
  window.create(sf::VideoMode(bin->getWidth(), bin->getHeight()), name, sf::Style::Default);
}

void GraphicsInternals::drawMap()
{
  sf::CircleShape hexa((*bin->getAllHexes()).getRadius(), 6); //Each hex will be a circle with 6 sides
  hexa.rotate(30);
  hexa.setOutlineThickness(0.8);
  hexa.setOutlineColor(sf::Color::Blue);
  hexa.setFillColor(sf::Color::White);
  hexa.setOrigin((*bin->getAllHexes()).getRadius(), (*bin->getAllHexes()).getRadius());
  for (const Bin::Hex& hex : bin->getAllHexes())
  {
    hexa.setPosition(hex.getX(), hex.getY());
    window.draw(hexa);
  }
}

void GraphicsInternals::drawEntities()
{
  //Every ent will be a red ring with a red dot at it's center
  if (bin->count())
    for (const Entity& entity : bin->getAll())
    {
      #include "../Compiler/EntityDrawCode.cpp"
    }
}

void GraphicsInternals::manageEvents()
{
  //check window events
  sf::Event event;
  while (window.pollEvent(event))
  {
    // "close requested" event: we close the window
    if (event.type == sf::Event::Closed)
    {
      manager->kill();
      window.close();
    }

    // catch the resize events
    if (event.type == sf::Event::Resized)
    {
      // update the view to the new size of the window
      sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
      window.setView(sf::View(visibleArea));
    }

    //zoom
    if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
    {
      // create a view half the size of the default view
      sf::View view = window.getView();
      if (event.mouseWheelScroll.delta <= -1)
        view.zoom(1.1);
      else if (event.mouseWheelScroll.delta >= 1)
        view.zoom(0.9);
      window.setView(view);
    }
  }
}

void GraphicsInternals::input()
{
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
  {
    sf::View view = window.getView();
    view.move(-moveSensitivity, 0);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
  {
    sf::View view = window.getView();
    view.move(moveSensitivity, 0);
    window.setView(view);
  }

  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
  {
    sf::View view = window.getView();
    view.move(0, -moveSensitivity);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
  {
    sf::View view = window.getView();
    view.move(0, moveSensitivity);
    window.setView(view);
  }
}

#include "../Plugins/Graphics/Graphics.cpp"
<commit_msg>Add Speed Controls (+/-)<commit_after>#include "Graphics.h"
using namespace std;

GraphicsInternals::GraphicsInternals(Bin* const bin, ThreadManager* const manager)
  : bin(bin), manager(manager) {}

GraphicsInternals::~GraphicsInternals() {}

void GraphicsInternals::openWindow(const string& name)
{
  window.create(sf::VideoMode(bin->getWidth(), bin->getHeight()), name, sf::Style::Default);
}

void GraphicsInternals::drawMap()
{
  sf::CircleShape hexa((*bin->getAllHexes()).getRadius(), 6); //Each hex will be a circle with 6 sides
  hexa.rotate(30);
  hexa.setOutlineThickness(0.8);
  hexa.setOutlineColor(sf::Color::Blue);
  hexa.setFillColor(sf::Color::White);
  hexa.setOrigin((*bin->getAllHexes()).getRadius(), (*bin->getAllHexes()).getRadius());
  for (const Bin::Hex& hex : bin->getAllHexes())
  {
    hexa.setPosition(hex.getX(), hex.getY());
    window.draw(hexa);
  }
}

void GraphicsInternals::drawEntities()
{
  //Every ent will be a red ring with a red dot at it's center
  if (bin->count())
    for (const Entity& entity : bin->getAll())
    {
      #include "../Compiler/EntityDrawCode.cpp"
    }
}

void GraphicsInternals::manageEvents()
{
  //check window events
  sf::Event event;
  while (window.pollEvent(event))
  {
    // "close requested" event: we close the window
    if (event.type == sf::Event::Closed)
    {
      manager->kill();
      window.close();
    }

    // catch the resize events
    if (event.type == sf::Event::Resized)
    {
      // update the view to the new size of the window
      sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
      window.setView(sf::View(visibleArea));
    }

    //zoom
    if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
    {
      // create a view half the size of the default view
      sf::View view = window.getView();
      if (event.mouseWheelScroll.delta <= -1)
        view.zoom(1.1);
      else if (event.mouseWheelScroll.delta >= 1)
        view.zoom(0.9);
      window.setView(view);
    }
  }
}

void GraphicsInternals::input()
{
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
  {
    sf::View view = window.getView();
    view.move(-moveSensitivity, 0);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
  {
    sf::View view = window.getView();
    view.move(moveSensitivity, 0);
    window.setView(view);
  }

  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
  {
    sf::View view = window.getView();
    view.move(0, -moveSensitivity);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
  {
    sf::View view = window.getView();
    view.move(0, moveSensitivity);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Add))
  {
    manager->setSpeed(manager->getSpeed()*2);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Subtract))
  {
    manager->setSpeed(manager->getSpeed()/2);
  }
}

#include "../Plugins/Graphics/Graphics.cpp"
<|endoftext|>


<commit_before>#include "Graphics.h"
using namespace std;

GraphicsInternals::GraphicsInternals(Bin* const bin, ThreadManager* const manager)
  : bin(bin), manager(manager) {}

GraphicsInternals::~GraphicsInternals() {}

void GraphicsInternals::openWindow(const string& name)
{
  window.create(sf::VideoMode(bin->getWidth(), bin->getHeight()), name, sf::Style::Default);
}

void GraphicsInternals::drawMap()
{
  sf::CircleShape hexa((*bin->getAllHexes()).getRadius(), 6); //Each hex will be a circle with 6 sides
  hexa.rotate(30);
  hexa.setOutlineThickness(0.8);
  hexa.setOutlineColor(sf::Color::Black);
  hexa.setFillColor(sf::Color::White);
  for (const Bin::Hex& hex : bin->getAllHexes())
  {
    hexa.setPosition(hex.getX(), hex.getY());
    window.draw(hexa);
  }
}

void GraphicsInternals::drawEntities()
{
  //Every ent will be a red ring with a red dot at it's center

  sf::CircleShape circularEnt(2, 30); //Each ent will be a circle of radius x
  circularEnt.setOrigin(2, 2);
  circularEnt.setOutlineThickness(0.8);
  circularEnt.setOutlineColor(sf::Color::Red);
  circularEnt.setFillColor(sf::Color::Transparent);

  sf::CircleShape entCenter(0.2, 30); //Each ent will be a circle of radius
  entCenter.setOrigin(0.2, 0.2);
  entCenter.setFillColor(sf::Color::Red);

  for (const Entity& entity : bin->getAll())
  {
    //Draw circle for entitiy
    circularEnt.setPosition(entity.getX(), entity.getY());
    window.draw(circularEnt);

    //Draw point for center
    entCenter.setPosition(entity.getX(), entity.getY());
    window.draw(entCenter);
  }
}

void GraphicsInternals::manageEvents()
{
  //check window events
  sf::Event event;
  while (window.pollEvent(event))
  {
    // "close requested" event: we close the window
    if (event.type == sf::Event::Closed)
    {
      manager->kill();
      window.close();
    }

    // catch the resize events
    if (event.type == sf::Event::Resized)
    {
      // update the view to the new size of the window
      sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
      window.setView(sf::View(visibleArea));
    }

    //zoom
    if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
    {
      // create a view half the size of the default view
      sf::View view = window.getView();
      if (event.mouseWheelScroll.delta <= -1)
        view.zoom(1.1);
      else if (event.mouseWheelScroll.delta >= 1)
        view.zoom(0.9);
      window.setView(view);
    }
  }
}

void GraphicsInternals::input()
{
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
  {
    sf::View view = window.getView();
    view.move(-moveSensitivity, 0);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
  {
    sf::View view = window.getView();
    view.move(moveSensitivity, 0);
    window.setView(view);
  }

  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
  {
    sf::View view = window.getView();
    view.move(0, -moveSensitivity);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
  {
    sf::View view = window.getView();
    view.move(0, moveSensitivity);
    window.setView(view);
  }
}

#include "../Plugins/Graphics/Graphics.cpp"
<commit_msg>Adjusted Hex Origin<commit_after>#include "Graphics.h"
using namespace std;

GraphicsInternals::GraphicsInternals(Bin* const bin, ThreadManager* const manager)
  : bin(bin), manager(manager) {}

GraphicsInternals::~GraphicsInternals() {}

void GraphicsInternals::openWindow(const string& name)
{
  window.create(sf::VideoMode(bin->getWidth(), bin->getHeight()), name, sf::Style::Default);
}

void GraphicsInternals::drawMap()
{
  sf::CircleShape hexa((*bin->getAllHexes()).getRadius(), 6); //Each hex will be a circle with 6 sides
  hexa.rotate(30);
  hexa.setOutlineThickness(0.8);
  hexa.setOutlineColor(sf::Color::Blue);
  hexa.setFillColor(sf::Color::White);
  hexa.setOrigin((*bin->getAllHexes()).getRadius(), (*bin->getAllHexes()).getRadius());
  for (const Bin::Hex& hex : bin->getAllHexes())
  {
    hexa.setPosition(hex.getX(), hex.getY());
    window.draw(hexa);
  }
}

void GraphicsInternals::drawEntities()
{
  //Every ent will be a red ring with a red dot at it's center

  sf::CircleShape circularEnt(2, 30); //Each ent will be a circle of radius x
  circularEnt.setOrigin(2, 2);
  circularEnt.setOutlineThickness(0.8);
  circularEnt.setOutlineColor(sf::Color::Red);
  circularEnt.setFillColor(sf::Color::Transparent);

  sf::CircleShape entCenter(0.2, 30); //Each ent will be a circle of radius
  entCenter.setOrigin(0.2, 0.2);
  entCenter.setFillColor(sf::Color::Red);

  for (const Entity& entity : bin->getAll())
  {
    //Draw circle for entitiy
    circularEnt.setPosition(entity.getX(), entity.getY());
    window.draw(circularEnt);

    //Draw point for center
    entCenter.setPosition(entity.getX(), entity.getY());
    window.draw(entCenter);
  }
}

void GraphicsInternals::manageEvents()
{
  //check window events
  sf::Event event;
  while (window.pollEvent(event))
  {
    // "close requested" event: we close the window
    if (event.type == sf::Event::Closed)
    {
      manager->kill();
      window.close();
    }

    // catch the resize events
    if (event.type == sf::Event::Resized)
    {
      // update the view to the new size of the window
      sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
      window.setView(sf::View(visibleArea));
    }

    //zoom
    if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
    {
      // create a view half the size of the default view
      sf::View view = window.getView();
      if (event.mouseWheelScroll.delta <= -1)
        view.zoom(1.1);
      else if (event.mouseWheelScroll.delta >= 1)
        view.zoom(0.9);
      window.setView(view);
    }
  }
}

void GraphicsInternals::input()
{
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
  {
    sf::View view = window.getView();
    view.move(-moveSensitivity, 0);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
  {
    sf::View view = window.getView();
    view.move(moveSensitivity, 0);
    window.setView(view);
  }

  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
  {
    sf::View view = window.getView();
    view.move(0, -moveSensitivity);
    window.setView(view);
  }
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
  {
    sf::View view = window.getView();
    view.move(0, moveSensitivity);
    window.setView(view);
  }
}

#include "../Plugins/Graphics/Graphics.cpp"
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * Copyright (c) 2007-2008 The Florida State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 *          Stephen Hines
 */

#ifndef __ARCH_ARM_PREDECODER_HH__
#define __ARCH_ARM_PREDECODER_HH__

#include "arch/arm/types.hh"
#include "base/misc.hh"
#include "base/types.hh"

class ThreadContext;

namespace ArmISA
{
    class Predecoder
    {
      protected:
        ThreadContext * tc;
        //The extended machine instruction being generated
        ExtMachInst emi;
        MachInst data;
        bool bigThumb;
        int offset;

      public:
        Predecoder(ThreadContext * _tc) :
            tc(_tc), data(0), bigThumb(false), offset(0)
        {}

        ThreadContext * getTC()
        {
            return tc;
        }

        void setTC(ThreadContext * _tc)
        {
            tc = _tc;
        }

        void reset()
        {
            bigThumb = false;
            offset = 0;
            emi = 0;
        }

        void process()
        {
            if (!emi.thumb) {
                emi.instBits = data;
                emi.sevenAndFour = bits(data, 7) && bits(data, 4);
                emi.isMisc = (bits(data, 24, 23) == 0x2 &&
                              bits(data, 20) == 0);
                DPRINTF(Predecoder, "Arm inst.\n");
            } else {
                uint16_t word = (data >> (offset * 8));
                if (bigThumb) {
                    // A 32 bit thumb inst is half collected.
                    emi.instBits = emi.instBits | word;
                    bigThumb = false;
                    offset += 2;
                    DPRINTF(Predecoder, "Second half of 32 bit Thumb.\n");
                } else {
                    uint16_t highBits = word & 0xF800;
                    if (highBits == 0xE800 || highBits == 0xF000 ||
                            highBits == 0xF800) {
                        // The start of a 32 bit thumb inst.
                        emi.bigThumb = 1;
                        if (offset == 0) {
                            // We've got the whole thing.
                            DPRINTF(Predecoder,
                                    "All of 32 bit Thumb.\n");
                            emi.instBits = (data >> 16) | (data << 16);
                            offset += 4;
                        } else {
                            // We only have the first half word.
                            DPRINTF(Predecoder,
                                    "First half of 32 bit Thumb.\n");
                            emi.instBits = (uint32_t)word << 16;
                            bigThumb = true;
                            offset += 2;
                        }
                    } else {
                        // A 16 bit thumb inst.
                        DPRINTF(Predecoder, "16 bit Thumb.\n");
                        offset += 2;
                        emi.instBits = word;
                        // Set the condition code field artificially.
                        emi.condCode = COND_UC;
                    }
                }
            }
        }

        //Use this to give data to the predecoder. This should be used
        //when there is control flow.
        void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
        {
            data = inst;
            offset = (fetchPC >= pc) ? 0 : pc - fetchPC;
            emi.thumb = (pc & (ULL(1) << PcTBitShift)) ? 1 : 0;
            process();
        }

        //Use this to give data to the predecoder. This should be used
        //when instructions are executed in order.
        void moreBytes(MachInst machInst)
        {
            moreBytes(0, 0, machInst);
        }

        bool needMoreBytes()
        {
            return sizeof(MachInst) > offset;
        }

        bool extMachInstReady()
        {
            // The only way an instruction wouldn't be ready is if this is a
            // 32 bit ARM instruction that's not 32 bit aligned.
            return !bigThumb;
        }

        int getInstSize()
        {
            return (!emi.thumb || emi.bigThumb) ? 4 : 2;
        }

        //This returns a constant reference to the ExtMachInst to avoid a copy
        ExtMachInst getExtMachInst()
        {
            ExtMachInst thisEmi = emi;
            emi = 0;
            return thisEmi;
        }
    };
};

#endif // __ARCH_ARM_PREDECODER_HH__
<commit_msg>ARM: Make the predecoder print out the ExtMachInst it gathered when traced.<commit_after>/*
 * Copyright (c) 2010 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * Copyright (c) 2007-2008 The Florida State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 *          Stephen Hines
 */

#ifndef __ARCH_ARM_PREDECODER_HH__
#define __ARCH_ARM_PREDECODER_HH__

#include "arch/arm/types.hh"
#include "base/misc.hh"
#include "base/types.hh"

class ThreadContext;

namespace ArmISA
{
    class Predecoder
    {
      protected:
        ThreadContext * tc;
        //The extended machine instruction being generated
        ExtMachInst emi;
        MachInst data;
        bool bigThumb;
        int offset;

      public:
        Predecoder(ThreadContext * _tc) :
            tc(_tc), data(0), bigThumb(false), offset(0)
        {}

        ThreadContext * getTC()
        {
            return tc;
        }

        void setTC(ThreadContext * _tc)
        {
            tc = _tc;
        }

        void reset()
        {
            bigThumb = false;
            offset = 0;
            emi = 0;
        }

        void process()
        {
            if (!emi.thumb) {
                emi.instBits = data;
                emi.sevenAndFour = bits(data, 7) && bits(data, 4);
                emi.isMisc = (bits(data, 24, 23) == 0x2 &&
                              bits(data, 20) == 0);
                DPRINTF(Predecoder, "Arm inst.\n");
            } else {
                uint16_t word = (data >> (offset * 8));
                if (bigThumb) {
                    // A 32 bit thumb inst is half collected.
                    emi.instBits = emi.instBits | word;
                    bigThumb = false;
                    offset += 2;
                    DPRINTF(Predecoder, "Second half of 32 bit Thumb: %#x.\n",
                            emi.instBits);
                } else {
                    uint16_t highBits = word & 0xF800;
                    if (highBits == 0xE800 || highBits == 0xF000 ||
                            highBits == 0xF800) {
                        // The start of a 32 bit thumb inst.
                        emi.bigThumb = 1;
                        if (offset == 0) {
                            // We've got the whole thing.
                            emi.instBits = (data >> 16) | (data << 16);
                            DPRINTF(Predecoder, "All of 32 bit Thumb: %#x.\n",
                                    emi.instBits);
                            offset += 4;
                        } else {
                            // We only have the first half word.
                            DPRINTF(Predecoder,
                                    "First half of 32 bit Thumb.\n");
                            emi.instBits = (uint32_t)word << 16;
                            bigThumb = true;
                            offset += 2;
                        }
                    } else {
                        // A 16 bit thumb inst.
                        offset += 2;
                        emi.instBits = word;
                        // Set the condition code field artificially.
                        emi.condCode = COND_UC;
                        DPRINTF(Predecoder, "16 bit Thumb: %#x.\n",
                                emi.instBits);
                    }
                }
            }
        }

        //Use this to give data to the predecoder. This should be used
        //when there is control flow.
        void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
        {
            data = inst;
            offset = (fetchPC >= pc) ? 0 : pc - fetchPC;
            emi.thumb = (pc & (ULL(1) << PcTBitShift)) ? 1 : 0;
            process();
        }

        //Use this to give data to the predecoder. This should be used
        //when instructions are executed in order.
        void moreBytes(MachInst machInst)
        {
            moreBytes(0, 0, machInst);
        }

        bool needMoreBytes()
        {
            return sizeof(MachInst) > offset;
        }

        bool extMachInstReady()
        {
            // The only way an instruction wouldn't be ready is if this is a
            // 32 bit ARM instruction that's not 32 bit aligned.
            return !bigThumb;
        }

        int getInstSize()
        {
            return (!emi.thumb || emi.bigThumb) ? 4 : 2;
        }

        //This returns a constant reference to the ExtMachInst to avoid a copy
        ExtMachInst getExtMachInst()
        {
            ExtMachInst thisEmi = emi;
            emi = 0;
            return thisEmi;
        }
    };
};

#endif // __ARCH_ARM_PREDECODER_HH__
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2016 Immo Software
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its contributors may
 *   be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*!
 * @file
 * @brief Source for Ar microkernel mutexes.
 */

#include "ar_internal.h"
#include <string.h>
#include <assert.h>

using namespace Ar;

//------------------------------------------------------------------------------
// Implementation
//------------------------------------------------------------------------------

// See ar_kernel.h for documentation of this function.
ar_status_t ar_mutex_create(ar_mutex_t * mutex, const char * name)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

    ar_status_t status = ar_semaphore_create(&mutex->m_sem, name, 1);

    if (status == kArSuccess)
    {
        // Start without an owner.
        mutex->m_owner = NULL;
        mutex->m_ownerLockCount = 0;
        mutex->m_originalPriority = 0;

        // Set the blocked list to sort by priority.
        mutex->m_sem.m_blockedList.m_predicate = ar_thread_sort_by_priority;

#if AR_GLOBAL_OBJECT_LISTS
        mutex->m_sem.m_createdNode.m_obj = mutex;
        g_ar.allObjects.semaphores.remove(&mutex->m_sem.m_createdNode);
        g_ar.allObjects.mutexes.add(&mutex->m_sem.m_createdNode);
#endif // AR_GLOBAL_OBJECT_LISTS
    }

    return status;
}

// See ar_kernel.h for documentation of this function.
//! @todo Return error when deleting a mutex that is still locked.
ar_status_t ar_mutex_delete(ar_mutex_t * mutex)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

#if AR_GLOBAL_OBJECT_LISTS
    g_ar.allObjects.mutexes.remove(&mutex->m_sem.m_createdNode);
#endif // AR_GLOBAL_OBJECT_LISTS

    return kArSuccess;
}

// See ar_kernel.h for documentation of this function.
ar_status_t ar_mutex_get(ar_mutex_t * mutex, uint32_t timeout)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

    // Handle locked kernel in irq state by deferring the get.
    if (ar_port_get_irq_state() && g_ar.lockCount)
    {
        return ar_post_deferred_action(kArDeferredMutexGet, mutex);
    }

    {
        KernelLock guard;

        // If this thread already owns the mutex, just increment the count.
        if (g_ar.currentThread == mutex->m_owner)
        {
            ++mutex->m_ownerLockCount;
            return kArSuccess;
        }
        // Otherwise attempt to get the mutex.
        else
        {
            // Will we block?
            if (mutex->m_sem.m_count == 0)
            {
                // Return immediately if the timeout is 0. No reason to call into the sem code.
                if (timeout == kArNoTimeout)
                {
                    return kArTimeoutError;
                }

                // Check if we need to hoist the owning thread's priority to our own.
                ar_thread_t * self = g_ar.currentThread;
                if (self->m_priority > mutex->m_owner->m_priority)
                {
                    if (!mutex->m_originalPriority)
                    {
                        mutex->m_originalPriority = mutex->m_owner->m_priority;
                    }
                    mutex->m_owner->m_priority = self->m_priority;
                }
            }

            ar_status_t result = ar_semaphore_get(&mutex->m_sem, timeout);
            if (result == kArSuccess)
            {
                // Set the owner now that we own the lock.
                mutex->m_owner = g_ar.currentThread;
                ++mutex->m_ownerLockCount;
            }
            else if (result == kArTimeoutError)
            {
                //! @todo Need to handle timeout after hoisting the owner thread.

            }

            return result;
        }
    }
}

// See ar_kernel.h for documentation of this function.
ar_status_t ar_mutex_put(ar_mutex_t * mutex)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

    // Handle locked kernel in irq state by deferring the put.
    if (ar_port_get_irq_state() && g_ar.lockCount)
    {
        return ar_post_deferred_action(kArDeferredMutexPut, mutex);
    }

    ar_status_t result = kArSuccess;

    {
        KernelLock guard;

        // Nothing to do if the mutex is already unlocked.
        if (mutex->m_ownerLockCount == 0)
        {
            return kArAlreadyUnlockedError;
        }

        // Only the owning thread can unlock a mutex.
        ar_thread_t * self = g_ar.currentThread;
        if (self != mutex->m_owner)
        {
            return kArNotOwnerError;
        }

        // We are the owner of the mutex, so decrement its recursive lock count.
        if (--mutex->m_ownerLockCount == 0)
        {
            // The lock count has reached zero, so put the semaphore and clear the owner.
            // The owner is cleared first since putting the sem can cause us to
            // switch threads.
            mutex->m_owner = NULL;

            result = ar_semaphore_put(&mutex->m_sem);

            // Restore this thread's priority if it had been raised.
            uint8_t original = mutex->m_originalPriority;
            if (original)
            {
                mutex->m_originalPriority = 0;
                ar_thread_set_priority(self, original);
            }
        }
    }

    return result;
}

// See ar_kernel.h for documentation of this function.
bool ar_mutex_is_locked(ar_mutex_t * mutex)
{
    return mutex ? mutex->m_sem.m_count == 0 : false;
}

// See ar_kernel.h for documentation of this function.
ar_thread_t * ar_mutex_get_owner(ar_mutex_t * mutex)
{
    return mutex ? (ar_thread_t *)mutex->m_owner : NULL;
}

// See ar_kernel.h for documentation of this function.
const char * ar_mutex_get_name(ar_mutex_t * mutex)
{
    return mutex ? mutex->m_sem.m_name : NULL;
}

//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------
<commit_msg>Fixed regression in mutex.<commit_after>/*
 * Copyright (c) 2007-2016 Immo Software
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its contributors may
 *   be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*!
 * @file
 * @brief Source for Ar microkernel mutexes.
 */

#include "ar_internal.h"
#include <string.h>
#include <assert.h>

using namespace Ar;

//------------------------------------------------------------------------------
// Implementation
//------------------------------------------------------------------------------

// See ar_kernel.h for documentation of this function.
ar_status_t ar_mutex_create(ar_mutex_t * mutex, const char * name)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

    ar_status_t status = ar_semaphore_create(&mutex->m_sem, name, 1);

    if (status == kArSuccess)
    {
        // Start without an owner.
        mutex->m_owner = NULL;
        mutex->m_ownerLockCount = 0;
        mutex->m_originalPriority = 0;

        // Set the blocked list to sort by priority.
        mutex->m_sem.m_blockedList.m_predicate = ar_thread_sort_by_priority;

#if AR_GLOBAL_OBJECT_LISTS
        mutex->m_sem.m_createdNode.m_obj = mutex;
        g_ar.allObjects.semaphores.remove(&mutex->m_sem.m_createdNode);
        g_ar.allObjects.mutexes.add(&mutex->m_sem.m_createdNode);
#endif // AR_GLOBAL_OBJECT_LISTS
    }

    return status;
}

// See ar_kernel.h for documentation of this function.
//! @todo Return error when deleting a mutex that is still locked.
ar_status_t ar_mutex_delete(ar_mutex_t * mutex)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

#if AR_GLOBAL_OBJECT_LISTS
    g_ar.allObjects.mutexes.remove(&mutex->m_sem.m_createdNode);
#endif // AR_GLOBAL_OBJECT_LISTS

    return kArSuccess;
}

// See ar_kernel.h for documentation of this function.
ar_status_t ar_mutex_get(ar_mutex_t * mutex, uint32_t timeout)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

    // Handle locked kernel in irq state by deferring the get.
    if (ar_port_get_irq_state() && g_ar.lockCount)
    {
        return ar_post_deferred_action(kArDeferredMutexGet, mutex);
    }

    {
        KernelLock guard;

        // If this thread already owns the mutex, just increment the count.
        if (g_ar.currentThread == mutex->m_owner)
        {
            ++mutex->m_ownerLockCount;
            return kArSuccess;
        }
        // Otherwise attempt to get the mutex.
        else
        {
            // Will we block?
            if (mutex->m_sem.m_count == 0)
            {
                // Return immediately if the timeout is 0. No reason to call into the sem code.
                if (timeout == kArNoTimeout)
                {
                    return kArTimeoutError;
                }

                // Check if we need to hoist the owning thread's priority to our own.
                ar_thread_t * self = g_ar.currentThread;
                if (self->m_priority > mutex->m_owner->m_priority)
                {
                    if (!mutex->m_originalPriority)
                    {
                        mutex->m_originalPriority = mutex->m_owner->m_priority;
                    }
                    mutex->m_owner->m_priority = self->m_priority;
                }
            }

            ar_status_t result;
            {
                KernelUnlock unlock;
                result = ar_semaphore_get(&mutex->m_sem, timeout);
            }
            if (result == kArSuccess)
            {
                // Set the owner now that we own the lock.
                mutex->m_owner = g_ar.currentThread;
                ++mutex->m_ownerLockCount;
            }
            else if (result == kArTimeoutError)
            {
                //! @todo Need to handle timeout after hoisting the owner thread.

            }

            return result;
        }
    }
}

// See ar_kernel.h for documentation of this function.
ar_status_t ar_mutex_put(ar_mutex_t * mutex)
{
    if (!mutex)
    {
        return kArInvalidParameterError;
    }

    // Handle locked kernel in irq state by deferring the put.
    if (ar_port_get_irq_state() && g_ar.lockCount)
    {
        return ar_post_deferred_action(kArDeferredMutexPut, mutex);
    }

    ar_status_t result = kArSuccess;

    {
        KernelLock guard;

        // Nothing to do if the mutex is already unlocked.
        if (mutex->m_ownerLockCount == 0)
        {
            return kArAlreadyUnlockedError;
        }

        // Only the owning thread can unlock a mutex.
        ar_thread_t * self = g_ar.currentThread;
        if (self != mutex->m_owner)
        {
            return kArNotOwnerError;
        }

        // We are the owner of the mutex, so decrement its recursive lock count.
        if (--mutex->m_ownerLockCount == 0)
        {
            // The lock count has reached zero, so put the semaphore and clear the owner.
            // The owner is cleared first since putting the sem can cause us to
            // switch threads.
            mutex->m_owner = NULL;

            {
                KernelUnlock unlock;
                result = ar_semaphore_put(&mutex->m_sem);
            }

            // Restore this thread's priority if it had been raised.
            uint8_t original = mutex->m_originalPriority;
            if (original)
            {
                mutex->m_originalPriority = 0;
                ar_thread_set_priority(self, original);
            }
        }
    }

    return result;
}

// See ar_kernel.h for documentation of this function.
bool ar_mutex_is_locked(ar_mutex_t * mutex)
{
    return mutex ? mutex->m_sem.m_count == 0 : false;
}

// See ar_kernel.h for documentation of this function.
ar_thread_t * ar_mutex_get_owner(ar_mutex_t * mutex)
{
    return mutex ? (ar_thread_t *)mutex->m_owner : NULL;
}

// See ar_kernel.h for documentation of this function.
const char * ar_mutex_get_name(ar_mutex_t * mutex)
{
    return mutex ? mutex->m_sem.m_name : NULL;
}

//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------
<|endoftext|>


<commit_before>#ifndef ARGPARSE_FORMATTER_HPP
#define ARGPARSE_FORMATTER_HPP
#include <string>

namespace argparse {

    class ArgumentParser;

    class Formatter {
        public:
            virtual ~Formatter() {};
            virtual void set_parser(ArgumentParser* parser) = 0;
            virtual std::string format_usage() const = 0;
            virtual std::string format_description() const = 0;
            virtual std::string format_arguments() const = 0;
            virtual std::string format_epilog() const = 0;
            virtual std::string format_version() const = 0;
    };

    class DefaultFormatter : public Formatter {
        public:
            DefaultFormatter(size_t option_arg_width=20, size_t total_width=80);
            void set_parser(ArgumentParser* parser) override;
            std::string format_usage() const override;
            std::string format_description() const override;
            std::string format_arguments() const override;
            std::string format_epilog() const override;
            std::string format_version() const override;
        private:
            size_t option_name_width_;
            size_t total_width_;
            ArgumentParser* parser_;
    };

} //namespace
#endif
<commit_msg>Remove extra semicolon<commit_after>#ifndef ARGPARSE_FORMATTER_HPP
#define ARGPARSE_FORMATTER_HPP
#include <string>

namespace argparse {

    class ArgumentParser;

    class Formatter {
        public:
            virtual ~Formatter() {}
            virtual void set_parser(ArgumentParser* parser) = 0;
            virtual std::string format_usage() const = 0;
            virtual std::string format_description() const = 0;
            virtual std::string format_arguments() const = 0;
            virtual std::string format_epilog() const = 0;
            virtual std::string format_version() const = 0;
    };

    class DefaultFormatter : public Formatter {
        public:
            DefaultFormatter(size_t option_arg_width=20, size_t total_width=80);
            void set_parser(ArgumentParser* parser) override;
            std::string format_usage() const override;
            std::string format_description() const override;
            std::string format_arguments() const override;
            std::string format_epilog() const override;
            std::string format_version() const override;
        private:
            size_t option_name_width_;
            size_t total_width_;
            ArgumentParser* parser_;
    };

} //namespace
#endif
<|endoftext|>