<commit_before>#include "kwm.h"

CFMachPortRef EventTap;

kwm_code KWMCode;
std::string KwmFilePath;
std::string HotkeySOFullFilePath;
bool KwmUseBuiltinHotkeys;

uint32_t MaxDisplayCount = 5;
uint32_t ActiveDisplaysCount;
CGDirectDisplayID ActiveDisplays[5];

screen_info *Screen;
int DefaultPaddingTop = 40, DefaultPaddingBottom = 20;
int DefaultPaddingLeft = 20, DefaultPaddingRight = 20;
int DefaultGapVertical = 10, DefaultGapHorizontal = 10;

std::map<unsigned int, screen_info> DisplayMap;
std::vector<window_info> WindowLst;
std::vector<int> FloatingSpaceLst;
std::vector<std::string> FloatingAppLst;
std::vector<int> FloatingWindowLst;

ProcessSerialNumber FocusedPSN;
window_info *FocusedWindow;
focus_option KwmFocusMode;
int KwmSplitMode = -1;
int MarkedWindowID = -1;
bool IsWindowDragInProgress = false;

pthread_t BackgroundThread;
pthread_t DaemonThread;

pthread_mutex_t BackgroundLock;

CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    pthread_mutex_lock(&BackgroundLock);

    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            DEBUG("Restarting Event Tap")
            CGEventTapEnable(EventTap, true);
        } break;
        case kCGEventKeyDown:
        {
            if(KwmUseBuiltinHotkeys)
            {
                CGEventFlags Flags = CGEventGetFlags(Event);
                bool CmdKey = (Flags & kCGEventFlagMaskCommand) == kCGEventFlagMaskCommand;
                bool AltKey = (Flags & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate;
                bool CtrlKey = (Flags & kCGEventFlagMaskControl) == kCGEventFlagMaskControl;
                bool ShiftKey = (Flags & kCGEventFlagMaskShift) == kCGEventFlagMaskShift;

                CGKeyCode Keycode = (CGKeyCode)CGEventGetIntegerValueField(Event, kCGKeyboardEventKeycode);

                std::string NewHotkeySOFileTime = KwmGetFileTime(HotkeySOFullFilePath.c_str());
                if(NewHotkeySOFileTime != "" &&
                   NewHotkeySOFileTime != KWMCode.HotkeySOFileTime)
                {
                    DEBUG("Reloading hotkeys.so")
                    UnloadKwmCode(&KWMCode);
                    KWMCode = LoadKwmCode();
                }

                if(KWMCode.IsValid)
                {
                    // Hotkeys specific to Kwms functionality
                    if(KWMCode.KWMHotkeyCommands(CmdKey, CtrlKey, AltKey, ShiftKey, Keycode))
                    {
                        pthread_mutex_unlock(&BackgroundLock);
                        return NULL;
                    }

                    // Capture custom hotkeys specified by the user
                    if(KWMCode.CustomHotkeyCommands(CmdKey, CtrlKey, AltKey, ShiftKey, Keycode))
                    {
                        pthread_mutex_unlock(&BackgroundLock);
                        return NULL;
                    }

                    // Let system hotkeys pass through as normal
                    if(KWMCode.SystemHotkeyCommands(CmdKey, CtrlKey, AltKey, ShiftKey, Keycode))
                    {
                        pthread_mutex_unlock(&BackgroundLock);
                        return Event;
                    }

                    int NewKeycode;
                    KWMCode.RemapKeys(Event, &CmdKey, &CtrlKey, &AltKey, &ShiftKey, Keycode, &NewKeycode);
                    if(NewKeycode != -1)
                    {
                        CGEventSetFlags(Event, 0);

                        if(CmdKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskCommand);

                        if(AltKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskAlternate);

                        if(CtrlKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskControl);

                        if(ShiftKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskShift);

                        CGEventSetIntegerValueField(Event, kCGKeyboardEventKeycode, NewKeycode);
                    }
                }
            }

            if(KwmFocusMode == FocusModeAutofocus)
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&FocusedPSN, Event);
                pthread_mutex_unlock(&BackgroundLock);
                return NULL;
            }
        } break;
        case kCGEventMouseMoved:
        {
            if(KwmFocusMode != FocusModeDisabled)
                FocusWindowBelowCursor();
        } break;
        case kCGEventLeftMouseDown:
        {
            DEBUG("Left mouse button was pressed")
            if(IsCursorInsideFocusedWindow())
               IsWindowDragInProgress = true;
        } break;
        case kCGEventLeftMouseUp:
        {
            if(IsWindowDragInProgress)
            {
                if(!IsCursorInsideFocusedWindow())
                    ToggleFocusedWindowFloating();

                IsWindowDragInProgress = false;
            }

            DEBUG("Left mouse button was released")
        } break;
    }

    pthread_mutex_unlock(&BackgroundLock);
    return Event;
}

kwm_code LoadKwmCode()
{
    kwm_code Code = {};

    Code.HotkeySOFileTime = KwmGetFileTime(HotkeySOFullFilePath.c_str());
    Code.KwmHotkeySO = dlopen(HotkeySOFullFilePath.c_str(),  RTLD_LAZY);
    if(Code.KwmHotkeySO)
    {
        Code.KWMHotkeyCommands = (kwm_hotkey_commands*) dlsym(Code.KwmHotkeySO, "KWMHotkeyCommands");
        Code.SystemHotkeyCommands = (kwm_hotkey_commands*) dlsym(Code.KwmHotkeySO, "SystemHotkeyCommands");
        Code.CustomHotkeyCommands = (kwm_hotkey_commands*) dlsym(Code.KwmHotkeySO, "CustomHotkeyCommands");
        Code.RemapKeys = (kwm_key_remap*) dlsym(Code.KwmHotkeySO, "RemapKeys");
    }
    else
    {
        DEBUG("LoadKwmCode() Could not open '" << HotkeySOFullFilePath << "'")
    }

    Code.IsValid = (Code.KWMHotkeyCommands && Code.SystemHotkeyCommands && Code.CustomHotkeyCommands && Code.RemapKeys);
    return Code;
}

void UnloadKwmCode(kwm_code *Code)
{
    if(Code->KwmHotkeySO)
        dlclose(Code->KwmHotkeySO);

    Code->HotkeySOFileTime = "";
    Code->KWMHotkeyCommands = 0;
    Code->SystemHotkeyCommands = 0;
    Code->CustomHotkeyCommands = 0;
    Code->RemapKeys = 0;
    Code->IsValid = 0;
}

std::string KwmGetFileTime(const char *File)
{
    struct stat attr;
    return stat(File, &attr) ? ctime(&attr.st_mtime) : "file not found";
}

void KwmQuit()
{
    exit(0);
}

void * KwmWindowMonitor(void*)
{
    while(1)
    {
        pthread_mutex_lock(&BackgroundLock);
        if(KwmFocusMode != FocusModeDisabled)
            UpdateWindowTree();

        pthread_mutex_unlock(&BackgroundLock);
        usleep(200000);
    }
}

bool IsPrefixOfString(std::string &Line, std::string Prefix)
{
    bool Result = false;

    if(Line.substr(0, Prefix.size()) == Prefix)
    {
        Line = Line.substr(Prefix.size()+1);
        Result = true;
    }

    return Result;
}

void KwmExecuteConfig()
{
    char *HomeP = std::getenv("HOME");
    if(!HomeP)
    {
        DEBUG("Failed to get environment variable 'HOME'")
        return;
    }

    std::string ENV_HOME = HomeP;
    std::string KWM_CONFIG_FILE = ".kwmrc";

    std::ifstream ConfigFD(ENV_HOME + "/" + KWM_CONFIG_FILE);
    if(ConfigFD.fail())
    {
        DEBUG("Could not open " << ENV_HOME << "/" << KWM_CONFIG_FILE
              << ", make sure the file exists." << std::endl)
        return;
    }

    std::string Line;
    while(std::getline(ConfigFD, Line))
    {
        if(!Line.empty() && Line[0] != '#')
        {
            if(IsPrefixOfString(Line, "kwmc"))
                KwmInterpretCommand(Line, 0);
            else if(IsPrefixOfString(Line, "sys"))
                    system(Line.c_str());
        }
    }
}

void GetKwmFilePath()
{
    char PathBuf[PROC_PIDPATHINFO_MAXSIZE];
    pid_t Pid = getpid();
    int Ret = proc_pidpath(Pid, PathBuf, sizeof(PathBuf));
    if (Ret > 0)
        KwmFilePath = PathBuf;

    std::size_t Split = KwmFilePath.find_last_of("/\\");
    KwmFilePath = KwmFilePath.substr(0, Split);
    HotkeySOFullFilePath = KwmFilePath + "/hotkeys.so";
}

void KwmInit()
{
    if(!CheckPrivileges())
        Fatal("Could not access OSX Accessibility!");

    if (pthread_mutex_init(&BackgroundLock, NULL) != 0)
        Fatal("Could not create mutex!");

    if(KwmStartDaemon())
        pthread_create(&DaemonThread, NULL, &KwmDaemonHandleConnectionBG, NULL);
    else
        Fatal("Kwm: Could not start daemon..");

    KwmFocusMode = FocusModeAutoraise;
    KwmUseBuiltinHotkeys = true;

    GetKwmFilePath();
    KwmExecuteConfig();
    KWMCode = LoadKwmCode();
    GetActiveDisplays();

    pthread_create(&BackgroundThread, NULL, &KwmWindowMonitor, NULL);
}

bool CheckPrivileges()
{
    const void * Keys[] = { kAXTrustedCheckOptionPrompt };
    const void * Values[] = { kCFBooleanTrue };

    CFDictionaryRef Options;
    Options = CFDictionaryCreate(kCFAllocatorDefault,
            Keys, Values, sizeof(Keys) / sizeof(*Keys),
            &kCFCopyStringDictionaryKeyCallBacks,
            &kCFTypeDictionaryValueCallBacks);

    return AXIsProcessTrustedWithOptions(Options);
}

void Fatal(const std::string &Err)
{
    std::cout << Err << std::endl;
    exit(1);
}

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

    CGEventMask EventMask;
    CFRunLoopSourceRef RunLoopSource;

    EventMask = ((1 << kCGEventKeyDown) |
                 (1 << kCGEventMouseMoved) |
                 (1 << kCGEventLeftMouseDown) |
                 (1 << kCGEventLeftMouseUp));

    EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, EventMask, CGEventCallback, NULL);

    if(!EventTap || !CGEventTapIsEnabled(EventTap))
        Fatal("ERROR: Could not create event-tap!");

    RunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, EventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), RunLoopSource, kCFRunLoopCommonModes);
    CGEventTapEnable(EventTap, true);
    NSApplicationLoad();
    CFRunLoopRun();
    return 0;
}
<commit_msg>fixed issue with hot-loading hotkeys.so<commit_after>#include "kwm.h"

CFMachPortRef EventTap;

kwm_code KWMCode;
std::string KwmFilePath;
std::string HotkeySOFullFilePath;
bool KwmUseBuiltinHotkeys;

uint32_t MaxDisplayCount = 5;
uint32_t ActiveDisplaysCount;
CGDirectDisplayID ActiveDisplays[5];

screen_info *Screen;
int DefaultPaddingTop = 40, DefaultPaddingBottom = 20;
int DefaultPaddingLeft = 20, DefaultPaddingRight = 20;
int DefaultGapVertical = 10, DefaultGapHorizontal = 10;

std::map<unsigned int, screen_info> DisplayMap;
std::vector<window_info> WindowLst;
std::vector<int> FloatingSpaceLst;
std::vector<std::string> FloatingAppLst;
std::vector<int> FloatingWindowLst;

ProcessSerialNumber FocusedPSN;
window_info *FocusedWindow;
focus_option KwmFocusMode;
int KwmSplitMode = -1;
int MarkedWindowID = -1;
bool IsWindowDragInProgress = false;

pthread_t BackgroundThread;
pthread_t DaemonThread;

pthread_mutex_t BackgroundLock;

CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    pthread_mutex_lock(&BackgroundLock);

    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            DEBUG("Restarting Event Tap")
            CGEventTapEnable(EventTap, true);
        } break;
        case kCGEventKeyDown:
        {
            if(KwmUseBuiltinHotkeys)
            {
                CGEventFlags Flags = CGEventGetFlags(Event);
                bool CmdKey = (Flags & kCGEventFlagMaskCommand) == kCGEventFlagMaskCommand;
                bool AltKey = (Flags & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate;
                bool CtrlKey = (Flags & kCGEventFlagMaskControl) == kCGEventFlagMaskControl;
                bool ShiftKey = (Flags & kCGEventFlagMaskShift) == kCGEventFlagMaskShift;

                CGKeyCode Keycode = (CGKeyCode)CGEventGetIntegerValueField(Event, kCGKeyboardEventKeycode);

                std::string NewHotkeySOFileTime = KwmGetFileTime(HotkeySOFullFilePath.c_str());
                if(NewHotkeySOFileTime != "file not found" &&
                   NewHotkeySOFileTime != KWMCode.HotkeySOFileTime)
                {
                    DEBUG("Reloading hotkeys.so")
                    UnloadKwmCode(&KWMCode);
                    KWMCode = LoadKwmCode();
                }

                if(KWMCode.IsValid)
                {
                    // Hotkeys specific to Kwms functionality
                    if(KWMCode.KWMHotkeyCommands(CmdKey, CtrlKey, AltKey, ShiftKey, Keycode))
                    {
                        pthread_mutex_unlock(&BackgroundLock);
                        return NULL;
                    }

                    // Capture custom hotkeys specified by the user
                    if(KWMCode.CustomHotkeyCommands(CmdKey, CtrlKey, AltKey, ShiftKey, Keycode))
                    {
                        pthread_mutex_unlock(&BackgroundLock);
                        return NULL;
                    }

                    // Let system hotkeys pass through as normal
                    if(KWMCode.SystemHotkeyCommands(CmdKey, CtrlKey, AltKey, ShiftKey, Keycode))
                    {
                        pthread_mutex_unlock(&BackgroundLock);
                        return Event;
                    }

                    int NewKeycode;
                    KWMCode.RemapKeys(Event, &CmdKey, &CtrlKey, &AltKey, &ShiftKey, Keycode, &NewKeycode);
                    if(NewKeycode != -1)
                    {
                        CGEventSetFlags(Event, 0);

                        if(CmdKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskCommand);

                        if(AltKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskAlternate);

                        if(CtrlKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskControl);

                        if(ShiftKey)
                            CGEventSetFlags(Event, kCGEventFlagMaskShift);

                        CGEventSetIntegerValueField(Event, kCGKeyboardEventKeycode, NewKeycode);
                    }
                }
            }

            if(KwmFocusMode == FocusModeAutofocus)
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&FocusedPSN, Event);
                pthread_mutex_unlock(&BackgroundLock);
                return NULL;
            }
        } break;
        case kCGEventMouseMoved:
        {
            if(KwmFocusMode != FocusModeDisabled)
                FocusWindowBelowCursor();
        } break;
        case kCGEventLeftMouseDown:
        {
            DEBUG("Left mouse button was pressed")
            if(IsCursorInsideFocusedWindow())
               IsWindowDragInProgress = true;
        } break;
        case kCGEventLeftMouseUp:
        {
            if(IsWindowDragInProgress)
            {
                if(!IsCursorInsideFocusedWindow())
                    ToggleFocusedWindowFloating();

                IsWindowDragInProgress = false;
            }

            DEBUG("Left mouse button was released")
        } break;
    }

    pthread_mutex_unlock(&BackgroundLock);
    return Event;
}

kwm_code LoadKwmCode()
{
    kwm_code Code = {};

    Code.HotkeySOFileTime = KwmGetFileTime(HotkeySOFullFilePath.c_str());
    Code.KwmHotkeySO = dlopen(HotkeySOFullFilePath.c_str(),  RTLD_LAZY);
    if(Code.KwmHotkeySO)
    {
        Code.KWMHotkeyCommands = (kwm_hotkey_commands*) dlsym(Code.KwmHotkeySO, "KWMHotkeyCommands");
        Code.SystemHotkeyCommands = (kwm_hotkey_commands*) dlsym(Code.KwmHotkeySO, "SystemHotkeyCommands");
        Code.CustomHotkeyCommands = (kwm_hotkey_commands*) dlsym(Code.KwmHotkeySO, "CustomHotkeyCommands");
        Code.RemapKeys = (kwm_key_remap*) dlsym(Code.KwmHotkeySO, "RemapKeys");
    }
    else
    {
        DEBUG("LoadKwmCode() Could not open '" << HotkeySOFullFilePath << "'")
    }

    Code.IsValid = (Code.KWMHotkeyCommands && Code.SystemHotkeyCommands && Code.CustomHotkeyCommands && Code.RemapKeys);
    return Code;
}

void UnloadKwmCode(kwm_code *Code)
{
    if(Code->KwmHotkeySO)
        dlclose(Code->KwmHotkeySO);

    Code->HotkeySOFileTime = "";
    Code->KWMHotkeyCommands = 0;
    Code->SystemHotkeyCommands = 0;
    Code->CustomHotkeyCommands = 0;
    Code->RemapKeys = 0;
    Code->IsValid = 0;
}

std::string KwmGetFileTime(const char *File)
{
    struct stat attr;

    int Result = stat(File, &attr);
    if(Result == -1)
        return "file not found";

    return ctime(&attr.st_mtime);
}

void KwmQuit()
{
    exit(0);
}

void * KwmWindowMonitor(void*)
{
    while(1)
    {
        pthread_mutex_lock(&BackgroundLock);
        if(KwmFocusMode != FocusModeDisabled)
            UpdateWindowTree();

        pthread_mutex_unlock(&BackgroundLock);
        usleep(200000);
    }
}

bool IsPrefixOfString(std::string &Line, std::string Prefix)
{
    bool Result = false;

    if(Line.substr(0, Prefix.size()) == Prefix)
    {
        Line = Line.substr(Prefix.size()+1);
        Result = true;
    }

    return Result;
}

void KwmExecuteConfig()
{
    char *HomeP = std::getenv("HOME");
    if(!HomeP)
    {
        DEBUG("Failed to get environment variable 'HOME'")
        return;
    }

    std::string ENV_HOME = HomeP;
    std::string KWM_CONFIG_FILE = ".kwmrc";

    std::ifstream ConfigFD(ENV_HOME + "/" + KWM_CONFIG_FILE);
    if(ConfigFD.fail())
    {
        DEBUG("Could not open " << ENV_HOME << "/" << KWM_CONFIG_FILE
              << ", make sure the file exists." << std::endl)
        return;
    }

    std::string Line;
    while(std::getline(ConfigFD, Line))
    {
        if(!Line.empty() && Line[0] != '#')
        {
            if(IsPrefixOfString(Line, "kwmc"))
                KwmInterpretCommand(Line, 0);
            else if(IsPrefixOfString(Line, "sys"))
                    system(Line.c_str());
        }
    }
}

void GetKwmFilePath()
{
    char PathBuf[PROC_PIDPATHINFO_MAXSIZE];
    pid_t Pid = getpid();
    int Ret = proc_pidpath(Pid, PathBuf, sizeof(PathBuf));
    if (Ret > 0)
        KwmFilePath = PathBuf;

    std::size_t Split = KwmFilePath.find_last_of("/\\");
    KwmFilePath = KwmFilePath.substr(0, Split);
    HotkeySOFullFilePath = KwmFilePath + "/hotkeys.so";
}

void KwmInit()
{
    if(!CheckPrivileges())
        Fatal("Could not access OSX Accessibility!");

    if (pthread_mutex_init(&BackgroundLock, NULL) != 0)
        Fatal("Could not create mutex!");

    if(KwmStartDaemon())
        pthread_create(&DaemonThread, NULL, &KwmDaemonHandleConnectionBG, NULL);
    else
        Fatal("Kwm: Could not start daemon..");

    KwmFocusMode = FocusModeAutoraise;
    KwmUseBuiltinHotkeys = true;

    GetKwmFilePath();
    KwmExecuteConfig();
    KWMCode = LoadKwmCode();
    GetActiveDisplays();

    pthread_create(&BackgroundThread, NULL, &KwmWindowMonitor, NULL);
}

bool CheckPrivileges()
{
    const void * Keys[] = { kAXTrustedCheckOptionPrompt };
    const void * Values[] = { kCFBooleanTrue };

    CFDictionaryRef Options;
    Options = CFDictionaryCreate(kCFAllocatorDefault,
            Keys, Values, sizeof(Keys) / sizeof(*Keys),
            &kCFCopyStringDictionaryKeyCallBacks,
            &kCFTypeDictionaryValueCallBacks);

    return AXIsProcessTrustedWithOptions(Options);
}

void Fatal(const std::string &Err)
{
    std::cout << Err << std::endl;
    exit(1);
}

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

    CGEventMask EventMask;
    CFRunLoopSourceRef RunLoopSource;

    EventMask = ((1 << kCGEventKeyDown) |
                 (1 << kCGEventMouseMoved) |
                 (1 << kCGEventLeftMouseDown) |
                 (1 << kCGEventLeftMouseUp));

    EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, EventMask, CGEventCallback, NULL);

    if(!EventTap || !CGEventTapIsEnabled(EventTap))
        Fatal("ERROR: Could not create event-tap!");

    RunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, EventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), RunLoopSource, kCFRunLoopCommonModes);
    CGEventTapEnable(EventTap, true);
    NSApplicationLoad();
    CFRunLoopRun();
    return 0;
}
<|endoftext|>


<commit_before>#include <mp/wavy.h>
#include <mp/functional.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>

using namespace mp::placeholders;

bool signal_handler(int signo, int* count, mp::wavy::loop* lo)
{
	std::cout << "signal" << std::endl;

	if(++(*count) >= 3) {
		lo->end();
		return false;
	}

	return true;
}

int main(void)
{
	signal(SIGUSR1, SIG_IGN);

	mp::wavy::loop lo;

	int count = 0;
	lo.add_signal(SIGUSR1, mp::bind(
				&signal_handler, _1, &count, &lo));

	lo.start(3);

	pid_t pid = getpid();

	usleep(50*1e3);
	kill(pid, SIGUSR1);
	usleep(50*1e3);
	kill(pid, SIGUSR1);
	usleep(50*1e3);
	kill(pid, SIGUSR1);

	lo.join();
}

<commit_msg>fixes test/signal<commit_after>#include <mp/wavy.h>
#include <mp/functional.h>
#include <mp/signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>

using namespace mp::placeholders;

bool signal_handler(int signo, int* count, mp::wavy::loop* lo)
{
	std::cout << "signal" << std::endl;

	if(++(*count) >= 3) {
		lo->end();
		return false;
	}

	return true;
}

int main(void)
{
	signal(SIGUSR1, SIG_IGN);     // kqueue compatibility
	mp::scoped_sigprocmask mask(  // epoll compatibility
			mp::sigset().add(SIGUSR1));

	mp::wavy::loop lo;

	int count = 0;
	lo.add_signal(SIGUSR1, mp::bind(
				&signal_handler, _1, &count, &lo));

	lo.start(3);

	pid_t pid = getpid();

	usleep(50*1e3);
	kill(pid, SIGUSR1);
	usleep(50*1e3);
	kill(pid, SIGUSR1);
	usleep(50*1e3);
	kill(pid, SIGUSR1);

	lo.join();
}

<|endoftext|>


<commit_before>#include "kwm.h"
#include "helpers.h"
#include "daemon.h"
#include "display.h"
#include "space.h"
#include "window.h"
#include "keys.h"
#include "interpreter.h"
#include "border.h"

const std::string KwmCurrentVersion = "Kwm Version 1.1.2";

kwm_mach KWMMach = {};
kwm_path KWMPath = {};
kwm_screen KWMScreen = {};
kwm_toggles KWMToggles = {};
kwm_focus KWMFocus = {};
kwm_mode KWMMode = {};
kwm_tiling KWMTiling = {};
kwm_cache KWMCache = {};
kwm_thread KWMThread = {};
kwm_hotkeys KWMHotkeys = {};
kwm_border FocusedBorder = {};
kwm_border MarkedBorder = {};
kwm_border PrefixBorder = {};
kwm_callback KWMCallback =  {};

CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    pthread_mutex_lock(&KWMThread.Lock);

    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            DEBUG("Restarting Event Tap")
            CGEventTapEnable(KWMMach.EventTap, true);
        } break;
        case kCGEventKeyDown:
        {
            if(KWMToggles.UseBuiltinHotkeys && KwmMainHotkeyTrigger(&Event))
            {
                    pthread_mutex_unlock(&KWMThread.Lock);
                    return NULL;
            }

            if(KWMMode.Focus == FocusModeAutofocus &&
               !IsActiveSpaceFloating())
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&KWMFocus.PSN, Event);
                pthread_mutex_unlock(&KWMThread.Lock);
                return NULL;
            }
        } break;
        case kCGEventKeyUp:
        {
            if(KWMMode.Focus == FocusModeAutofocus &&
               !IsActiveSpaceFloating())
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&KWMFocus.PSN, Event);
                pthread_mutex_unlock(&KWMThread.Lock);
                return NULL;
            }
        } break;
        case kCGEventMouseMoved:
        {
            UpdateActiveScreen();

            if(KWMMode.Focus != FocusModeDisabled &&
               KWMMode.Focus != FocusModeStandby &&
               !IsActiveSpaceFloating())
                FocusWindowBelowCursor();
        } break;
        case kCGEventLeftMouseDown:
        {
            DEBUG("Left mouse button was pressed")
            if(!IsActiveSpaceFloating())
            {
                FocusWindowBelowCursor();
                if(KWMToggles.EnableDragAndDrop)
                    KWMToggles.DragInProgress = true;
            }
        } break;
        case kCGEventLeftMouseUp:
        {
            DEBUG("Left mouse button was released")
            if(!IsActiveSpaceFloating())
            {
                if(KWMToggles.EnableDragAndDrop && KWMToggles.DragInProgress)
                    KWMToggles.DragInProgress = false;

                if(KWMFocus.Window && FocusedBorder.Enabled)
                {
                    if(IsWindowFloating(KWMFocus.Window->WID, NULL))
                        UpdateBorder("focused");
                }
            }
        } break;
    }

    pthread_mutex_unlock(&KWMThread.Lock);
    return Event;
}

void KwmQuit()
{
    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);
    CloseBorder(&PrefixBorder);

    exit(0);
}

void * KwmWindowMonitor(void*)
{
    while(1)
    {
        pthread_mutex_lock(&KWMThread.Lock);
        CheckPrefixTimeout();

        if(!IsSpaceTransitionInProgress() &&
           IsActiveSpaceManaged())
            UpdateWindowTree();

        pthread_mutex_unlock(&KWMThread.Lock);
        usleep(100000);
    }
}

void KwmReloadConfig()
{
    KwmClearSettings();
    KwmExecuteConfig();
}

void KwmClearSettings()
{
    std::map<std::string, std::vector<CFTypeRef> >::iterator It;
    for(It = KWMTiling.AllowedWindowRoles.begin(); It != KWMTiling.AllowedWindowRoles.end(); ++It)
    {
        std::vector<CFTypeRef> &WindowRoles = It->second;
        for(std::size_t RoleIndex = 0; RoleIndex < WindowRoles.size(); ++RoleIndex)
            CFRelease(WindowRoles[RoleIndex]);

        WindowRoles.clear();
    }

    KWMTiling.FloatingAppLst.clear();
    KWMHotkeys.List.clear();
    KWMHotkeys.Prefix.Enabled = false;
}

void KwmExecuteConfig()
{
    char *HomeP = std::getenv("HOME");
    if(!HomeP)
    {
        DEBUG("Failed to get environment variable 'HOME'")
        return;
    }

    KWMPath.EnvHome = HomeP;
    KWMPath.ConfigFile = "kwmrc";
    KWMPath.ConfigFolder = ".kwm";
    KwmExecuteFile(KWMPath.ConfigFile);
}

void KwmExecuteInitScript()
{
    std::string InitFile = KWMPath.EnvHome + "/" + KWMPath.ConfigFolder + "/init";

    struct stat Buffer;
    if(stat(InitFile.c_str(), &Buffer) == 0)
        KwmExecuteThreadedSystemCommand(InitFile);
}

void KwmExecuteFile(std::string File)
{
    std::ifstream FileHandle(KWMPath.EnvHome + "/" + KWMPath.ConfigFolder + "/" + File);
    if(FileHandle.fail())
    {
        DEBUG("Could not open " << KWMPath.EnvHome << "/" << KWMPath.ConfigFolder << "/" << File
              << ", make sure the file exists." << std::endl)
        return;
    }

    std::string Line;
    while(std::getline(FileHandle, Line))
    {
        if(!Line.empty() && Line[0] != '#')
        {
            if(IsPrefixOfString(Line, "kwmc"))
                KwmInterpretCommand(Line, 0);
            else if(IsPrefixOfString(Line, "sys"))
                KwmExecuteThreadedSystemCommand(Line);
            else if(IsPrefixOfString(Line, "include"))
                KwmExecuteFile(Line);
        }
    }

    FileHandle.close();
}

void KwmExecuteSystemCommand(std::string Command)
{
    system(Command.c_str());
}

void KwmExecuteThreadedSystemCommand(std::string Command)
{
    std::string *HCommand = new std::string(Command);
    pthread_create(&KWMThread.SystemCommand, NULL, &KwmStartThreadedSystemCommand, HCommand);
}

void * KwmStartThreadedSystemCommand(void *Args)
{
    std::string Command = *((std::string*)Args);
    KwmExecuteSystemCommand(Command);
    delete (std::string*)Args;
    return NULL;
}

bool GetKwmFilePath()
{
    bool Result = false;
    char PathBuf[PROC_PIDPATHINFO_MAXSIZE];
    pid_t Pid = getpid();
    int Ret = proc_pidpath(Pid, PathBuf, sizeof(PathBuf));
    if (Ret > 0)
    {
        KWMPath.FilePath = PathBuf;

        std::size_t Split = KWMPath.FilePath.find_last_of("/\\");
        KWMPath.FilePath = KWMPath.FilePath.substr(0, Split);
        KWMPath.HotkeySOFullPath = KWMPath.FilePath + "/hotkeys.so";
        Result = true;
    }

    return Result;
}

void KwmInit()
{
    if(!CheckPrivileges())
        Fatal("Could not access OSX Accessibility!");

    if (pthread_mutex_init(&KWMThread.Lock, NULL) != 0)
        Fatal("Could not create mutex!");

    if(KwmStartDaemon())
        pthread_create(&KWMThread.Daemon, NULL, &KwmDaemonHandleConnectionBG, NULL);
    else
        Fatal("Kwm: Could not start daemon..");

    signal(SIGSEGV, SignalHandler);

    KWMScreen.SplitRatio = 0.5;
    KWMScreen.SplitMode = -1;
    KWMScreen.MarkedWindow = -1;
    KWMScreen.PrevSpace = -1;
    KWMScreen.DefaultOffset = CreateDefaultScreenOffset();
    KWMScreen.MaxCount = 5;
    KWMScreen.ActiveCount = 0;

    KWMToggles.EnableTilingMode = true;
    KWMToggles.UseBuiltinHotkeys = true;
    KWMToggles.EnableDragAndDrop = true;
    KWMToggles.UseMouseFollowsFocus = true;

    KWMMode.Space = SpaceModeBSP;
    KWMMode.Focus = FocusModeAutoraise;
    KWMMode.Cycle = CycleModeScreen;

    KWMHotkeys.Prefix.Enabled = false;
    KWMHotkeys.Prefix.Global = false;
    KWMHotkeys.Prefix.Active = false;
    KWMHotkeys.Prefix.Timeout = 0.75;

    FocusedBorder.Radius = -1;
    MarkedBorder.Radius = -1;
    PrefixBorder.Radius = -1;

    GetKwmFilePath();
    KwmExecuteConfig();
    GetActiveDisplays();
    KwmExecuteInitScript();

    pthread_create(&KWMThread.WindowMonitor, NULL, &KwmWindowMonitor, NULL);
}

bool CheckPrivileges()
{
    bool Result = false;
    const void * Keys[] = { kAXTrustedCheckOptionPrompt };
    const void * Values[] = { kCFBooleanTrue };

    CFDictionaryRef Options;
    Options = CFDictionaryCreate(kCFAllocatorDefault,
            Keys, Values, sizeof(Keys) / sizeof(*Keys),
            &kCFCopyStringDictionaryKeyCallBacks,
            &kCFTypeDictionaryValueCallBacks);

    Result = AXIsProcessTrustedWithOptions(Options);
    CFRelease(Options);

    return Result;
}

bool CheckArguments(int argc, char **argv)
{
    bool Result = false;

    if(argc == 2)
    {
        std::string Arg = argv[1];
        if(Arg == "--version")
        {
            std::cout << KwmCurrentVersion << std::endl;
            Result = true;
        }
    }

    return Result;
}

void SignalHandler(int Signum)
{
    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);
    CloseBorder(&PrefixBorder);

    signal(Signum, SIG_DFL);
    kill(getpid(), Signum);
}

void Fatal(const std::string &Err)
{
    std::cout << Err << std::endl;
    exit(1);
}

int main(int argc, char **argv)
{
    if(CheckArguments(argc, argv))
        return 0;

    KwmInit();
    KWMMach.EventMask = ((1 << kCGEventKeyDown) |
                         (1 << kCGEventKeyUp) |
                         (1 << kCGEventMouseMoved) |
                         (1 << kCGEventLeftMouseDown) |
                         (1 << kCGEventLeftMouseUp));

    KWMMach.EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, KWMMach.EventMask, CGEventCallback, NULL);
    if(!KWMMach.EventTap || !CGEventTapIsEnabled(KWMMach.EventTap))
        Fatal("ERROR: Could not create event-tap!");

    CFRunLoopAddSource(CFRunLoopGetCurrent(),
                       CFMachPortCreateRunLoopSource(kCFAllocatorDefault, KWMMach.EventTap, 0),
                       kCFRunLoopCommonModes);

    CGEventTapEnable(KWMMach.EventTap, true);
    CreateWorkspaceWatcher(KWMMach.WorkspaceWatcher);

    NSApplicationLoad();
    CFRunLoopRun();
    return 0;
}
<commit_msg>catch signals<commit_after>#include "kwm.h"
#include "helpers.h"
#include "daemon.h"
#include "display.h"
#include "space.h"
#include "window.h"
#include "keys.h"
#include "interpreter.h"
#include "border.h"

const std::string KwmCurrentVersion = "Kwm Version 1.1.2";

kwm_mach KWMMach = {};
kwm_path KWMPath = {};
kwm_screen KWMScreen = {};
kwm_toggles KWMToggles = {};
kwm_focus KWMFocus = {};
kwm_mode KWMMode = {};
kwm_tiling KWMTiling = {};
kwm_cache KWMCache = {};
kwm_thread KWMThread = {};
kwm_hotkeys KWMHotkeys = {};
kwm_border FocusedBorder = {};
kwm_border MarkedBorder = {};
kwm_border PrefixBorder = {};
kwm_callback KWMCallback =  {};

CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    pthread_mutex_lock(&KWMThread.Lock);

    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            DEBUG("Restarting Event Tap")
            CGEventTapEnable(KWMMach.EventTap, true);
        } break;
        case kCGEventKeyDown:
        {
            if(KWMToggles.UseBuiltinHotkeys && KwmMainHotkeyTrigger(&Event))
            {
                    pthread_mutex_unlock(&KWMThread.Lock);
                    return NULL;
            }

            if(KWMMode.Focus == FocusModeAutofocus &&
               !IsActiveSpaceFloating())
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&KWMFocus.PSN, Event);
                pthread_mutex_unlock(&KWMThread.Lock);
                return NULL;
            }
        } break;
        case kCGEventKeyUp:
        {
            if(KWMMode.Focus == FocusModeAutofocus &&
               !IsActiveSpaceFloating())
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&KWMFocus.PSN, Event);
                pthread_mutex_unlock(&KWMThread.Lock);
                return NULL;
            }
        } break;
        case kCGEventMouseMoved:
        {
            UpdateActiveScreen();

            if(KWMMode.Focus != FocusModeDisabled &&
               KWMMode.Focus != FocusModeStandby &&
               !IsActiveSpaceFloating())
                FocusWindowBelowCursor();
        } break;
        case kCGEventLeftMouseDown:
        {
            DEBUG("Left mouse button was pressed")
            if(!IsActiveSpaceFloating())
            {
                FocusWindowBelowCursor();
                if(KWMToggles.EnableDragAndDrop)
                    KWMToggles.DragInProgress = true;
            }
        } break;
        case kCGEventLeftMouseUp:
        {
            DEBUG("Left mouse button was released")
            if(!IsActiveSpaceFloating())
            {
                if(KWMToggles.EnableDragAndDrop && KWMToggles.DragInProgress)
                    KWMToggles.DragInProgress = false;

                if(KWMFocus.Window && FocusedBorder.Enabled)
                {
                    if(IsWindowFloating(KWMFocus.Window->WID, NULL))
                        UpdateBorder("focused");
                }
            }
        } break;
    }

    pthread_mutex_unlock(&KWMThread.Lock);
    return Event;
}

void KwmQuit()
{
    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);
    CloseBorder(&PrefixBorder);

    exit(0);
}

void * KwmWindowMonitor(void*)
{
    while(1)
    {
        pthread_mutex_lock(&KWMThread.Lock);
        CheckPrefixTimeout();

        if(!IsSpaceTransitionInProgress() &&
           IsActiveSpaceManaged())
            UpdateWindowTree();

        pthread_mutex_unlock(&KWMThread.Lock);
        usleep(100000);
    }
}

void KwmReloadConfig()
{
    KwmClearSettings();
    KwmExecuteConfig();
}

void KwmClearSettings()
{
    std::map<std::string, std::vector<CFTypeRef> >::iterator It;
    for(It = KWMTiling.AllowedWindowRoles.begin(); It != KWMTiling.AllowedWindowRoles.end(); ++It)
    {
        std::vector<CFTypeRef> &WindowRoles = It->second;
        for(std::size_t RoleIndex = 0; RoleIndex < WindowRoles.size(); ++RoleIndex)
            CFRelease(WindowRoles[RoleIndex]);

        WindowRoles.clear();
    }

    KWMTiling.FloatingAppLst.clear();
    KWMHotkeys.List.clear();
    KWMHotkeys.Prefix.Enabled = false;
}

void KwmExecuteConfig()
{
    char *HomeP = std::getenv("HOME");
    if(!HomeP)
    {
        DEBUG("Failed to get environment variable 'HOME'")
        return;
    }

    KWMPath.EnvHome = HomeP;
    KWMPath.ConfigFile = "kwmrc";
    KWMPath.ConfigFolder = ".kwm";
    KwmExecuteFile(KWMPath.ConfigFile);
}

void KwmExecuteInitScript()
{
    std::string InitFile = KWMPath.EnvHome + "/" + KWMPath.ConfigFolder + "/init";

    struct stat Buffer;
    if(stat(InitFile.c_str(), &Buffer) == 0)
        KwmExecuteThreadedSystemCommand(InitFile);
}

void KwmExecuteFile(std::string File)
{
    std::ifstream FileHandle(KWMPath.EnvHome + "/" + KWMPath.ConfigFolder + "/" + File);
    if(FileHandle.fail())
    {
        DEBUG("Could not open " << KWMPath.EnvHome << "/" << KWMPath.ConfigFolder << "/" << File
              << ", make sure the file exists." << std::endl)
        return;
    }

    std::string Line;
    while(std::getline(FileHandle, Line))
    {
        if(!Line.empty() && Line[0] != '#')
        {
            if(IsPrefixOfString(Line, "kwmc"))
                KwmInterpretCommand(Line, 0);
            else if(IsPrefixOfString(Line, "sys"))
                KwmExecuteThreadedSystemCommand(Line);
            else if(IsPrefixOfString(Line, "include"))
                KwmExecuteFile(Line);
        }
    }

    FileHandle.close();
}

void KwmExecuteSystemCommand(std::string Command)
{
    system(Command.c_str());
}

void KwmExecuteThreadedSystemCommand(std::string Command)
{
    std::string *HCommand = new std::string(Command);
    pthread_create(&KWMThread.SystemCommand, NULL, &KwmStartThreadedSystemCommand, HCommand);
}

void * KwmStartThreadedSystemCommand(void *Args)
{
    std::string Command = *((std::string*)Args);
    KwmExecuteSystemCommand(Command);
    delete (std::string*)Args;
    return NULL;
}

bool GetKwmFilePath()
{
    bool Result = false;
    char PathBuf[PROC_PIDPATHINFO_MAXSIZE];
    pid_t Pid = getpid();
    int Ret = proc_pidpath(Pid, PathBuf, sizeof(PathBuf));
    if (Ret > 0)
    {
        KWMPath.FilePath = PathBuf;

        std::size_t Split = KWMPath.FilePath.find_last_of("/\\");
        KWMPath.FilePath = KWMPath.FilePath.substr(0, Split);
        KWMPath.HotkeySOFullPath = KWMPath.FilePath + "/hotkeys.so";
        Result = true;
    }

    return Result;
}

void KwmInit()
{
    if(!CheckPrivileges())
        Fatal("Could not access OSX Accessibility!");

    if (pthread_mutex_init(&KWMThread.Lock, NULL) != 0)
        Fatal("Could not create mutex!");

    if(KwmStartDaemon())
        pthread_create(&KWMThread.Daemon, NULL, &KwmDaemonHandleConnectionBG, NULL);
    else
        Fatal("Kwm: Could not start daemon..");

    signal(SIGSEGV, SignalHandler);
    signal(SIGABRT, SignalHandler);
    signal(SIGTRAP, SignalHandler);

    KWMScreen.SplitRatio = 0.5;
    KWMScreen.SplitMode = -1;
    KWMScreen.MarkedWindow = -1;
    KWMScreen.PrevSpace = -1;
    KWMScreen.DefaultOffset = CreateDefaultScreenOffset();
    KWMScreen.MaxCount = 5;
    KWMScreen.ActiveCount = 0;

    KWMToggles.EnableTilingMode = true;
    KWMToggles.UseBuiltinHotkeys = true;
    KWMToggles.EnableDragAndDrop = true;
    KWMToggles.UseMouseFollowsFocus = true;

    KWMMode.Space = SpaceModeBSP;
    KWMMode.Focus = FocusModeAutoraise;
    KWMMode.Cycle = CycleModeScreen;

    KWMHotkeys.Prefix.Enabled = false;
    KWMHotkeys.Prefix.Global = false;
    KWMHotkeys.Prefix.Active = false;
    KWMHotkeys.Prefix.Timeout = 0.75;

    FocusedBorder.Radius = -1;
    MarkedBorder.Radius = -1;
    PrefixBorder.Radius = -1;

    GetKwmFilePath();
    KwmExecuteConfig();
    GetActiveDisplays();
    KwmExecuteInitScript();

    pthread_create(&KWMThread.WindowMonitor, NULL, &KwmWindowMonitor, NULL);
}

bool CheckPrivileges()
{
    bool Result = false;
    const void * Keys[] = { kAXTrustedCheckOptionPrompt };
    const void * Values[] = { kCFBooleanTrue };

    CFDictionaryRef Options;
    Options = CFDictionaryCreate(kCFAllocatorDefault,
            Keys, Values, sizeof(Keys) / sizeof(*Keys),
            &kCFCopyStringDictionaryKeyCallBacks,
            &kCFTypeDictionaryValueCallBacks);

    Result = AXIsProcessTrustedWithOptions(Options);
    CFRelease(Options);

    return Result;
}

bool CheckArguments(int argc, char **argv)
{
    bool Result = false;

    if(argc == 2)
    {
        std::string Arg = argv[1];
        if(Arg == "--version")
        {
            std::cout << KwmCurrentVersion << std::endl;
            Result = true;
        }
    }

    return Result;
}

void SignalHandler(int Signum)
{
    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);
    CloseBorder(&PrefixBorder);

    signal(Signum, SIG_DFL);
    kill(getpid(), Signum);
}

void Fatal(const std::string &Err)
{
    std::cout << Err << std::endl;
    exit(1);
}

int main(int argc, char **argv)
{
    if(CheckArguments(argc, argv))
        return 0;

    KwmInit();
    KWMMach.EventMask = ((1 << kCGEventKeyDown) |
                         (1 << kCGEventKeyUp) |
                         (1 << kCGEventMouseMoved) |
                         (1 << kCGEventLeftMouseDown) |
                         (1 << kCGEventLeftMouseUp));

    KWMMach.EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, KWMMach.EventMask, CGEventCallback, NULL);
    if(!KWMMach.EventTap || !CGEventTapIsEnabled(KWMMach.EventTap))
        Fatal("ERROR: Could not create event-tap!");

    CFRunLoopAddSource(CFRunLoopGetCurrent(),
                       CFMachPortCreateRunLoopSource(kCFAllocatorDefault, KWMMach.EventTap, 0),
                       kCFRunLoopCommonModes);

    CGEventTapEnable(KWMMach.EventTap, true);
    CreateWorkspaceWatcher(KWMMach.WorkspaceWatcher);

    NSApplicationLoad();
    CFRunLoopRun();
    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <string>
#include "database/Database.h"
#include "EmuEEPROM/src/EmuEEPROM.h"
#include "board/Internal.h"

namespace
{
    class EmuEEPROMStorage : public EmuEEPROM::StorageAccess
    {
        public:
        EmuEEPROMStorage() = default;

        ~EmuEEPROMStorage()
        {
            std::fstream file;

            file.open(_filename.c_str(), std::ios::trunc | std::ios::in | std::ios::out | std::ios::binary);
            file.unsetf(std::ios::skipws);

            if (file.is_open())
            {
                file.write(reinterpret_cast<char*>(&_flashVector[0]), _flashVector.size() * sizeof(uint8_t));
                file.close();
            }

            _filename += "_offset";

            //also create a file containing the offset at which to write generated flash
            file.open(_filename.c_str(), std::ios::trunc | std::ios::out);

            if (file.is_open())
            {
                file << Board::detail::map::flashPageDescriptor(Board::detail::map::eepromFlashPageFactory()).address;
                file.close();
            }
        }

        bool init() override
        {
            _flashVector.resize(pageSize(), 0xFF);
            return true;
        }

        uint32_t startAddress(EmuEEPROM::page_t page) override
        {
            return 0;
        }

        bool erasePage(EmuEEPROM::page_t page) override
        {
            return true;
        }

        bool write16(uint32_t address, uint16_t data) override
        {
            _flashVector.at(address + 0) = data >> 0 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 1) = data >> 8 & static_cast<uint16_t>(0xFF);

            return true;
        }

        bool write32(uint32_t address, uint32_t data) override
        {
            _flashVector.at(address + 0) = data >> 0 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 1) = data >> 8 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 2) = data >> 16 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 3) = data >> 24 & static_cast<uint16_t>(0xFF);

            return true;
        }

        bool read16(uint32_t address, uint16_t& data) override
        {
            if (address >= _flashVector.size())
            {
                data = 0xFFFF;
            }
            else
            {
                data = _flashVector.at(address + 1);
                data <<= 8;
                data |= _flashVector.at(address + 0);
            }

            return true;
        }

        bool read32(uint32_t address, uint32_t& data) override
        {
            if (address >= _flashVector.size())
            {
                data = 0xFFFF;
            }
            else
            {
                data = _flashVector.at(address + 3);
                data <<= 8;
                data |= _flashVector.at(address + 2);
                data <<= 8;
                data |= _flashVector.at(address + 1);
                data <<= 8;
                data |= _flashVector.at(address + 0);
            }

            return true;
        }

        uint32_t pageSize() override
        {
            return Board::detail::map::flashPageDescriptor(Board::detail::map::eepromFlashPage1()).size;
        }

        void setFilename(const char* filename)
        {
            _filename = filename;
        }

        private:
        std::vector<uint8_t> _flashVector;
        std::string          _filename;

    } emuEEPROMstorage;

    EmuEEPROM emuEEPROM(emuEEPROMstorage, false);

    class DBhandlers : public Database::Handlers
    {
        public:
        DBhandlers() = default;

        void presetChange(uint8_t preset) override
        {
        }

        void factoryResetStart() override
        {
        }

        void factoryResetDone() override
        {
        }

        void initialized() override
        {
        }
    } dbHandlers;

    class StorageAccess : public LESSDB::StorageAccess
    {
        public:
        StorageAccess() = default;

        bool init() override
        {
            return emuEEPROM.init();
        }

        uint32_t size() override
        {
            return emuEEPROMstorage.pageSize();
        }

        bool clear() override
        {
            return emuEEPROM.format();
        }

        bool read(uint32_t address, int32_t& value, LESSDB::sectionParameterType_t type) override
        {
            switch (type)
            {
            case LESSDB::sectionParameterType_t::word:
            case LESSDB::sectionParameterType_t::byte:
            {
                uint16_t tempData;

                auto readStatus = emuEEPROM.read(address, tempData);

                if (readStatus == EmuEEPROM::readStatus_t::ok)
                {
                    value = tempData;
                }
                else if (readStatus == EmuEEPROM::readStatus_t::noVar)
                {
                    //variable with this address doesn't exist yet - set value to 0
                    value = 0;
                }
                else
                {
                    return false;
                }

                return true;
            }
            break;

            default:
                return false;
            }
        }

        bool write(uint32_t address, int32_t value, LESSDB::sectionParameterType_t type) override
        {
            switch (type)
            {
            case LESSDB::sectionParameterType_t::word:
            case LESSDB::sectionParameterType_t::byte:
            {
                uint16_t tempData = value;

                return emuEEPROM.write(address, tempData) == EmuEEPROM::writeStatus_t::ok;
            }
            break;

            default:
                return false;
            }
        }

        size_t paramUsage(LESSDB::sectionParameterType_t type) override
        {
            switch (type)
            {
            case LESSDB::sectionParameterType_t::dword:
                return 8;

            default:
                return 4;    //2 bytes for address, 2 bytes for data
            }
        }
    } storageAccess;

    Database database(dbHandlers, storageAccess, true);
}    // namespace

int main(int argc, char* argv[])
{
    if (argc <= 1)
    {
        std::cout << argv[0] << "ERROR: Filename for generated flash not provided" << std::endl;
        return -1;
    }
    else
    {
        emuEEPROMstorage.setFilename(argv[1]);
    }

    return !database.init();
}<commit_msg>flashgen: handle halfbyte and bit parameter types<commit_after>#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <string>
#include "database/Database.h"
#include "EmuEEPROM/src/EmuEEPROM.h"
#include "board/Internal.h"

namespace
{
    class EmuEEPROMStorage : public EmuEEPROM::StorageAccess
    {
        public:
        EmuEEPROMStorage() = default;

        ~EmuEEPROMStorage()
        {
            std::fstream file;

            file.open(_filename.c_str(), std::ios::trunc | std::ios::in | std::ios::out | std::ios::binary);
            file.unsetf(std::ios::skipws);

            if (file.is_open())
            {
                file.write(reinterpret_cast<char*>(&_flashVector[0]), _flashVector.size() * sizeof(uint8_t));
                file.close();
            }

            _filename += "_offset";

            //also create a file containing the offset at which to write generated flash
            file.open(_filename.c_str(), std::ios::trunc | std::ios::out);

            if (file.is_open())
            {
                file << Board::detail::map::flashPageDescriptor(Board::detail::map::eepromFlashPageFactory()).address;
                file.close();
            }
        }

        bool init() override
        {
            _flashVector.resize(pageSize(), 0xFF);
            return true;
        }

        uint32_t startAddress(EmuEEPROM::page_t page) override
        {
            return 0;
        }

        bool erasePage(EmuEEPROM::page_t page) override
        {
            return true;
        }

        bool write16(uint32_t address, uint16_t data) override
        {
            _flashVector.at(address + 0) = data >> 0 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 1) = data >> 8 & static_cast<uint16_t>(0xFF);

            return true;
        }

        bool write32(uint32_t address, uint32_t data) override
        {
            _flashVector.at(address + 0) = data >> 0 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 1) = data >> 8 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 2) = data >> 16 & static_cast<uint16_t>(0xFF);
            _flashVector.at(address + 3) = data >> 24 & static_cast<uint16_t>(0xFF);

            return true;
        }

        bool read16(uint32_t address, uint16_t& data) override
        {
            if (address >= _flashVector.size())
            {
                data = 0xFFFF;
            }
            else
            {
                data = _flashVector.at(address + 1);
                data <<= 8;
                data |= _flashVector.at(address + 0);
            }

            return true;
        }

        bool read32(uint32_t address, uint32_t& data) override
        {
            if (address >= _flashVector.size())
            {
                data = 0xFFFF;
            }
            else
            {
                data = _flashVector.at(address + 3);
                data <<= 8;
                data |= _flashVector.at(address + 2);
                data <<= 8;
                data |= _flashVector.at(address + 1);
                data <<= 8;
                data |= _flashVector.at(address + 0);
            }

            return true;
        }

        uint32_t pageSize() override
        {
            return Board::detail::map::flashPageDescriptor(Board::detail::map::eepromFlashPage1()).size;
        }

        void setFilename(const char* filename)
        {
            _filename = filename;
        }

        private:
        std::vector<uint8_t> _flashVector;
        std::string          _filename;

    } emuEEPROMstorage;

    EmuEEPROM emuEEPROM(emuEEPROMstorage, false);

    class DBhandlers : public Database::Handlers
    {
        public:
        DBhandlers() = default;

        void presetChange(uint8_t preset) override
        {
        }

        void factoryResetStart() override
        {
        }

        void factoryResetDone() override
        {
        }

        void initialized() override
        {
        }
    } dbHandlers;

    class StorageAccess : public LESSDB::StorageAccess
    {
        public:
        StorageAccess() = default;

        bool init() override
        {
            return emuEEPROM.init();
        }

        uint32_t size() override
        {
            return emuEEPROMstorage.pageSize();
        }

        bool clear() override
        {
            return emuEEPROM.format();
        }

        bool read(uint32_t address, int32_t& value, LESSDB::sectionParameterType_t type) override
        {
            switch (type)
            {
            case LESSDB::sectionParameterType_t::word:
            case LESSDB::sectionParameterType_t::byte:
            case LESSDB::sectionParameterType_t::halfByte:
            case LESSDB::sectionParameterType_t::bit:
            {
                uint16_t tempData;

                auto readStatus = emuEEPROM.read(address, tempData);

                if (readStatus == EmuEEPROM::readStatus_t::ok)
                {
                    value = tempData;
                }
                else if (readStatus == EmuEEPROM::readStatus_t::noVar)
                {
                    //variable with this address doesn't exist yet - set value to 0
                    value = 0;
                }
                else
                {
                    return false;
                }

                return true;
            }
            break;

            default:
                return false;
            }
        }

        bool write(uint32_t address, int32_t value, LESSDB::sectionParameterType_t type) override
        {
            switch (type)
            {
            case LESSDB::sectionParameterType_t::word:
            case LESSDB::sectionParameterType_t::byte:
            case LESSDB::sectionParameterType_t::halfByte:
            case LESSDB::sectionParameterType_t::bit:
            {
                uint16_t tempData = value;

                return emuEEPROM.write(address, tempData) == EmuEEPROM::writeStatus_t::ok;
            }
            break;

            default:
                return false;
            }
        }

        size_t paramUsage(LESSDB::sectionParameterType_t type) override
        {
            switch (type)
            {
            case LESSDB::sectionParameterType_t::dword:
                return 8;

            default:
                return 4;    //2 bytes for address, 2 bytes for data
            }
        }
    } storageAccess;

    Database database(dbHandlers, storageAccess, true);
}    // namespace

int main(int argc, char* argv[])
{
    if (argc <= 1)
    {
        std::cout << argv[0] << "ERROR: Filename for generated flash not provided" << std::endl;
        return -1;
    }
    else
    {
        emuEEPROMstorage.setFilename(argv[1]);
    }

    return !database.init();
}<|endoftext|>


<commit_before>// template <class T> void foo(S1<T> s1, const typename T::T2 t2) {}

// originally found in package 'aspell'

// ERR-MATCH:

template <class T> struct S1 {};

template <class T> void foo(S1<T> s1, const typename T::T2 t2) {}
<commit_msg>Turned segfault into assertion failure, so have ERR-MATCH now<commit_after>// template <class T> void foo(S1<T> s1, const typename T::T2 t2) {}

// originally found in package 'aspell'

// ERR-MATCH: Assertion failed: .*ceae1527-94a7-480d-9134-5dbd8cbfb2aa

template <class T> struct S1 {};

template <class T> void foo(S1<T> s1, const typename T::T2 t2) {}
<|endoftext|>


<commit_before>#ifndef INC_METTLE_MATCHERS_COLLECTION_HPP
#define INC_METTLE_MATCHERS_COLLECTION_HPP

#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <sstream>
#include <tuple>

#include "core.hpp"
#include "../detail/move_if.hpp"

namespace mettle {

namespace detail {

  template<typename Matcher>
  class member_impl : public matcher_tag {
  public:
    member_impl(std::string desc, bool initial, Matcher matcher)
      : desc_(std::move(desc)), initial_(initial),
        matcher_(std::move(matcher)) {}

    template<typename U>
    match_result operator ()(const U &value) const {
      std::ostringstream ss;
      ostream_list_append append(ss);
      bool good = initial_;

      ss << "[";
      for(auto &&i : value) {
        auto result = matcher_(i);
        if(result != initial_)
          good = result;
        append(matcher_message(result, i));
      }
      ss << "]";

      return {good, ss.str()};
    }

    std::string desc() const {
      return desc_ + matcher_.desc();
    }
  private:
    const std::string desc_;
    const bool initial_;
    Matcher matcher_;
  };
}

template<typename T>
auto member(T &&thing) {
  return detail::member_impl<ensure_matcher_t<T>>(
    "member ", false, ensure_matcher(std::forward<T>(thing))
  );
}

template<typename T>
auto each(T &&thing) {
  return detail::member_impl<ensure_matcher_t<T>>(
    "each ", true, ensure_matcher(std::forward<T>(thing))
  );
}

namespace detail {
  template<typename Matcher>
  class each_impl : public matcher_tag {
  public:
    template<typename T, typename U>
    each_impl(T begin, T end, U &&meta_matcher) {
      for(; begin != end; ++begin)
        matchers_.push_back(meta_matcher(*begin));
    }

    template<typename U>
    match_result operator ()(const U &value) const {
      std::ostringstream ss;
      ostream_list_append append(ss);
      bool good = true;

      ss << "[";
      auto i = std::begin(value), end = std::end(value);
      for(auto &&m : matchers_) {
        if(i == end) {
          good = false;
          break;
        }

        match_result result = m(*i);
        good &= result;
        append(matcher_message(result, *i));
        ++i;
      }

      // Print any remaining expected values (if `value` is longer than the list
      // of matchers).
      good &= (i == end);
      for(; i != end; ++i)
        append(to_printable(*i));

      ss << "]";

      return {good, ss.str()};
    }

    std::string desc() const {
      return "[" + stringify(joined(matchers_, [](const auto &matcher) {
        return matcher.desc();
      })) + "]";
    }
  private:
    std::vector<Matcher> matchers_;
  };
}

template<typename T, typename U>
inline auto each(T begin, T end, U &&meta_matcher) {
  using Matcher = decltype(meta_matcher(*begin));
  static_assert(is_matcher<Matcher>::value,
                "meta_matcher must be a function that returns a matcher");
  return detail::each_impl<decltype(meta_matcher(*begin))>(
    begin, end, std::forward<U>(meta_matcher)
  );
}

template<typename T, typename U>
inline auto each(T &thing, U &&meta_matcher) {
  return each(std::begin(thing), std::end(thing),
              std::forward<U>(meta_matcher));
}

template<typename T, typename U>
inline auto each(T &&thing, U &&meta_matcher) {
  return each(std::make_move_iterator(std::begin(thing)),
              std::make_move_iterator(std::end(thing)),
              std::forward<U>(meta_matcher));
}

template<typename T, typename U>
inline auto each(std::initializer_list<T> list, U &&meta_matcher) {
  return each(list.begin(), list.end(), std::forward<U>(meta_matcher));
}

namespace detail {
  template<typename ...T>
  class array_impl : public matcher_tag {
  public:
    array_impl(T ...matchers) : matchers_(std::move(matchers)...) {}

    template<typename U>
    match_result operator ()(const U &value) const {
      std::ostringstream ss;
      ostream_list_append append(ss);
      bool good = true;

      ss << "[";
      auto i = std::begin(value), end = std::end(value);
      tuple_for_until(matchers_, [&i, &end, &good, &append](const auto &m) {
        if(i == end) {
          good = false;
          return true;
        }

        auto result = m(*i);
        good &= result;
        append(matcher_message(result, *i));
        ++i;
        return false;
      });

      // Print any remaining expected values (if `value` is longer than the list
      // of matchers).
      good &= (i == end);
      for(; i != end; ++i)
        append(to_printable(*i));

      ss << "]";

      return {good, ss.str()};
    }

    std::string desc() const {
      return "[" + stringify(tuple_joined(matchers_, [](auto &&matcher) {
        return matcher.desc();
      })) + "]";
    }
  private:
    std::tuple<T...> matchers_;
  };
}

template<typename ...T>
inline auto array(T &&...things) {
  return detail::array_impl<ensure_matcher_t<T>...>(
    ensure_matcher(std::forward<T>(things))...
  );
}

auto sorted() {
  return make_matcher([](const auto &value) {
    return std::is_sorted(std::begin(value), std::end(value));
  }, "sorted");
}

template<typename T>
auto sorted(T &&compare) {
  return make_matcher(
    std::forward<T>(compare),
    [](const auto &value, auto &&compare) {
    return std::is_sorted(std::begin(value), std::end(value), compare);
  }, "sorted by ");
}

} // namespace mettle

#endif
<commit_msg>Remove superfluous #include<commit_after>#ifndef INC_METTLE_MATCHERS_COLLECTION_HPP
#define INC_METTLE_MATCHERS_COLLECTION_HPP

#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <sstream>
#include <tuple>

#include "core.hpp"

namespace mettle {

namespace detail {

  template<typename Matcher>
  class member_impl : public matcher_tag {
  public:
    member_impl(std::string desc, bool initial, Matcher matcher)
      : desc_(std::move(desc)), initial_(initial),
        matcher_(std::move(matcher)) {}

    template<typename U>
    match_result operator ()(const U &value) const {
      std::ostringstream ss;
      ostream_list_append append(ss);
      bool good = initial_;

      ss << "[";
      for(auto &&i : value) {
        auto result = matcher_(i);
        if(result != initial_)
          good = result;
        append(matcher_message(result, i));
      }
      ss << "]";

      return {good, ss.str()};
    }

    std::string desc() const {
      return desc_ + matcher_.desc();
    }
  private:
    const std::string desc_;
    const bool initial_;
    Matcher matcher_;
  };
}

template<typename T>
auto member(T &&thing) {
  return detail::member_impl<ensure_matcher_t<T>>(
    "member ", false, ensure_matcher(std::forward<T>(thing))
  );
}

template<typename T>
auto each(T &&thing) {
  return detail::member_impl<ensure_matcher_t<T>>(
    "each ", true, ensure_matcher(std::forward<T>(thing))
  );
}

namespace detail {
  template<typename Matcher>
  class each_impl : public matcher_tag {
  public:
    template<typename T, typename U>
    each_impl(T begin, T end, U &&meta_matcher) {
      for(; begin != end; ++begin)
        matchers_.push_back(meta_matcher(*begin));
    }

    template<typename U>
    match_result operator ()(const U &value) const {
      std::ostringstream ss;
      ostream_list_append append(ss);
      bool good = true;

      ss << "[";
      auto i = std::begin(value), end = std::end(value);
      for(auto &&m : matchers_) {
        if(i == end) {
          good = false;
          break;
        }

        match_result result = m(*i);
        good &= result;
        append(matcher_message(result, *i));
        ++i;
      }

      // Print any remaining expected values (if `value` is longer than the list
      // of matchers).
      good &= (i == end);
      for(; i != end; ++i)
        append(to_printable(*i));

      ss << "]";

      return {good, ss.str()};
    }

    std::string desc() const {
      return "[" + stringify(joined(matchers_, [](const auto &matcher) {
        return matcher.desc();
      })) + "]";
    }
  private:
    std::vector<Matcher> matchers_;
  };
}

template<typename T, typename U>
inline auto each(T begin, T end, U &&meta_matcher) {
  using Matcher = decltype(meta_matcher(*begin));
  static_assert(is_matcher<Matcher>::value,
                "meta_matcher must be a function that returns a matcher");
  return detail::each_impl<decltype(meta_matcher(*begin))>(
    begin, end, std::forward<U>(meta_matcher)
  );
}

template<typename T, typename U>
inline auto each(T &thing, U &&meta_matcher) {
  return each(std::begin(thing), std::end(thing),
              std::forward<U>(meta_matcher));
}

template<typename T, typename U>
inline auto each(T &&thing, U &&meta_matcher) {
  return each(std::make_move_iterator(std::begin(thing)),
              std::make_move_iterator(std::end(thing)),
              std::forward<U>(meta_matcher));
}

template<typename T, typename U>
inline auto each(std::initializer_list<T> list, U &&meta_matcher) {
  return each(list.begin(), list.end(), std::forward<U>(meta_matcher));
}

namespace detail {
  template<typename ...T>
  class array_impl : public matcher_tag {
  public:
    array_impl(T ...matchers) : matchers_(std::move(matchers)...) {}

    template<typename U>
    match_result operator ()(const U &value) const {
      std::ostringstream ss;
      ostream_list_append append(ss);
      bool good = true;

      ss << "[";
      auto i = std::begin(value), end = std::end(value);
      tuple_for_until(matchers_, [&i, &end, &good, &append](const auto &m) {
        if(i == end) {
          good = false;
          return true;
        }

        auto result = m(*i);
        good &= result;
        append(matcher_message(result, *i));
        ++i;
        return false;
      });

      // Print any remaining expected values (if `value` is longer than the list
      // of matchers).
      good &= (i == end);
      for(; i != end; ++i)
        append(to_printable(*i));

      ss << "]";

      return {good, ss.str()};
    }

    std::string desc() const {
      return "[" + stringify(tuple_joined(matchers_, [](auto &&matcher) {
        return matcher.desc();
      })) + "]";
    }
  private:
    std::tuple<T...> matchers_;
  };
}

template<typename ...T>
inline auto array(T &&...things) {
  return detail::array_impl<ensure_matcher_t<T>...>(
    ensure_matcher(std::forward<T>(things))...
  );
}

auto sorted() {
  return make_matcher([](const auto &value) {
    return std::is_sorted(std::begin(value), std::end(value));
  }, "sorted");
}

template<typename T>
auto sorted(T &&compare) {
  return make_matcher(
    std::forward<T>(compare),
    [](const auto &value, auto &&compare) {
    return std::is_sorted(std::begin(value), std::end(value), compare);
  }, "sorted by ");
}

} // namespace mettle

#endif
<|endoftext|>


<commit_before>/*################################################################################
  ##
  ##   Copyright (C) 2011-2017 Keith O'Hara
  ##
  ##   This file is part of the OptimLib C++ library.
  ##
  ##   OptimLib is free software: you can redistribute it and/or modify
  ##   it under the terms of the GNU General Public License as published by
  ##   the Free Software Foundation, either version 2 of the License, or
  ##   (at your option) any later version.
  ##
  ##   OptimLib is distributed in the hope that it will be useful,
  ##   but WITHOUT ANY WARRANTY; without even the implied warranty of
  ##   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  ##   GNU General Public License for more details.
  ##
  ################################################################################*/

/*
 * Determine the upper-lower bounds combo type
 *
 * Keith O'Hara
 * 05/01/2012
 *
 * This version:
 * 08/12/2017
 */

// note: std::isfinite is not true for: NaN, - Inf, or + Inf

inline
arma::uvec
determine_bounds_type(const bool vals_bound, const int n_vals, const arma::vec& lower_bounds, const arma::vec& upper_bounds)
{
    arma::uvec ret_vec(n_vals);

    ret_vec.fill(1); // base case: 1 - no bounds imposed

    if (vals_bound) {
        for (int i=0; i < n_vals; i++) {
            if ( std::isfinite(lower_bounds(i)) && std::isfinite(upper_bounds(i)) ) {
                // lower and upper bound imposed
                ret_vec(i) = 4;
            } else if ( std::isfinite(lower_bounds(i)) && !std::isfinite(upper_bounds(i)) ) {
                // lower bound only
                ret_vec(i) = 2;
            } else if ( !std::isfinite(lower_bounds(i)) && std::isfinite(upper_bounds(i)) ) {
                // upper bound only
                ret_vec(i) = 3;
            } else {
                printf("determine_bounds_type: unknown error\n");
            }
        }
    }
    //
    return ret_vec;
}
<commit_msg>not an error<commit_after>/*################################################################################
  ##
  ##   Copyright (C) 2011-2017 Keith O'Hara
  ##
  ##   This file is part of the OptimLib C++ library.
  ##
  ##   OptimLib is free software: you can redistribute it and/or modify
  ##   it under the terms of the GNU General Public License as published by
  ##   the Free Software Foundation, either version 2 of the License, or
  ##   (at your option) any later version.
  ##
  ##   OptimLib is distributed in the hope that it will be useful,
  ##   but WITHOUT ANY WARRANTY; without even the implied warranty of
  ##   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  ##   GNU General Public License for more details.
  ##
  ################################################################################*/

/*
 * Determine the upper-lower bounds combo type
 *
 * Keith O'Hara
 * 05/01/2012
 *
 * This version:
 * 08/12/2017
 */

// note: std::isfinite is not true for: NaN, - Inf, or + Inf

inline
arma::uvec
determine_bounds_type(const bool vals_bound, const int n_vals, const arma::vec& lower_bounds, const arma::vec& upper_bounds)
{
    arma::uvec ret_vec(n_vals);

    ret_vec.fill(1); // base case: 1 - no bounds imposed

    if (vals_bound) {
        for (int i=0; i < n_vals; i++) {
            if ( std::isfinite(lower_bounds(i)) && std::isfinite(upper_bounds(i)) ) {
                // lower and upper bound imposed
                ret_vec(i) = 4;
            } else if ( std::isfinite(lower_bounds(i)) && !std::isfinite(upper_bounds(i)) ) {
                // lower bound only
                ret_vec(i) = 2;
            } else if ( !std::isfinite(lower_bounds(i)) && std::isfinite(upper_bounds(i)) ) {
                // upper bound only
                ret_vec(i) = 3;
            }
        }
    }
    //
    return ret_vec;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.1  1999/11/09 01:02:14  twl
 * Initial revision
 *
 * Revision 1.3  1999/11/08 20:42:25  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include    <util/PlatformUtils.hpp>
#include    <util/XMLString.hpp>
#include    <util/URL.hpp>
#include    <internal/URLInputSource.hpp>
#include    <internal/XMLScanner.hpp>
#include    <validators/DTD/DTDValidator.hpp>
#include    "ParserTest.hpp"

// ---------------------------------------------------------------------------
//  Global data
//
//  errStrm
//  outStrm
//      The streams we use to output our test data and error info. These are
//      simple classes used just for XML4C2 samples and debug. They are not
//      sufficient for real applications, nor are they supported for
//      production code use. They merely provide a simple and portable means
//      to output the Unicode data from the parser on the local host.
// ---------------------------------------------------------------------------
XMLStdErr   errStrm;
XMLStdOut   outStrm;

// ---------------------------------------------------------------------------
//  Program entry point
// ---------------------------------------------------------------------------
int main(int argC, char** argV)
{
    // Init the XML platform
    try
    {
        XMLPlatformUtils::Initialize();
    }

    catch(const XMLException& toCatch)
    {
        errStrm << "Error during platform init! Message:\n"
                << toCatch.getMessage() << EndLn;
        return 1;
    }

    //
    //  Create our test parser object. This guy implements the internal event
    //  APIs and is plugged into the scanner.
    //
    TestParser parserTest;

    // Figure out the parameters
    bool doValidation = false;
    bool doNamespaces = false;
    bool keepGoing = false;
    XMLCh*  urlPath = 0;
    for (int index = 1; index < argC; index++)
    {
        if (!XMLString::compareIString(argV[index], "/Debug"))
            parserTest.setOutputType(OutputType_Debug);
        else if (!XMLString::compareIString(argV[index], "/Validate"))
            doValidation = true;
        else if (!XMLString::compareIString(argV[index], "/Namespaces"))
        {
            doNamespaces = true;
            parserTest.setDoNamespaces(true);
        }
        else if (!XMLString::compareIString(argV[index], "/XML"))
            parserTest.setOutputType(OutputType_XML);
        else if (!XMLString::compareIString(argV[index], "/IntDTD"))
            parserTest.setShowIntDTD(true);
        else if (!XMLString::compareIString(argV[index], "/ShowWarnings"))
            parserTest.setShowWarnings(true);
        else if (!XMLString::compareIString(argV[index], "/ShowErrLoc"))
            parserTest.setShowErrLoc(true);
        else if (!XMLString::compareIString(argV[index], "/JCCanon"))
            parserTest.setOutputType(OutputType_JCCanon);
        else if (!XMLString::compareIString(argV[index], "/SunCanon"))
            parserTest.setOutputType(OutputType_SunCanon);
        else if (!XMLString::compareIString(argV[index], "/KeepGoing"))
            keepGoing = true;
        else if (!XMLString::compareNIString(argV[index], "/URL=", 5))
            urlPath = XMLString::transcode(&argV[index][5]);
        else
            errStrm << "Unknown parameter: " << argV[index] << EndLn;
    }

    // We have to have a URL to work on
    if (!urlPath)
    {
        errStrm << "A URL must be provided, /URL=xxxx" << EndLn;
        return 1;
    }

    //
    //  Create a validator of the correct type so that we can install it
    //  on the scanner.
    //
    //  <TBD> Later, when Schema validators exist, we'll have a parameter
    //  to select one or the other
    //
    XMLValidator* validator = 0;
    DTDValidator* dtdVal = new DTDValidator(&parserTest);
    dtdVal->setDocTypeHandler(&parserTest);
    validator = dtdVal;

    // And now create the scanner and give it all the handlers
    XMLScanner scanner
    (
        &parserTest
        , 0
        , &parserTest
        , validator
    );

    // Set the scanner flags that we were told to
    scanner.setDoValidation(doValidation);
    scanner.setDoNamespaces(doNamespaces);
    scanner.setExitOnFirstFatal(!keepGoing);

    // Tell the parser about the scanner
    parserTest.setScanner(&scanner);

    try
    {
        URLInputSource src(urlPath);
        scanner.scanDocument(src);
    }

    catch(const XMLException& toCatch)
    {
        outStrm << "Exception during scan:\n    "
                << toCatch.getMessage()
                << EndLn;
    }

    return 0;
}
<commit_msg>Changes for the new URL and InputSource changes.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.2  2000/01/12 00:29:49  roddey
 * Changes for the new URL and InputSource changes.
 *
 * Revision 1.1.1.1  1999/11/09 01:02:14  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:42:25  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include    <util/PlatformUtils.hpp>
#include    <util/XMLString.hpp>
#include    <util/URL.hpp>
#include    <internal/XMLScanner.hpp>
#include    <validators/DTD/DTDValidator.hpp>
#include    "ParserTest.hpp"

// ---------------------------------------------------------------------------
//  Global data
//
//  errStrm
//  outStrm
//      The streams we use to output our test data and error info. These are
//      simple classes used just for XML4C2 samples and debug. They are not
//      sufficient for real applications, nor are they supported for
//      production code use. They merely provide a simple and portable means
//      to output the Unicode data from the parser on the local host.
// ---------------------------------------------------------------------------
XMLStdErr   errStrm;
XMLStdOut   outStrm;

// ---------------------------------------------------------------------------
//  Program entry point
// ---------------------------------------------------------------------------
int main(int argC, char** argV)
{
    // Init the XML platform
    try
    {
        XMLPlatformUtils::Initialize();
    }

    catch(const XMLException& toCatch)
    {
        errStrm << "Error during platform init! Message:\n"
                << toCatch.getMessage() << EndLn;
        return 1;
    }

    //
    //  Create our test parser object. This guy implements the internal event
    //  APIs and is plugged into the scanner.
    //
    TestParser parserTest;

    // Figure out the parameters
    bool doValidation = false;
    bool doNamespaces = false;
    bool keepGoing = false;
    XMLCh*  urlPath = 0;
    for (int index = 1; index < argC; index++)
    {
        if (!XMLString::compareIString(argV[index], "/Debug"))
            parserTest.setOutputType(OutputType_Debug);
        else if (!XMLString::compareIString(argV[index], "/Validate"))
            doValidation = true;
        else if (!XMLString::compareIString(argV[index], "/Namespaces"))
        {
            doNamespaces = true;
            parserTest.setDoNamespaces(true);
        }
        else if (!XMLString::compareIString(argV[index], "/XML"))
            parserTest.setOutputType(OutputType_XML);
        else if (!XMLString::compareIString(argV[index], "/IntDTD"))
            parserTest.setShowIntDTD(true);
        else if (!XMLString::compareIString(argV[index], "/ShowWarnings"))
            parserTest.setShowWarnings(true);
        else if (!XMLString::compareIString(argV[index], "/ShowErrLoc"))
            parserTest.setShowErrLoc(true);
        else if (!XMLString::compareIString(argV[index], "/JCCanon"))
            parserTest.setOutputType(OutputType_JCCanon);
        else if (!XMLString::compareIString(argV[index], "/SunCanon"))
            parserTest.setOutputType(OutputType_SunCanon);
        else if (!XMLString::compareIString(argV[index], "/KeepGoing"))
            keepGoing = true;
        else if (!XMLString::compareNIString(argV[index], "/URL=", 5))
            urlPath = XMLString::transcode(&argV[index][5]);
        else
            errStrm << "Unknown parameter: " << argV[index] << EndLn;
    }

    // We have to have a URL to work on
    if (!urlPath)
    {
        errStrm << "A URL must be provided, /URL=xxxx" << EndLn;
        return 1;
    }

    //
    //  Create a validator of the correct type so that we can install it
    //  on the scanner.
    //
    //  <TBD> Later, when Schema validators exist, we'll have a parameter
    //  to select one or the other
    //
    XMLValidator* validator = 0;
    DTDValidator* dtdVal = new DTDValidator(&parserTest);
    dtdVal->setDocTypeHandler(&parserTest);
    validator = dtdVal;

    // And now create the scanner and give it all the handlers
    XMLScanner scanner
    (
        &parserTest
        , 0
        , &parserTest
        , validator
    );

    // Set the scanner flags that we were told to
    scanner.setDoValidation(doValidation);
    scanner.setDoNamespaces(doNamespaces);
    scanner.setExitOnFirstFatal(!keepGoing);

    // Tell the parser about the scanner
    parserTest.setScanner(&scanner);

    try
    {
        scanner.scanDocument(urlPath);
    }

    catch(const XMLException& toCatch)
    {
        outStrm << "Exception during scan:\n    "
                << toCatch.getMessage()
                << EndLn;
    }
    return 0;
}
<|endoftext|>