<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/in_process_webkit/dom_storage_message_filter.h"

#include "base/nullable_string16.h"
#include "content/browser/browser_thread.h"
#include "content/browser/in_process_webkit/dom_storage_area.h"
#include "content/browser/in_process_webkit/dom_storage_context.h"
#include "content/browser/in_process_webkit/dom_storage_namespace.h"
#include "content/common/dom_storage_messages.h"
#include "googleurl/src/gurl.h"

using WebKit::WebStorageArea;

DOMStorageMessageFilter* DOMStorageMessageFilter::storage_event_message_filter =
    NULL;
const GURL* DOMStorageMessageFilter::storage_event_url_ = NULL;

DOMStorageMessageFilter::
ScopedStorageEventContext::ScopedStorageEventContext(
    DOMStorageMessageFilter* dispatcher_message_filter, const GURL* url) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DCHECK(!storage_event_message_filter);
  DCHECK(!storage_event_url_);
  storage_event_message_filter = dispatcher_message_filter;
  storage_event_url_ = url;
  DCHECK(storage_event_message_filter);
  DCHECK(storage_event_url_);
}

DOMStorageMessageFilter::
ScopedStorageEventContext::~ScopedStorageEventContext() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DCHECK(storage_event_message_filter);
  DCHECK(storage_event_url_);
  storage_event_message_filter = NULL;
  storage_event_url_ = NULL;
}

DOMStorageMessageFilter::DOMStorageMessageFilter(
    int process_id, WebKitContext* webkit_context)
    : webkit_context_(webkit_context),
      process_id_(process_id) {
}

DOMStorageMessageFilter::~DOMStorageMessageFilter() {
  // This is not always true during testing.
  if (peer_handle())
    Context()->UnregisterMessageFilter(this);
}

void DOMStorageMessageFilter::OnChannelConnected(int32 peer_pid) {
  BrowserMessageFilter::OnChannelConnected(peer_pid);

  Context()->RegisterMessageFilter(this);
}

/* static */
void DOMStorageMessageFilter::DispatchStorageEvent(const NullableString16& key,
    const NullableString16& old_value, const NullableString16& new_value,
    const string16& origin, const GURL& url, bool is_local_storage) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DCHECK(is_local_storage);  // Only LocalStorage is implemented right now.
  DCHECK(storage_event_message_filter);
  DOMStorageMsg_Event_Params params;
  params.key = key;
  params.old_value = old_value;
  params.new_value = new_value;
  params.origin = origin;
  params.url = *storage_event_url_;  // The url passed in is junk.
  params.storage_type = is_local_storage ? DOM_STORAGE_LOCAL
                                         : DOM_STORAGE_SESSION;
  // The storage_event_message_filter is the DOMStorageMessageFilter that is up
  // in the current call stack since it caused the storage event to fire.
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
      NewRunnableMethod(storage_event_message_filter,
          &DOMStorageMessageFilter::OnStorageEvent, params));
}

bool DOMStorageMessageFilter::OnMessageReceived(const IPC::Message& message,
                                                bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(DOMStorageMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_StorageAreaId, OnStorageAreaId)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_Length, OnLength)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_Key, OnKey)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_GetItem, OnGetItem)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_SetItem, OnSetItem)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_RemoveItem, OnRemoveItem)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_Clear, OnClear)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DOMStorageMessageFilter::OnDestruct() const {
  BrowserThread::DeleteOnIOThread::Destruct(this);
}

void DOMStorageMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message,
    BrowserThread::ID* thread) {
  if (IPC_MESSAGE_CLASS(message) == DOMStorageMsgStart)
    *thread = BrowserThread::WEBKIT;
}

void DOMStorageMessageFilter::OnStorageAreaId(int64 namespace_id,
                                              const string16& origin,
                                              int64* storage_area_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));

  DOMStorageNamespace* storage_namespace =
      Context()->GetStorageNamespace(namespace_id, true);
  if (!storage_namespace) {
    *storage_area_id = DOMStorageContext::kInvalidStorageId;
    return;
  }
  DOMStorageArea* storage_area = storage_namespace->GetStorageArea(origin);
  *storage_area_id = storage_area->id();
}

void DOMStorageMessageFilter::OnLength(int64 storage_area_id,
                                       unsigned* length) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *length = 0;
  } else {
    *length = storage_area->Length();
  }
}

void DOMStorageMessageFilter::OnKey(int64 storage_area_id, unsigned index,
                                    NullableString16* key) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *key = NullableString16(true);
  } else {
    *key = storage_area->Key(index);
  }
}

void DOMStorageMessageFilter::OnGetItem(int64 storage_area_id,
                                        const string16& key,
                                        NullableString16* value) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *value = NullableString16(true);
  } else {
    *value = storage_area->GetItem(key);
  }
}

void DOMStorageMessageFilter::OnSetItem(
    int64 storage_area_id, const string16& key,
    const string16& value, const GURL& url,
    WebKit::WebStorageArea::Result* result, NullableString16* old_value) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *old_value = NullableString16(true);
    *result = WebKit::WebStorageArea::ResultOK;
    return;
  }

  ScopedStorageEventContext scope(this, &url);
  *old_value = storage_area->SetItem(key, value, result);
}

void DOMStorageMessageFilter::OnRemoveItem(
    int64 storage_area_id, const string16& key, const GURL& url,
    NullableString16* old_value) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *old_value = NullableString16(true);
    return;
  }

  ScopedStorageEventContext scope(this, &url);
  *old_value = storage_area->RemoveItem(key);
}

void DOMStorageMessageFilter::OnClear(int64 storage_area_id, const GURL& url,
                                      bool* something_cleared) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *something_cleared = false;
    return;
  }

  ScopedStorageEventContext scope(this, &url);
  *something_cleared = storage_area->Clear();
}

void DOMStorageMessageFilter::OnStorageEvent(
    const DOMStorageMsg_Event_Params& params) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  const DOMStorageContext::MessageFilterSet* set =
      Context()->GetMessageFilterSet();
  DOMStorageContext::MessageFilterSet::const_iterator cur = set->begin();
  while (cur != set->end()) {
    // The renderer that generates the event handles it itself.
    if (*cur != this)
      (*cur)->Send(new DOMStorageMsg_Event(params));
    ++cur;
  }
}
<commit_msg>A stab at fixing a frequent crasher in the DOMStorage stuff.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/in_process_webkit/dom_storage_message_filter.h"

#include "base/nullable_string16.h"
#include "content/browser/browser_thread.h"
#include "content/browser/in_process_webkit/dom_storage_area.h"
#include "content/browser/in_process_webkit/dom_storage_context.h"
#include "content/browser/in_process_webkit/dom_storage_namespace.h"
#include "content/common/dom_storage_messages.h"
#include "googleurl/src/gurl.h"

using WebKit::WebStorageArea;

DOMStorageMessageFilter* DOMStorageMessageFilter::storage_event_message_filter =
    NULL;
const GURL* DOMStorageMessageFilter::storage_event_url_ = NULL;

DOMStorageMessageFilter::
ScopedStorageEventContext::ScopedStorageEventContext(
    DOMStorageMessageFilter* dispatcher_message_filter, const GURL* url) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DCHECK(!storage_event_message_filter);
  DCHECK(!storage_event_url_);
  storage_event_message_filter = dispatcher_message_filter;
  storage_event_url_ = url;
  DCHECK(storage_event_message_filter);
  DCHECK(storage_event_url_);
}

DOMStorageMessageFilter::
ScopedStorageEventContext::~ScopedStorageEventContext() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DCHECK(storage_event_message_filter);
  DCHECK(storage_event_url_);
  storage_event_message_filter = NULL;
  storage_event_url_ = NULL;
}

DOMStorageMessageFilter::DOMStorageMessageFilter(
    int process_id, WebKitContext* webkit_context)
    : webkit_context_(webkit_context),
      process_id_(process_id) {
}

DOMStorageMessageFilter::~DOMStorageMessageFilter() {
  if (peer_handle())
    Context()->UnregisterMessageFilter(this);
}

void DOMStorageMessageFilter::OnChannelConnected(int32 peer_pid) {
  BrowserMessageFilter::OnChannelConnected(peer_pid);
  if (peer_handle())
    Context()->RegisterMessageFilter(this);
}

/* static */
void DOMStorageMessageFilter::DispatchStorageEvent(const NullableString16& key,
    const NullableString16& old_value, const NullableString16& new_value,
    const string16& origin, const GURL& url, bool is_local_storage) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DCHECK(is_local_storage);  // Only LocalStorage is implemented right now.
  DCHECK(storage_event_message_filter);
  DOMStorageMsg_Event_Params params;
  params.key = key;
  params.old_value = old_value;
  params.new_value = new_value;
  params.origin = origin;
  params.url = *storage_event_url_;  // The url passed in is junk.
  params.storage_type = is_local_storage ? DOM_STORAGE_LOCAL
                                         : DOM_STORAGE_SESSION;
  // The storage_event_message_filter is the DOMStorageMessageFilter that is up
  // in the current call stack since it caused the storage event to fire.
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
      NewRunnableMethod(storage_event_message_filter,
          &DOMStorageMessageFilter::OnStorageEvent, params));
}

bool DOMStorageMessageFilter::OnMessageReceived(const IPC::Message& message,
                                                bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(DOMStorageMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_StorageAreaId, OnStorageAreaId)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_Length, OnLength)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_Key, OnKey)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_GetItem, OnGetItem)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_SetItem, OnSetItem)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_RemoveItem, OnRemoveItem)
    IPC_MESSAGE_HANDLER(DOMStorageHostMsg_Clear, OnClear)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DOMStorageMessageFilter::OnDestruct() const {
  BrowserThread::DeleteOnIOThread::Destruct(this);
}

void DOMStorageMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message,
    BrowserThread::ID* thread) {
  if (IPC_MESSAGE_CLASS(message) == DOMStorageMsgStart)
    *thread = BrowserThread::WEBKIT;
}

void DOMStorageMessageFilter::OnStorageAreaId(int64 namespace_id,
                                              const string16& origin,
                                              int64* storage_area_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));

  DOMStorageNamespace* storage_namespace =
      Context()->GetStorageNamespace(namespace_id, true);
  if (!storage_namespace) {
    *storage_area_id = DOMStorageContext::kInvalidStorageId;
    return;
  }
  DOMStorageArea* storage_area = storage_namespace->GetStorageArea(origin);
  *storage_area_id = storage_area->id();
}

void DOMStorageMessageFilter::OnLength(int64 storage_area_id,
                                       unsigned* length) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *length = 0;
  } else {
    *length = storage_area->Length();
  }
}

void DOMStorageMessageFilter::OnKey(int64 storage_area_id, unsigned index,
                                    NullableString16* key) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *key = NullableString16(true);
  } else {
    *key = storage_area->Key(index);
  }
}

void DOMStorageMessageFilter::OnGetItem(int64 storage_area_id,
                                        const string16& key,
                                        NullableString16* value) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *value = NullableString16(true);
  } else {
    *value = storage_area->GetItem(key);
  }
}

void DOMStorageMessageFilter::OnSetItem(
    int64 storage_area_id, const string16& key,
    const string16& value, const GURL& url,
    WebKit::WebStorageArea::Result* result, NullableString16* old_value) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *old_value = NullableString16(true);
    *result = WebKit::WebStorageArea::ResultOK;
    return;
  }

  ScopedStorageEventContext scope(this, &url);
  *old_value = storage_area->SetItem(key, value, result);
}

void DOMStorageMessageFilter::OnRemoveItem(
    int64 storage_area_id, const string16& key, const GURL& url,
    NullableString16* old_value) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *old_value = NullableString16(true);
    return;
  }

  ScopedStorageEventContext scope(this, &url);
  *old_value = storage_area->RemoveItem(key);
}

void DOMStorageMessageFilter::OnClear(int64 storage_area_id, const GURL& url,
                                      bool* something_cleared) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
  DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
  if (!storage_area) {
    *something_cleared = false;
    return;
  }

  ScopedStorageEventContext scope(this, &url);
  *something_cleared = storage_area->Clear();
}

void DOMStorageMessageFilter::OnStorageEvent(
    const DOMStorageMsg_Event_Params& params) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  const DOMStorageContext::MessageFilterSet* set =
      Context()->GetMessageFilterSet();
  DOMStorageContext::MessageFilterSet::const_iterator cur = set->begin();
  while (cur != set->end()) {
    // The renderer that generates the event handles it itself.
    if (*cur != this)
      (*cur)->Send(new DOMStorageMsg_Event(params));
    ++cur;
  }
}
<|endoftext|>


<commit_before>/*
  FUSE: Filesystem in Userspace
  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>

  This program can be distributed under the terms of the GNU GPL.
  See the file COPYING.

  gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello
*/

#define FUSE_USE_VERSION 30

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#include <iostream>
#include <fstream>
#include <loss/fs/virtual_fileystem.h>
#include <loss/fs/ram_filesystem.h>
#include <loss/fs/ram_filesystem_drive.h>

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";

static loss::VirtualFileSystem *vfs = nullptr;
static loss::RamFileSystem *ramfs = nullptr;

static int hello_getattr(const char *path, struct stat *stbuf)
{
    int res = 0;

    memset(stbuf, 0, sizeof(struct stat));
    // Not really used at the moment
    stbuf->st_nlink = 1;
    /*
    if (strcmp(path, "/") == 0) {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 2;
    } else if (strcmp(path, hello_path) == 0) {
        stbuf->st_mode = S_IFREG | 0444;
        stbuf->st_nlink = 1;
        stbuf->st_size = strlen(hello_str);
    } else
        res = -ENOENT;
        */
    loss::MetadataDef metadata;
    auto read_result = vfs->entry_metadata(path, metadata);
    if (read_result != loss::SUCCESS)
    {
        res = -ENOENT;
    }
    else
    {
        if (metadata.type() == loss::FOLDER_ENTRY)
        {
            stbuf->st_mode = S_IFDIR | 0755;
        }
        else if (metadata.type() == loss::FILE_ENTRY)
        {
            stbuf->st_mode = S_IFREG | 0444;
            uint32_t size;
            vfs->entry_size(path, size);
            stbuf->st_size = size;
        }
    }

    return res;
}

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
             off_t offset, struct fuse_file_info *fi)
{
    (void) offset;
    (void) fi;

    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);

    loss::FolderEntry folder;
    auto read_result = vfs->read_folder(path, folder);

    if (read_result == loss::SUCCESS)
    {
        for (auto &iter : folder)
        {
            filler(buf, iter.first.c_str(), NULL, 0);
        }
    }
    else
    {
        return -ENOENT;
    }

    return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi)
{
    loss::MetadataDef metadata;
    if (vfs->entry_metadata(path, metadata) != loss::SUCCESS)
    {
        return -ENOENT;
    }

    if ((fi->flags & 3) != O_RDONLY)
    {
        return -EACCES;
    }

    return 0;
}

static int hello_read(const char *path, char *buf, size_t size, off_t offset,
              struct fuse_file_info *fi)
{
    auto read_result = vfs->read(path, offset, size, (uint8_t*)buf);
    if (read_result.status() != loss::SUCCESS)
    {
        return -ENOENT;
    }

    return read_result.bytes();
    /*
    size_t len;
    (void) fi;
    if(strcmp(path, hello_path) != 0)
        return -ENOENT;

    len = strlen(hello_str);
    if (offset < len) {
        if (offset + size > len)
            size = len - offset;
        memcpy(buf, hello_str + offset, size);
    } else
        size = 0;

    return size;
        */
}

static struct fuse_operations hello_oper = {
    .getattr    = hello_getattr,
    .readdir    = hello_readdir,
    .open       = hello_open,
    .read       = hello_read,
};

int main(int argc, char *argv[])
{
    int i;
	for(i = 1; i < argc && (argv[i][0] == '-'); i++)
    {
		if(i == argc)
        {
			return (-1);
		}
	}

    vfs = new loss::VirtualFileSystem();
    ramfs = new loss::RamFileSystem();
    vfs->root_filesystem(ramfs);
    const char *file_to_open = argv[i];
    {
        std::ifstream input(file_to_open);
        loss::RamFileSystemDeserialise deserialise(input, ramfs);
        deserialise.load();
    }

	for(; i < argc; i++)
    {
		argv[i] = argv[i+1];
	}
	argc--;
    auto result = fuse_main(argc, argv, &hello_oper, NULL);

    delete vfs;

    return result;
}
<commit_msg>- Added debug to lossfs, trying to get writing working.<commit_after>/*
  FUSE: Filesystem in Userspace
  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>

  This program can be distributed under the terms of the GNU GPL.
  See the file COPYING.

  gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello
*/

#define FUSE_USE_VERSION 30

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#include <iostream>
#include <fstream>
#include <loss/fs/virtual_fileystem.h>
#include <loss/fs/ram_filesystem.h>
#include <loss/fs/ram_filesystem_drive.h>

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";

static loss::VirtualFileSystem *vfs = nullptr;
static loss::RamFileSystem *ramfs = nullptr;

static int hello_getattr(const char *path, struct stat *stbuf)
{
    std::cout << "Getattr: " << path << "\n";
    int res = 0;

    memset(stbuf, 0, sizeof(struct stat));
    // Not really used at the moment
    stbuf->st_nlink = 1;
    /*
    if (strcmp(path, "/") == 0) {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 2;
    } else if (strcmp(path, hello_path) == 0) {
        stbuf->st_mode = S_IFREG | 0444;
        stbuf->st_nlink = 1;
        stbuf->st_size = strlen(hello_str);
    } else
        res = -ENOENT;
        */
    loss::MetadataDef metadata;
    auto read_result = vfs->entry_metadata(path, metadata);
    if (read_result != loss::SUCCESS)
    {
        res = -ENOENT;
    }
    else
    {
        if (metadata.type() == loss::FOLDER_ENTRY)
        {
            stbuf->st_mode = S_IFDIR | 0755;
        }
        else if (metadata.type() == loss::FILE_ENTRY)
        {
            stbuf->st_mode = S_IFREG | 0666;
            uint32_t size;
            vfs->entry_size(path, size);
            stbuf->st_size = size;
        }
    }

    return res;
}

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
             off_t offset, struct fuse_file_info *fi)
{
    std::cout << "Readdir: " << path << "\n";
    (void) offset;
    (void) fi;

    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);

    loss::FolderEntry folder;
    auto read_result = vfs->read_folder(path, folder);

    if (read_result == loss::SUCCESS)
    {
        for (auto &iter : folder)
        {
            filler(buf, iter.first.c_str(), NULL, 0);
        }
    }
    else
    {
        return -ENOENT;
    }

    return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi)
{
    std::cout << "Open: " << path << "\n";
    loss::MetadataDef metadata;
    if (vfs->entry_metadata(path, metadata) != loss::SUCCESS)
    {
        return -ENOENT;
    }

    return 0;
}

static int hello_read(const char *path, char *buf, size_t size, off_t offset,
              struct fuse_file_info *fi)
{
    std::cout << "Read: " << path << ": " << size << ": " << offset << "\n";
    auto read_result = vfs->read(path, offset, size, (uint8_t*)buf);
    if (read_result.status() != loss::SUCCESS)
    {
        return -ENOENT;
    }

    return read_result.bytes();
    /*
    size_t len;
    (void) fi;
    if(strcmp(path, hello_path) != 0)
        return -ENOENT;

    len = strlen(hello_str);
    if (offset < len) {
        if (offset + size > len)
            size = len - offset;
        memcpy(buf, hello_str + offset, size);
    } else
        size = 0;

    return size;
        */
}

static int hello_write(const char *path, const char *buf, size_t size, off_t off, struct fuse_file_info *fi)
{
    std::cout << "Write: " << path << ": " << size << ": " << off << "\n";
    auto write_result = vfs->write(path, off, size, (const uint8_t *)buf);
    return write_result.bytes();
}

static struct fuse_operations hello_oper = {
    .getattr    = hello_getattr,
    .readdir    = hello_readdir,
    .open       = hello_open,
    .read       = hello_read,
    .write      = hello_write,
};

int main(int argc, char *argv[])
{
    int i;
	for(i = 1; i < argc && (argv[i][0] == '-'); i++)
    {
		if(i == argc)
        {
			return (-1);
		}
	}

    vfs = new loss::VirtualFileSystem();
    ramfs = new loss::RamFileSystem();
    vfs->root_filesystem(ramfs);
    const char *file_to_open = argv[i];
    {
        std::ifstream input(file_to_open);
        loss::RamFileSystemDeserialise deserialise(input, ramfs);
        deserialise.load();
    }

	for(; i < argc; i++)
    {
		argv[i] = argv[i+1];
	}
	argc--;
    auto result = fuse_main(argc, argv, &hello_oper, NULL);

    delete vfs;

    return result;
}
<|endoftext|>


<commit_before>/*
 * DynApproxBetweenness.cpp
 *
 *  Created on: 31.07.2014
 *      Author: ebergamini
 */

#include "DynApproxBetweenness.h"
#include "../auxiliary/Random.h"
#include "../properties/Diameter.h"
#include "../graph/Sampling.h"
#include "../graph/DynDijkstra.h"
#include "../graph/DynBFS.h"
#include "../auxiliary/Log.h"
#include "../auxiliary/NumericTools.h"

namespace NetworKit {

DynApproxBetweenness::DynApproxBetweenness(const Graph& G, double epsilon, double delta, bool storePredecessors) : Centrality(G, true),
storePreds(storePredecessors), epsilon(epsilon), delta(delta) {

}

count DynApproxBetweenness::getNumberOfSamples() {
    return r;
}

void DynApproxBetweenness::run() {
    if (G.isDirected()) {
        throw std::runtime_error("Invalid argument: G must be undirected.");
    }
    scoreData.clear();
    scoreData.resize(G.upperNodeIdBound());
    u.clear();
    v.clear();
    sampledPaths.clear();

    double c = 0.5; // universal positive constant - see reference in paper

    edgeweight vd = Diameter::estimatedVertexDiameterPedantic(G);

    INFO("estimated diameter: ", vd);
    r = ceil((c / (epsilon * epsilon)) * (floor(log(vd - 2)) + 1 + log(1 / delta)));
    INFO("taking ", r, " path samples");
    sssp.clear();
    sssp.resize(r);
    u.resize(r);
    v.resize(r);
    sampledPaths.resize(r);

    for (count i = 0; i < r; i++) {
        DEBUG("sample ", i);
        // sample random node pair
        u[i] = Sampling::randomNode(G);
        do {
            v[i] = Sampling::randomNode(G);
        } while (v[i] == u[i]);
        if (G.isWeighted()) {
            sssp[i].reset(new DynDijkstra(G, u[i], storePreds));
        } else {
            sssp[i].reset(new DynBFS(G, u[i], storePreds));
        }
        DEBUG("running shortest path algorithm for node ", u[i]);
        sssp[i]->setTargetNode(v[i]);
        sssp[i]->run();
        if (sssp[i]->distances[v[i]] > 0) { // at least one path between {u, v} exists
            DEBUG("updating estimate for path ", u[i], " <-> ", v[i]);
            // random path sampling and estimation update
            sampledPaths[i].clear();
            node t = v[i];
            while (t != u[i])  {
                // sample z in P_u(t) with probability sigma_uz / sigma_us
                std::vector<std::pair<node, double> > choices;
                if (storePreds) {
                    for (node z : sssp[i]->previous[t]) {
                        // workaround for integer overflow in large graphs
                        bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                        double weight;
                        tmp.ToDouble(weight);

                        choices.emplace_back(z, weight); 	// sigma_uz / sigma_us
                    }
                }
                else {
                G.forInEdgesOf(t, [&](node t, node z, edgeweight w){
                        if (Aux::NumericTools::logically_equal(sssp[i]->distances[t], sssp[i]->distances[z] + w)) {
                            // workaround for integer overflow in large graphs
                            bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                            double weight;
                            tmp.ToDouble(weight);

                            choices.emplace_back(z, weight);
                        }

                    });
                }
                INFO("Node considered: ", t);
                INFO("Source considered: ", u[i]);
                assert (choices.size() > 0);
                node z = Aux::Random::weightedChoice(choices);
                assert (z <= G.upperNodeIdBound());
                if (z != u[i]) {
                    scoreData[z] += 1 / (double) r;
                    sampledPaths[i].push_back(z);
                }
                t = z;
            }
        }
    }

}

void DynApproxBetweenness::update(const std::vector<GraphEvent>& batch) {
    INFO ("Updating");
    for (node i = 0; i < r; i++) {
        sssp[i]->update(batch);
        if (sssp[i]->modified()) {
            // subtract contributions to nodes in the old sampled path
            for (node z: sampledPaths[i]) {
                scoreData[z] -= 1 / (double) r;
            }
            // sample a new shortest path
            sampledPaths[i].clear();
            node t = v[i];
            while (t != u[i])  {
                // sample z in P_u(t) with probability sigma_uz / sigma_us
                std::vector<std::pair<node, double> > choices;
                if (storePreds) {
                    for (node z : sssp[i]->previous[t]) {
                        // workaround for integer overflow in large graphs
                        bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                        double weight;
                        tmp.ToDouble(weight);

                        choices.emplace_back(z, weight);
                    }
                }
                else {
                    G.forEdgesOf(t, [&](node t, node z, edgeweight w){
                        if (Aux::NumericTools::logically_equal(sssp[i]->distances[t], sssp[i]->distances[z] + w)) {
                            // workaround for integer overflow in large graphs
                            bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                            double weight;
                            tmp.ToDouble(weight);

                            choices.emplace_back(z, weight);
                        }
                    });
                }
                assert (choices.size() > 0); // this should fail only if the graph is not connected
                if (choices.size() == 0) {
                    INFO ("node: ", t);
                    INFO ("source: ", u[i]);
                    INFO ("distance: ", sssp[i]->distances[t]);
                }
                node z = Aux::Random::weightedChoice(choices);
                assert (z <= G.upperNodeIdBound());
                if (z != u[i]) {
                    scoreData[z] += 1 / (double) r;
                    sampledPaths[i].push_back(z);
                }
                t = z;
            }

        }

    }
}

} /* namespace NetworKit */
<commit_msg>replaced forInEdges with forEdges in dyn approx betweenness<commit_after>/*
 * DynApproxBetweenness.cpp
 *
 *  Created on: 31.07.2014
 *      Author: ebergamini
 */

#include "DynApproxBetweenness.h"
#include "../auxiliary/Random.h"
#include "../properties/Diameter.h"
#include "../graph/Sampling.h"
#include "../graph/DynDijkstra.h"
#include "../graph/DynBFS.h"
#include "../auxiliary/Log.h"
#include "../auxiliary/NumericTools.h"

namespace NetworKit {

DynApproxBetweenness::DynApproxBetweenness(const Graph& G, double epsilon, double delta, bool storePredecessors) : Centrality(G, true),
storePreds(storePredecessors), epsilon(epsilon), delta(delta) {

}

count DynApproxBetweenness::getNumberOfSamples() {
    return r;
}

void DynApproxBetweenness::run() {
    if (G.isDirected()) {
        throw std::runtime_error("Invalid argument: G must be undirected.");
    }
    scoreData.clear();
    scoreData.resize(G.upperNodeIdBound());
    u.clear();
    v.clear();
    sampledPaths.clear();

    double c = 0.5; // universal positive constant - see reference in paper

    edgeweight vd = Diameter::estimatedVertexDiameterPedantic(G);

    INFO("estimated diameter: ", vd);
    r = ceil((c / (epsilon * epsilon)) * (floor(log(vd - 2)) + 1 + log(1 / delta)));
    INFO("taking ", r, " path samples");
    sssp.clear();
    sssp.resize(r);
    u.resize(r);
    v.resize(r);
    sampledPaths.resize(r);

    for (count i = 0; i < r; i++) {
        DEBUG("sample ", i);
        // sample random node pair
        u[i] = Sampling::randomNode(G);
        do {
            v[i] = Sampling::randomNode(G);
        } while (v[i] == u[i]);
        if (G.isWeighted()) {
            sssp[i].reset(new DynDijkstra(G, u[i], storePreds));
        } else {
            sssp[i].reset(new DynBFS(G, u[i], storePreds));
        }
        DEBUG("running shortest path algorithm for node ", u[i]);
        sssp[i]->setTargetNode(v[i]);
        sssp[i]->run();
        if (sssp[i]->distances[v[i]] > 0) { // at least one path between {u, v} exists
            DEBUG("updating estimate for path ", u[i], " <-> ", v[i]);
            // random path sampling and estimation update
            sampledPaths[i].clear();
            node t = v[i];
            while (t != u[i])  {
                // sample z in P_u(t) with probability sigma_uz / sigma_us
                std::vector<std::pair<node, double> > choices;
                if (storePreds) {
                    for (node z : sssp[i]->previous[t]) {
                        // workaround for integer overflow in large graphs
                        bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                        double weight;
                        tmp.ToDouble(weight);

                        choices.emplace_back(z, weight); 	// sigma_uz / sigma_us
                    }
                }
                else {
                G.forEdgesOf(t, [&](node t, node z, edgeweight w){
                        if (Aux::NumericTools::logically_equal(sssp[i]->distances[t], sssp[i]->distances[z] + w)) {
                            // workaround for integer overflow in large graphs
                            bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                            double weight;
                            tmp.ToDouble(weight);

                            choices.emplace_back(z, weight);
                        }

                    });
                }
                INFO("Node considered: ", t);
                INFO("Source considered: ", u[i]);
                assert (choices.size() > 0);
                node z = Aux::Random::weightedChoice(choices);
                assert (z <= G.upperNodeIdBound());
                if (z != u[i]) {
                    scoreData[z] += 1 / (double) r;
                    sampledPaths[i].push_back(z);
                }
                t = z;
            }
        }
    }

}

void DynApproxBetweenness::update(const std::vector<GraphEvent>& batch) {
    INFO ("Updating");
    for (node i = 0; i < r; i++) {
        sssp[i]->update(batch);
        if (sssp[i]->modified()) {
            // subtract contributions to nodes in the old sampled path
            for (node z: sampledPaths[i]) {
                scoreData[z] -= 1 / (double) r;
            }
            // sample a new shortest path
            sampledPaths[i].clear();
            node t = v[i];
            while (t != u[i])  {
                // sample z in P_u(t) with probability sigma_uz / sigma_us
                std::vector<std::pair<node, double> > choices;
                if (storePreds) {
                    for (node z : sssp[i]->previous[t]) {
                        // workaround for integer overflow in large graphs
                        bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                        double weight;
                        tmp.ToDouble(weight);

                        choices.emplace_back(z, weight);
                    }
                }
                else {
                    G.forEdgesOf(t, [&](node t, node z, edgeweight w){
                        if (Aux::NumericTools::logically_equal(sssp[i]->distances[t], sssp[i]->distances[z] + w)) {
                            // workaround for integer overflow in large graphs
                            bigfloat tmp = sssp[i]->numberOfPaths(z) / sssp[i]->numberOfPaths(t);
                            double weight;
                            tmp.ToDouble(weight);

                            choices.emplace_back(z, weight);
                        }
                    });
                }
                assert (choices.size() > 0); // this should fail only if the graph is not connected
                if (choices.size() == 0) {
                    INFO ("node: ", t);
                    INFO ("source: ", u[i]);
                    INFO ("distance: ", sssp[i]->distances[t]);
                }
                node z = Aux::Random::weightedChoice(choices);
                assert (z <= G.upperNodeIdBound());
                if (z != u[i]) {
                    scoreData[z] += 1 / (double) r;
                    sampledPaths[i].push_back(z);
                }
                t = z;
            }

        }

    }
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *                2019  Nina Engelhardt <nak@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct ScratchpadPass : public Pass {
	ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    scratchpad [options]\n");
		log("\n");
		log("This pass allows to read and modify values from the scratchpad of the current\n");
		log("design. Options:\n");
		log("    -get <identifier>\n");
		log("        print the value saved in the scratchpad under the given identifier\n");
		log("    -set <identifier> <value>\n");
		log("        save the given value in the scratchpad under the given identifier\n");
		log("    -unset <identifier>\n");
		log("        remove the entry for the given identifier from the scratchpad\n");
		log("    -copy <identifier_from> <identifier_to>\n");
		log("        copy the value of the first identifier to the second identifier\n");
		log("The identifier may not contain whitespace. By convention, it is usually prefixed\n");
		log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n");
		log("contains whitespace, it must be enclosed in double quotes.\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-get" && argidx+1 < args.size()) {
				string identifier = args[++argidx];
				if (design->scratchpad.count(identifier)){
					log("%s\n", design->scratchpad_get_string(identifier).c_str());
				} else {
					log("\"%s\" not set\n", identifier.c_str());
				}
				continue;
			}
			if (args[argidx] == "-set" && argidx+2 < args.size()) {
				string identifier = args[++argidx];
				string value = args[++argidx];
				if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2);
				design->scratchpad_set_string(identifier, value);
				continue;
			}
			if (args[argidx] == "-unset" && argidx+1 < args.size()) {
				string identifier = args[++argidx];
				design->scratchpad_unset(identifier);
				continue;
			}
			if (args[argidx] == "-copy" && argidx+2 < args.size()) {
				string identifier_from = args[++argidx];
				string identifier_to = args[++argidx];
				if (design->scratchpad.count(identifier_from) == 0) log_error("\"%s\" not set\n", identifier_from.c_str());
				string value = design->scratchpad_get_string(identifier_from);
				design->scratchpad_set_string(identifier_to, value);
				continue;
			}
			log("Unrecognized argument: %s\n", args[argidx].c_str());
			break;
		}
	}
} ScratchpadPass;
PRIVATE_NAMESPACE_END
<commit_msg>add periods and newlines to help message<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *                2019  Nina Engelhardt <nak@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct ScratchpadPass : public Pass {
	ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    scratchpad [options]\n");
		log("\n");
		log("This pass allows to read and modify values from the scratchpad of the current\n");
		log("design. Options:\n\n");
		log("    -get <identifier>\n");
		log("        print the value saved in the scratchpad under the given identifier.\n\n");
		log("    -set <identifier> <value>\n");
		log("        save the given value in the scratchpad under the given identifier.\n\n");
		log("    -unset <identifier>\n");
		log("        remove the entry for the given identifier from the scratchpad.\n\n");
		log("    -copy <identifier_from> <identifier_to>\n");
		log("        copy the value of the first identifier to the second identifier.\n\n");
		log("The identifier may not contain whitespace. By convention, it is usually prefixed\n");
		log("by the name of the pass that uses it, e.g. 'opt.did_something'. If the value\n");
		log("contains whitespace, it must be enclosed in double quotes.\n");
		log("\n");
	}

	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-get" && argidx+1 < args.size()) {
				string identifier = args[++argidx];
				if (design->scratchpad.count(identifier)){
					log("%s\n", design->scratchpad_get_string(identifier).c_str());
				} else {
					log("\"%s\" not set\n", identifier.c_str());
				}
				continue;
			}
			if (args[argidx] == "-set" && argidx+2 < args.size()) {
				string identifier = args[++argidx];
				string value = args[++argidx];
				if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2);
				design->scratchpad_set_string(identifier, value);
				continue;
			}
			if (args[argidx] == "-unset" && argidx+1 < args.size()) {
				string identifier = args[++argidx];
				design->scratchpad_unset(identifier);
				continue;
			}
			if (args[argidx] == "-copy" && argidx+2 < args.size()) {
				string identifier_from = args[++argidx];
				string identifier_to = args[++argidx];
				if (design->scratchpad.count(identifier_from) == 0) log_error("\"%s\" not set\n", identifier_from.c_str());
				string value = design->scratchpad_get_string(identifier_from);
				design->scratchpad_set_string(identifier_to, value);
				continue;
			}
			log("Unrecognized argument: %s\n", args[argidx].c_str());
			break;
		}
	}
} ScratchpadPass;
PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2018  whitequark <whitequark@whitequark.org>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct EquivOptPass:public ScriptPass
{
	EquivOptPass() : ScriptPass("equiv_opt", "prove equivalence for optimized circuit") { }

	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    equiv_opt [options] [command]\n");
		log("\n");
		log("This command checks circuit equivalence before and after an optimization pass.\n");
		log("\n");
		log("    -run <from_label>:<to_label>\n");
		log("        only run the commands between the labels (see below). an empty\n");
		log("        from label is synonymous to the start of the command list, and empty to\n");
		log("        label is synonymous to the end of the command list.\n");
		log("\n");
		log("    -map <filename>\n");
		log("        expand the modules in this file before proving equivalence. this is\n");
		log("        useful for handling architecture-specific primitives.\n");
		log("\n");
		log("    -assert\n");
		log("        produce an error if the circuits are not equivalent.\n");
		log("\n");
		log("    -multiclock\n");
		log("        run clk2fflogic before equivalence checking.\n");
		log("\n");
		log("    -undef\n");
		log("        enable modelling of undef states during equiv_induct.\n");
		log("\n");
		log("The following commands are executed by this verification command:\n");
		help_script();
		log("\n");
	}

	std::string command, techmap_opts;
	bool assert, undef, multiclock;

	void clear_flags() YS_OVERRIDE
	{
		command = "";
		techmap_opts = "";
		assert = false;
		undef = false;
		multiclock = false;
	}

	void execute(std::vector < std::string > args, RTLIL::Design * design) YS_OVERRIDE
	{
		string run_from, run_to;
		clear_flags();

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-run" && argidx + 1 < args.size()) {
				size_t pos = args[argidx + 1].find(':');
				if (pos == std::string::npos)
					break;
				run_from = args[++argidx].substr(0, pos);
				run_to = args[argidx].substr(pos + 1);
				continue;
			}
			if (args[argidx] == "-map" && argidx + 1 < args.size()) {
				techmap_opts += " -map " + args[++argidx];
				continue;
			}
			if (args[argidx] == "-assert") {
				assert = true;
				continue;
			}
			if (args[argidx] == "-undef") {
				undef = true;
				continue;
			}
			if (args[argidx] == "-multiclock") {
				multiclock = true;
				continue;
			}
			break;
		}

		for (; argidx < args.size(); argidx++) {
			if (command.empty()) {
				if (args[argidx].compare(0, 1, "-") == 0)
					cmd_error(args, argidx, "Unknown option.");
			} else {
				command += " ";
			}
			command += args[argidx];
		}

		if (command.empty())
			log_cmd_error("No optimization pass specified!\n");

		if (!design->full_selection())
			log_cmd_error("This command only operates on fully selected designs!\n");

		log_header(design, "Executing EQUIV_OPT pass.\n");
		log_push();

		run_script(design, run_from, run_to);

		log_pop();
	}

	void script() YS_OVERRIDE
	{
		if (check_label("run_pass")) {
			run("hierarchy -auto-top");
			run("design -save preopt");
			if (help_mode)
				run("[command]");
			else
				run(command);
			run("design -stash postopt");
		}

		if (check_label("prepare")) {
			run("design -copy-from preopt  -as gold A:top");
			run("design -copy-from postopt -as gate A:top");
		}

		if ((!techmap_opts.empty() || help_mode) && check_label("techmap", "(only with -map)")) {
			string opts;
			if (help_mode)
				opts = " -map <filename> ...";
			else
				opts = techmap_opts;
			run("techmap -wb -D EQUIV -autoproc" + opts);
		}

		if (check_label("prove")) {
			if (multiclock || help_mode)
				run("clk2fflogic", "(only with -multiclock)");
			run("equiv_make gold gate equiv");
			if (help_mode)
				run("equiv_induct [-undef] equiv");
			else if (undef)
				run("equiv_induct -undef equiv");
			else
				run("equiv_induct equiv");
			if (help_mode)
				run("equiv_status [-assert] equiv");
			else if (assert)
				run("equiv_status -assert equiv");
			else
				run("equiv_status equiv");
		}

		if (check_label("restore")) {
			run("design -load preopt");
		}
	}
} EquivOptPass;

PRIVATE_NAMESPACE_END
<commit_msg>Add new -async2sync option<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2018  whitequark <whitequark@whitequark.org>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct EquivOptPass:public ScriptPass
{
	EquivOptPass() : ScriptPass("equiv_opt", "prove equivalence for optimized circuit") { }

	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    equiv_opt [options] [command]\n");
		log("\n");
		log("This command checks circuit equivalence before and after an optimization pass.\n");
		log("\n");
		log("    -run <from_label>:<to_label>\n");
		log("        only run the commands between the labels (see below). an empty\n");
		log("        from label is synonymous to the start of the command list, and empty to\n");
		log("        label is synonymous to the end of the command list.\n");
		log("\n");
		log("    -map <filename>\n");
		log("        expand the modules in this file before proving equivalence. this is\n");
		log("        useful for handling architecture-specific primitives.\n");
		log("\n");
		log("    -assert\n");
		log("        produce an error if the circuits are not equivalent.\n");
		log("\n");
		log("    -multiclock\n");
		log("        run clk2fflogic before equivalence checking.\n");
		log("\n");
		log("    -undef\n");
		log("        enable modelling of undef states during equiv_induct.\n");
		log("\n");
		log("The following commands are executed by this verification command:\n");
		help_script();
		log("\n");
	}

	std::string command, techmap_opts;
	bool assert, undef, multiclock, async2sync;

	void clear_flags() YS_OVERRIDE
	{
		command = "";
		techmap_opts = "";
		assert = false;
		undef = false;
		multiclock = false;
		async2sync = false;
	}

	void execute(std::vector < std::string > args, RTLIL::Design * design) YS_OVERRIDE
	{
		string run_from, run_to;
		clear_flags();

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-run" && argidx + 1 < args.size()) {
				size_t pos = args[argidx + 1].find(':');
				if (pos == std::string::npos)
					break;
				run_from = args[++argidx].substr(0, pos);
				run_to = args[argidx].substr(pos + 1);
				continue;
			}
			if (args[argidx] == "-map" && argidx + 1 < args.size()) {
				techmap_opts += " -map " + args[++argidx];
				continue;
			}
			if (args[argidx] == "-assert") {
				assert = true;
				continue;
			}
			if (args[argidx] == "-undef") {
				undef = true;
				continue;
			}
			if (args[argidx] == "-multiclock") {
				multiclock = true;
				continue;
			}
			if (args[argidx] == "-async2sync") {
				async2sync = true;
				continue;
			}
			break;
		}

		for (; argidx < args.size(); argidx++) {
			if (command.empty()) {
				if (args[argidx].compare(0, 1, "-") == 0)
					cmd_error(args, argidx, "Unknown option.");
			} else {
				command += " ";
			}
			command += args[argidx];
		}

		if (command.empty())
			log_cmd_error("No optimization pass specified!\n");

		if (!design->full_selection())
			log_cmd_error("This command only operates on fully selected designs!\n");

		if (async2sync && multiclock)
			log_cmd_error("The '-async2sync' and '-multiclock' options are mutually exclusive!\n");

		log_header(design, "Executing EQUIV_OPT pass.\n");
		log_push();

		run_script(design, run_from, run_to);

		log_pop();
	}

	void script() YS_OVERRIDE
	{
		if (check_label("run_pass")) {
			run("hierarchy -auto-top");
			run("design -save preopt");
			if (help_mode)
				run("[command]");
			else
				run(command);
			run("design -stash postopt");
		}

		if (check_label("prepare")) {
			run("design -copy-from preopt  -as gold A:top");
			run("design -copy-from postopt -as gate A:top");
		}

		if ((!techmap_opts.empty() || help_mode) && check_label("techmap", "(only with -map)")) {
			string opts;
			if (help_mode)
				opts = " -map <filename> ...";
			else
				opts = techmap_opts;
			run("techmap -wb -D EQUIV -autoproc" + opts);
		}

		if (check_label("prove")) {
			if (multiclock || help_mode)
				run("clk2fflogic", "(only with -multiclock)");
			if (async2sync || help_mode)
				run("async2sync", "(only with -async2sync)");
			run("equiv_make gold gate equiv");
			if (help_mode)
				run("equiv_induct [-undef] equiv");
			else if (undef)
				run("equiv_induct -undef equiv");
			else
				run("equiv_induct equiv");
			if (help_mode)
				run("equiv_status [-assert] equiv");
			else if (assert)
				run("equiv_status -assert equiv");
			else
				run("equiv_status equiv");
		}

		if (check_label("restore")) {
			run("design -load preopt");
		}
	}
} EquivOptPass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mvdGLImageWidget.h"

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
//#include <QKeyEvent>
//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)
#include "itkImageRegionConstIteratorWithIndex.h"

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdAbstractImageModel.h"
#include "mvdApplication.h"
#include "mvdDatasetModel.h"

namespace mvd
{
/*
  TRANSLATOR mvd::GLImageWidget

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*******************************************************************************/
GLImageWidget
::GLImageWidget( AbstractViewManipulator * manipulator,
                 AbstractModelRenderer * renderer,
                 QWidget* parent,
		 const QGLWidget* shareWidget,
		 Qt::WindowFlags flags ) :
  QGLWidget( parent, shareWidget, flags ),
  m_ImageViewManipulator( NULL ),
  m_ImageModelRenderer( NULL ),
  m_ImageModel( NULL )
{
  // Set focus policy so that the widget gets the focus if it is clicked
  setFocusPolicy(Qt::StrongFocus);
  Initialize(manipulator, renderer);
}

/*******************************************************************************/
GLImageWidget
::GLImageWidget( AbstractViewManipulator * manipulator,
                 AbstractModelRenderer * renderer,
                 QGLContext* context,
		 QWidget* parent,
		 const QGLWidget* shareWidget,
		 Qt::WindowFlags flags ) :
  QGLWidget( context, parent, shareWidget, flags ),
  m_ImageViewManipulator( NULL ),
  m_ImageModelRenderer( NULL ),
  m_ImageModel( NULL )
{
  // Set focus policy so that the widget gets the focus if it is clicked
  setFocusPolicy(Qt::StrongFocus);

  Initialize(manipulator, renderer);
}

/*******************************************************************************/
GLImageWidget
::GLImageWidget( AbstractViewManipulator * manipulator,
                 AbstractModelRenderer * renderer,
                 const QGLFormat& format,
                 QWidget* parent,
                 const QGLWidget* shareWidget,
                 Qt::WindowFlags flags ) :
  QGLWidget( format, parent, shareWidget, flags ),
  m_ImageViewManipulator( NULL ),
  m_ImageModelRenderer( NULL ),
  m_ImageModel( NULL )
{
  // Set focus policy so that the widget gets the focus if it is clicked
  setFocusPolicy(Qt::StrongFocus);

  Initialize(manipulator, renderer);
}

/*******************************************************************************/
GLImageWidget
::~GLImageWidget()
{
  // m_ImageViewManipulator (deleted as a child of a QObjet parent).
  // m_ImageModelRenderer (deleted as a child of a QObjet parent).
}

/*******************************************************************************/
void
GLImageWidget
::Initialize( AbstractViewManipulator* manipulator,
	      AbstractModelRenderer* renderer )
{
  assert( manipulator!=NULL );
  assert( renderer!=NULL );

  m_ImageViewManipulator = manipulator;
  m_ImageViewManipulator->setParent(this);

  m_ImageModelRenderer = renderer;
  m_ImageModelRenderer->setParent(this);

  QObject::connect(
    this, SIGNAL( movingMouse() ),
    m_ImageModelRenderer, SLOT( onMovingEvent() )
  );

  QObject::connect(
    this, SIGNAL( releasingMouse() ),
    m_ImageModelRenderer, SLOT(onReleasedMouse())
  );

  // Connect this model region changed.
  QObject::connect(
    this,
    SIGNAL( ModelImageRegionChanged( const ImageRegionType& , const SpacingType&) ),
    // to:
    m_ImageViewManipulator,
    SLOT( OnModelImageRegionChanged( const ImageRegionType&, const SpacingType& ) )
  );

  // Connect the renderer origin (of extent) changed to the manipulator
  QObject::connect(
    m_ImageModelRenderer,
    SIGNAL( ViewportOriginChanged( const IndexType& ) ),
    // to:
    m_ImageViewManipulator,
    SLOT( OnViewportOriginChanged( const IndexType&) )
  );

}

/*******************************************************************************/
void
GLImageWidget
::initializeGL()
{
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glShadeModel(GL_FLAT);
}

/*******************************************************************************/
void
GLImageWidget
::resizeGL(int width, int height)
{
  // TODO: Replace (GLint) casts with safer casts or no cast (if there is no compile-time warning).
  glViewport(0, 0, (GLint)width, (GLint)height);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, (GLint)width, 0, (GLint)height, -1, 1);
}

/*******************************************************************************/
void
GLImageWidget
::paintGL()
{
  // Clear back-buffer(s) before rendering sub-components.
  glClear( GL_COLOR_BUFFER_BIT );

  // Get the region to draw from the ImageViewManipulator navigation
  // context.
  const ImageRegionType region(
    m_ImageViewManipulator->GetViewportImageRegion() );

  // Get the zoom
  const double isotropicZoom = m_ImageViewManipulator->GetIsotropicZoom();

  // Setup rendering context with image-model and redering information.
  AbstractModelRenderer::RenderingContext context(
    m_ImageModel,
    region, isotropicZoom,
    width(), height(),
    m_ImageViewManipulator->HasZoomChanged()
  );

    // use the model renderer to paint the requested region of the image.
  m_ImageModelRenderer->paintGL( context );
}

/*******************************************************************************/
// Delegate the event to the ImageViewManipulator
void
GLImageWidget
::mousePressEvent( QMouseEvent* event )
{
  QCursor dragCursor;
  dragCursor.setShape(Qt::ClosedHandCursor) ;
  this->setCursor(dragCursor);

  //
  m_ImageViewManipulator->mousePressEvent(event);
  this->update();
}

/*******************************************************************************/
void
GLImageWidget
::mouseMoveEvent( QMouseEvent* event )
{
  // if a button is clicked == drag
  if ( event->buttons() & Qt::LeftButton  ||
       event->buttons() & Qt::RightButton ||
       event->buttons() & Qt::MidButton   ||
       event->buttons() & Qt::XButton1    ||
       event->buttons() & Qt::XButton2 )
    {
    // emit a signal movingMouse to update the renderer status
    emit movingMouse();

    // drag detected
    m_ImageViewManipulator->mouseMoveEvent(event);

    // repaint the buffer
    this->update();

    // emited to update to force the ql widget (if any) to update
    emit CentralWidgetUpdated();
    }
  else // just mouse cursor moving
    {
    // no mouse button is grabbed here -> no drag detected
    m_ImageViewManipulator->PropagatePointUnderCursorCoordinates(event->pos());
    }
}

/*******************************************************************************/
void
GLImageWidget
::mouseReleaseEvent( QMouseEvent* event )
{
  QCursor stdCursor;
  stdCursor.setShape(Qt::ArrowCursor) ;
  this->setCursor(stdCursor);

  // emit a signal releasingMouse to update the renderer status
  emit releasingMouse();

  // call paintGL
  this->update();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
void
GLImageWidget
::wheelEvent( QWheelEvent* event )
{
  // emit a signal releasingMouse to update the renderer status
  emit releasingMouse();

  m_ImageViewManipulator->wheelEvent(event);

  // repaint the buffer
  this->update();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
void
GLImageWidget
::resizeEvent( QResizeEvent* event )
{
  // First, call superclass implementation
  QGLWidget::resizeEvent(event);

  m_ImageViewManipulator->resizeEvent(event);

  // emit a signal releasingMouse to update the renderer status
  emit releasingMouse();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
void
GLImageWidget
::keyPressEvent( QKeyEvent* event )
{
  m_ImageViewManipulator->keyPressEvent(event);
  this->update();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
/* SLOTS                                                                       */
/******************************************************************************/
void
GLImageWidget
::OnSpacingChanged(const SpacingType& spacing)
{
  m_ImageViewManipulator->SetSpacing(spacing);
}
/*******************************************************************************/

}
<commit_msg>ENH: enable receiving mouse move events even if no button is pressed<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mvdGLImageWidget.h"

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
//#include <QKeyEvent>
//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)
#include "itkImageRegionConstIteratorWithIndex.h"

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdAbstractImageModel.h"
#include "mvdApplication.h"
#include "mvdDatasetModel.h"

namespace mvd
{
/*
  TRANSLATOR mvd::GLImageWidget

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*******************************************************************************/
GLImageWidget
::GLImageWidget( AbstractViewManipulator * manipulator,
                 AbstractModelRenderer * renderer,
                 QWidget* parent,
		 const QGLWidget* shareWidget,
		 Qt::WindowFlags flags ) :
  QGLWidget( parent, shareWidget, flags ),
  m_ImageViewManipulator( NULL ),
  m_ImageModelRenderer( NULL ),
  m_ImageModel( NULL )
{
  // Set focus policy so that the widget gets the focus if it is clicked
  setMouseTracking(true);
  setFocusPolicy(Qt::StrongFocus);
  Initialize(manipulator, renderer);
}

/*******************************************************************************/
GLImageWidget
::GLImageWidget( AbstractViewManipulator * manipulator,
                 AbstractModelRenderer * renderer,
                 QGLContext* context,
		 QWidget* parent,
		 const QGLWidget* shareWidget,
		 Qt::WindowFlags flags ) :
  QGLWidget( context, parent, shareWidget, flags ),
  m_ImageViewManipulator( NULL ),
  m_ImageModelRenderer( NULL ),
  m_ImageModel( NULL )
{
  // Set focus policy so that the widget gets the focus if it is clicked
  setMouseTracking(true);
  setFocusPolicy(Qt::StrongFocus);

  Initialize(manipulator, renderer);
}

/*******************************************************************************/
GLImageWidget
::GLImageWidget( AbstractViewManipulator * manipulator,
                 AbstractModelRenderer * renderer,
                 const QGLFormat& format,
                 QWidget* parent,
                 const QGLWidget* shareWidget,
                 Qt::WindowFlags flags ) :
  QGLWidget( format, parent, shareWidget, flags ),
  m_ImageViewManipulator( NULL ),
  m_ImageModelRenderer( NULL ),
  m_ImageModel( NULL )
{
  // Set focus policy so that the widget gets the focus if it is clicked
  setMouseTracking(true);
  setFocusPolicy(Qt::StrongFocus);

  Initialize(manipulator, renderer);
}

/*******************************************************************************/
GLImageWidget
::~GLImageWidget()
{
  // m_ImageViewManipulator (deleted as a child of a QObjet parent).
  // m_ImageModelRenderer (deleted as a child of a QObjet parent).
}

/*******************************************************************************/
void
GLImageWidget
::Initialize( AbstractViewManipulator* manipulator,
	      AbstractModelRenderer* renderer )
{
  assert( manipulator!=NULL );
  assert( renderer!=NULL );

  m_ImageViewManipulator = manipulator;
  m_ImageViewManipulator->setParent(this);

  m_ImageModelRenderer = renderer;
  m_ImageModelRenderer->setParent(this);

  QObject::connect(
    this, SIGNAL( movingMouse() ),
    m_ImageModelRenderer, SLOT( onMovingEvent() )
  );

  QObject::connect(
    this, SIGNAL( releasingMouse() ),
    m_ImageModelRenderer, SLOT(onReleasedMouse())
  );

  // Connect this model region changed.
  QObject::connect(
    this,
    SIGNAL( ModelImageRegionChanged( const ImageRegionType& , const SpacingType&) ),
    // to:
    m_ImageViewManipulator,
    SLOT( OnModelImageRegionChanged( const ImageRegionType&, const SpacingType& ) )
  );

  // Connect the renderer origin (of extent) changed to the manipulator
  QObject::connect(
    m_ImageModelRenderer,
    SIGNAL( ViewportOriginChanged( const IndexType& ) ),
    // to:
    m_ImageViewManipulator,
    SLOT( OnViewportOriginChanged( const IndexType&) )
  );

}

/*******************************************************************************/
void
GLImageWidget
::initializeGL()
{
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glShadeModel(GL_FLAT);
}

/*******************************************************************************/
void
GLImageWidget
::resizeGL(int width, int height)
{
  // TODO: Replace (GLint) casts with safer casts or no cast (if there is no compile-time warning).
  glViewport(0, 0, (GLint)width, (GLint)height);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, (GLint)width, 0, (GLint)height, -1, 1);
}

/*******************************************************************************/
void
GLImageWidget
::paintGL()
{
  // Clear back-buffer(s) before rendering sub-components.
  glClear( GL_COLOR_BUFFER_BIT );

  // Get the region to draw from the ImageViewManipulator navigation
  // context.
  const ImageRegionType region(
    m_ImageViewManipulator->GetViewportImageRegion() );

  // Get the zoom
  const double isotropicZoom = m_ImageViewManipulator->GetIsotropicZoom();

  // Setup rendering context with image-model and redering information.
  AbstractModelRenderer::RenderingContext context(
    m_ImageModel,
    region, isotropicZoom,
    width(), height(),
    m_ImageViewManipulator->HasZoomChanged()
  );

    // use the model renderer to paint the requested region of the image.
  m_ImageModelRenderer->paintGL( context );
}

/*******************************************************************************/
// Delegate the event to the ImageViewManipulator
void
GLImageWidget
::mousePressEvent( QMouseEvent* event )
{
  QCursor dragCursor;
  dragCursor.setShape(Qt::ClosedHandCursor) ;
  this->setCursor(dragCursor);

  //
  m_ImageViewManipulator->mousePressEvent(event);
  this->update();
}

/*******************************************************************************/
void
GLImageWidget
::mouseMoveEvent( QMouseEvent* event )
{
  // if a button is clicked == drag
  if ( event->buttons() & Qt::LeftButton  ||
       event->buttons() & Qt::RightButton ||
       event->buttons() & Qt::MidButton   ||
       event->buttons() & Qt::XButton1    ||
       event->buttons() & Qt::XButton2 )
    {
    // emit a signal movingMouse to update the renderer status
    emit movingMouse();

    // drag detected
    m_ImageViewManipulator->mouseMoveEvent(event);

    // repaint the buffer
    this->update();

    // emited to update to force the ql widget (if any) to update
    emit CentralWidgetUpdated();
    }
  else // just mouse cursor moving
    {
    // no mouse button is grabbed here -> no drag detected
    m_ImageViewManipulator->PropagatePointUnderCursorCoordinates(event->pos());
    }
}

/*******************************************************************************/
void
GLImageWidget
::mouseReleaseEvent( QMouseEvent* event )
{
  QCursor stdCursor;
  stdCursor.setShape(Qt::ArrowCursor) ;
  this->setCursor(stdCursor);

  // emit a signal releasingMouse to update the renderer status
  emit releasingMouse();

  // call paintGL
  this->update();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
void
GLImageWidget
::wheelEvent( QWheelEvent* event )
{
  // emit a signal releasingMouse to update the renderer status
  emit releasingMouse();

  m_ImageViewManipulator->wheelEvent(event);

  // repaint the buffer
  this->update();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
void
GLImageWidget
::resizeEvent( QResizeEvent* event )
{
  // First, call superclass implementation
  QGLWidget::resizeEvent(event);

  m_ImageViewManipulator->resizeEvent(event);

  // emit a signal releasingMouse to update the renderer status
  emit releasingMouse();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
void
GLImageWidget
::keyPressEvent( QKeyEvent* event )
{
  m_ImageViewManipulator->keyPressEvent(event);
  this->update();

  // emited to update to force the ql widget (if any) to update
  emit CentralWidgetUpdated();
}

/*******************************************************************************/
/* SLOTS                                                                       */
/******************************************************************************/
void
GLImageWidget
::OnSpacingChanged(const SpacingType& spacing)
{
  m_ImageViewManipulator->SetSpacing(spacing);
}
/*******************************************************************************/

}
<|endoftext|>


<commit_before>#include "Actor.h"

#include "DrawUtils.h"
#include "Math/ofDraw.h"

using namespace std;
using namespace math;

void Actor::updateAnimationFrames()
{
	if (frames.size() > 1) {
		if (ofGetElapsedTimef() > timeSpent + framerate) {
			timeSpent = ofGetElapsedTimef();
			frame = (frame + 1) % frames.size();
		}
	} else {
		frame = 0;
	}
}

Actor::Actor(float _width, float _height, std::initializer_list<unsigned> _frames, float _framerate)
	: frames(_frames), frame(0), framerate(_framerate), timeSpent(0), centered(true), color(Vector3D(255, 255, 255))
{
	size = Vector2D(
		_width > 0 ? _width : image.getWidth(),
		_height > 0 ? _height : image.getHeight());

	if (frames.empty())
		frames.push_back(0);
	frames.resize(frames.size());

	setAngle(0.0f);
	setPosition(Vector2D());
	setScale(Vector2D(1, 1));

	box.position.set(0, 0);
	box.size = getSizeScaled();
}

void Actor::init(const std::string fileName)
{
	image.load(fileName);
	bitmask = Bitmask(image, box,);
}

Vector2D Actor::getSizeScaled() const
{
	return Vector2D(localScale.x * size.x, localScale.y * size.y);
}

math::AABB Actor::getBox() const
{
	return box;
}

void Actor::setPosition(float x, float y)
{
	this->position.set(x, y);
}

void Actor::setPosition(Vector2D position)
{
	this->position = position;
}

void Actor::setAngle(float angle)
{
	this->angle = angle;
}

void Actor::setScale(math::Vector2D scale)
{
	this->localScale.set(scale);
}

void Actor::setColor(Vector3D color)
{
	this->color = color;
}

void Actor::translate(float x, float y)
{
	translate(Vector2D(x, y));
}

void Actor::translate(Vector2D translation)
{
	setPosition(position + translation);
}

void Actor::rotate(float angle)
{
	setAngle(this->angle + angle);
}

void Actor::scale(float ratio)
{
	setScale(localScale + localScale * ratio);
}

void Actor::scale(Vector2D ratio)
{
	setScale(Vector2D(localScale.x * ratio.x, localScale.y * ratio.y));
}

void Actor::update()
{
	//Update animation
	updateAnimationFrames();

	box.transform(position, angle, getSizeScaled(), centered);

	//Uncomment for an automatic AABB rotation example in AABBRotationExample
	//rotate(toRadians(30 * ofGetLastFrameTime()));
}

void Actor::draw() const
{
	auto world =
		lh::newAffineScale(localScale.x, localScale.y) *
		lh::newAffineRotation(angle) *
		lh::newAffineTranslation(position);

	cg::setColor(color);
	lh::draw(lh::flipY(world), image, size, frame);
	cg::setColor(Vector3D(255, 0, 0));
	box.draw(make_shared<ofAABB_DrawHelper>());
}

void Actor::drawIntersection(const Actor& other) const
{
	if (!box.intersects(other.box)) return;
	auto iBox = box.intersection(other.box);

	cg::setColor(Vector3D(0, 0, 255));
	iBox.draw(make_shared<ofAABB_DrawHelper>());
}

bool Actor::testCollision(const Actor& other) const
{
	//Broad Phase
	if (!box.intersects(other.box)) return false;

	//If you want to ignore Narrow Phase, uncomment
	//return true;

	//Narrow Phase
	return bitmask.testCollision(other.bitmask);
}

Actor::~Actor(void)
{
}
<commit_msg>Bitmask algorithm first version complete<commit_after>#include "Actor.h"

#include "DrawUtils.h"
#include "Math/ofDraw.h"

using namespace std;
using namespace math;

void Actor::updateAnimationFrames()
{
	if (frames.size() > 1) {
		if (ofGetElapsedTimef() > timeSpent + framerate) {
			timeSpent = ofGetElapsedTimef();
			frame = (frame + 1) % frames.size();
		}
	} else {
		frame = 0;
	}
}

Actor::Actor(float _width, float _height, std::initializer_list<unsigned> _frames, float _framerate)
	: frames(_frames), frame(0), framerate(_framerate), timeSpent(0), centered(true), color(Vector3D(255, 255, 255))
{
	size = Vector2D(
		_width > 0 ? _width : image.getWidth(),
		_height > 0 ? _height : image.getHeight());

	if (frames.empty())
		frames.push_back(0);
	frames.resize(frames.size());

	setAngle(0.0f);
	setPosition(Vector2D());
	setScale(Vector2D(1, 1));

	box.position.set(0, 0);
	box.size = getSizeScaled();
}

void Actor::init(const std::string fileName)
{
	image.load(fileName);
	bitmask = Bitmask(image, box);
}

Vector2D Actor::getSizeScaled() const
{
	return Vector2D(localScale.x * size.x, localScale.y * size.y);
}

math::AABB Actor::getBox() const
{
	return box;
}

void Actor::setPosition(float x, float y)
{
	this->position.set(x, y);
}

void Actor::setPosition(Vector2D position)
{
	this->position = position;
}

void Actor::setAngle(float angle)
{
	this->angle = angle;
}

void Actor::setScale(math::Vector2D scale)
{
	this->localScale.set(scale);
}

void Actor::setColor(Vector3D color)
{
	this->color = color;
}

void Actor::translate(float x, float y)
{
	translate(Vector2D(x, y));
}

void Actor::translate(Vector2D translation)
{
	setPosition(position + translation);
}

void Actor::rotate(float angle)
{
	setAngle(this->angle + angle);
}

void Actor::scale(float ratio)
{
	setScale(localScale + localScale * ratio);
}

void Actor::scale(Vector2D ratio)
{
	setScale(Vector2D(localScale.x * ratio.x, localScale.y * ratio.y));
}

void Actor::update()
{
	//Update animation
	updateAnimationFrames();

	box.transform(position, angle, getSizeScaled(), centered);

	//Uncomment for an automatic AABB rotation example in AABBRotationExample
	//rotate(toRadians(30 * ofGetLastFrameTime()));
}

void Actor::draw() const
{
	auto world =
		lh::newAffineScale(localScale.x, localScale.y) *
		lh::newAffineRotation(angle) *
		lh::newAffineTranslation(position);

	cg::setColor(color);
	lh::draw(lh::flipY(world), image, size, frame);
	cg::setColor(Vector3D(255, 0, 0));
	box.draw(make_shared<ofAABB_DrawHelper>());
}

void Actor::drawIntersection(const Actor& other) const
{
	if (!box.intersects(other.box)) return;
	auto iBox = box.intersection(other.box);

	cg::setColor(Vector3D(0, 0, 255));
	iBox.draw(make_shared<ofAABB_DrawHelper>());
}

bool Actor::testCollision(const Actor& other) const
{
	//Broad Phase
	if (!box.intersects(other.box)) return false;

	//If you want to ignore Narrow Phase, uncomment
	//return true;

	//Narrow Phase
	return bitmask.testCollision(other.bitmask);
}

Actor::~Actor(void)
{
}
<|endoftext|>


<commit_before>/* net6 - Library providing IPv4/IPv6 network access
 * Copyright (C) 2005 Armin Burgmeier / 0x539 dev group
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdexcept>

#include "config.hpp"
#include "common.hpp"
#include "gettext_package.hpp"

#ifdef ENABLE_NLS
namespace
{
	net6::gettext_package* local_package = NULL;
}
#endif

void net6::init_gettext(gettext_package& package)
{
#ifdef ENABLE_NLS
	local_package = &package;
#endif
}

const char* net6::_(const char* msgid)
{
#ifdef ENABLE_NLS
	if(local_package == NULL)
	{
		throw std::logic_error(
			"net6::_:\n"
			"init_gettext() has not yet been called. Most "
			"This certainly means that you have\n"
			"not created a net6::main object."
		);
	}

	return local_package->gettext(msgid);
#else
	return msgid;
#endif
}

<commit_msg>[project @ Removed a superfluous word]<commit_after>/* net6 - Library providing IPv4/IPv6 network access
 * Copyright (C) 2005 Armin Burgmeier / 0x539 dev group
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdexcept>

#include "config.hpp"
#include "common.hpp"
#include "gettext_package.hpp"

#ifdef ENABLE_NLS
namespace
{
	net6::gettext_package* local_package = NULL;
}
#endif

void net6::init_gettext(gettext_package& package)
{
#ifdef ENABLE_NLS
	local_package = &package;
#endif
}

const char* net6::_(const char* msgid)
{
#ifdef ENABLE_NLS
	if(local_package == NULL)
	{
		throw std::logic_error(
			"net6::_:\n"
			"init_gettext() has not yet been called. "
			"This certainly means that you have\n"
			"not created a net6::main object."
		);
	}

	return local_package->gettext(msgid);
#else
	return msgid;
#endif
}

<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/chrome_paths.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"

#if defined(OS_MACOSX)
#include "base/mac_util.h"
#endif

namespace chrome {

bool GetGearsPluginPathFromCommandLine(FilePath* path) {
#ifndef NDEBUG
  // for debugging, support a cmd line based override
  std::wstring plugin_path = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kGearsPluginPathOverride);
  // TODO(tc): After GetSwitchNativeValue lands, we don't need to use
  // FromWStringHack.
  *path = FilePath::FromWStringHack(plugin_path);
  return !plugin_path.empty();
#else
  return false;
#endif
}

bool PathProvider(int key, FilePath* result) {
  // Some keys are just aliases...
  switch (key) {
    case chrome::DIR_APP:
      return PathService::Get(base::DIR_MODULE, result);
    case chrome::DIR_LOGS:
#ifdef NDEBUG
      // Release builds write to the data dir
      return PathService::Get(chrome::DIR_USER_DATA, result);
#else
      // Debug builds write next to the binary (in the build tree)
#if defined(OS_MACOSX)
      if (!PathService::Get(base::DIR_EXE, result))
        return false;
      if (mac_util::AmIBundled()) {
        // If we're called from chrome, dump it beside the app (outside the
        // app bundle), if we're called from a unittest, we'll already
        // outside the bundle so use the exe dir.
        // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
        *result = result->DirName();
        *result = result->DirName();
        *result = result->DirName();
      }
      return true;
#else
      return PathService::Get(base::DIR_EXE, result);
#endif // defined(OS_MACOSX)
#endif // NDEBUG
    case chrome::FILE_RESOURCE_MODULE:
      return PathService::Get(base::FILE_MODULE, result);
  }

  // Assume that we will not need to create the directory if it does not exist.
  // This flag can be set to true for the cases where we want to create it.
  bool create_dir = false;

  FilePath cur;
  switch (key) {
    case chrome::DIR_USER_DATA:
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_USER_CACHE:
#if defined(OS_LINUX)
      if (!GetUserCacheDirectory(&cur))
        return false;
      create_dir = true;
#else
      // No concept of a separate cache directory on non-Linux systems.
      return false;
#endif
      break;
    case chrome::DIR_USER_DOCUMENTS:
      if (!GetUserDocumentsDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_DEFAULT_DOWNLOADS:
      if (!GetUserDownloadsDirectory(&cur))
        return false;
      break;
    case chrome::DIR_CRASH_DUMPS:
      // The crash reports are always stored relative to the default user data
      // directory.  This avoids the problem of having to re-initialize the
      // exception handler after parsing command line options, which may
      // override the location of the app's profile directory.
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
      create_dir = true;
      break;
    case chrome::DIR_USER_DESKTOP:
      if (!GetUserDesktop(&cur))
        return false;
      break;
    case chrome::DIR_INSPECTOR:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
#if defined(OS_MACOSX)
      cur = cur.DirName();
      cur = cur.Append(FILE_PATH_LITERAL("Resources"));
      cur = cur.Append(FILE_PATH_LITERAL("inspector"));
#else
      cur = cur.Append(FILE_PATH_LITERAL("resources"));
      cur = cur.Append(FILE_PATH_LITERAL("inspector"));
#endif
      break;
    case chrome::DIR_APP_DICTIONARIES:
#if defined(OS_LINUX) || defined(OS_MACOSX)
      // We can't write into the EXE dir on Linux, so keep dictionaries
      // alongside the safe browsing database in the user data dir.
      // And we don't want to write into the bundle on the Mac, so push
      // it to the user data dir there also.
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
#else
      if (!PathService::Get(base::DIR_EXE, &cur))
        return false;
#endif
      cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
      create_dir = true;
      break;
    case chrome::FILE_LOCAL_STATE:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      cur = cur.Append(chrome::kLocalStateFilename);
      break;
    case chrome::FILE_RECORDED_SCRIPT:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("script.log"));
      break;
    case chrome::FILE_GEARS_PLUGIN:
      if (!GetGearsPluginPathFromCommandLine(&cur)) {
#if defined(OS_WIN)
        // Search for gears.dll alongside chrome.dll first.  This new model
        // allows us to package gears.dll with the Chrome installer and update
        // it while Chrome is running.
        if (!PathService::Get(base::DIR_MODULE, &cur))
          return false;
        cur = cur.Append(FILE_PATH_LITERAL("gears.dll"));

        if (!file_util::PathExists(cur)) {
          if (!PathService::Get(base::DIR_EXE, &cur))
            return false;
          cur = cur.Append(FILE_PATH_LITERAL("plugins"));
          cur = cur.Append(FILE_PATH_LITERAL("gears"));
          cur = cur.Append(FILE_PATH_LITERAL("gears.dll"));
        }
#else
        // No gears.dll on non-Windows systems.
        return false;
#endif
      }
      break;
    // The following are only valid in the development environment, and
    // will fail if executed from an installed executable (because the
    // generated path won't exist).
    case chrome::DIR_TEST_DATA:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("chrome"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      cur = cur.Append(FILE_PATH_LITERAL("data"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::DIR_TEST_TOOLS:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("chrome"));
      cur = cur.Append(FILE_PATH_LITERAL("tools"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    default:
      return false;
  }

  if (create_dir && !file_util::PathExists(cur) &&
      !file_util::CreateDirectory(cur))
    return false;

  *result = cur;
  return true;
}

// This cannot be done as a static initializer sadly since Visual Studio will
// eliminate this object file if there is no direct entry point into it.
void RegisterPathProvider() {
  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
}

}  // namespace chrome
<commit_msg>Create the download folder if it doesn't exist.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/chrome_paths.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"

#if defined(OS_MACOSX)
#include "base/mac_util.h"
#endif

namespace chrome {

bool GetGearsPluginPathFromCommandLine(FilePath* path) {
#ifndef NDEBUG
  // for debugging, support a cmd line based override
  std::wstring plugin_path = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kGearsPluginPathOverride);
  // TODO(tc): After GetSwitchNativeValue lands, we don't need to use
  // FromWStringHack.
  *path = FilePath::FromWStringHack(plugin_path);
  return !plugin_path.empty();
#else
  return false;
#endif
}

bool PathProvider(int key, FilePath* result) {
  // Some keys are just aliases...
  switch (key) {
    case chrome::DIR_APP:
      return PathService::Get(base::DIR_MODULE, result);
    case chrome::DIR_LOGS:
#ifdef NDEBUG
      // Release builds write to the data dir
      return PathService::Get(chrome::DIR_USER_DATA, result);
#else
      // Debug builds write next to the binary (in the build tree)
#if defined(OS_MACOSX)
      if (!PathService::Get(base::DIR_EXE, result))
        return false;
      if (mac_util::AmIBundled()) {
        // If we're called from chrome, dump it beside the app (outside the
        // app bundle), if we're called from a unittest, we'll already
        // outside the bundle so use the exe dir.
        // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
        *result = result->DirName();
        *result = result->DirName();
        *result = result->DirName();
      }
      return true;
#else
      return PathService::Get(base::DIR_EXE, result);
#endif // defined(OS_MACOSX)
#endif // NDEBUG
    case chrome::FILE_RESOURCE_MODULE:
      return PathService::Get(base::FILE_MODULE, result);
  }

  // Assume that we will not need to create the directory if it does not exist.
  // This flag can be set to true for the cases where we want to create it.
  bool create_dir = false;

  FilePath cur;
  switch (key) {
    case chrome::DIR_USER_DATA:
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_USER_CACHE:
#if defined(OS_LINUX)
      if (!GetUserCacheDirectory(&cur))
        return false;
      create_dir = true;
#else
      // No concept of a separate cache directory on non-Linux systems.
      return false;
#endif
      break;
    case chrome::DIR_USER_DOCUMENTS:
      if (!GetUserDocumentsDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_DEFAULT_DOWNLOADS:
      if (!GetUserDownloadsDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_CRASH_DUMPS:
      // The crash reports are always stored relative to the default user data
      // directory.  This avoids the problem of having to re-initialize the
      // exception handler after parsing command line options, which may
      // override the location of the app's profile directory.
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
      create_dir = true;
      break;
    case chrome::DIR_USER_DESKTOP:
      if (!GetUserDesktop(&cur))
        return false;
      break;
    case chrome::DIR_INSPECTOR:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
#if defined(OS_MACOSX)
      cur = cur.DirName();
      cur = cur.Append(FILE_PATH_LITERAL("Resources"));
      cur = cur.Append(FILE_PATH_LITERAL("inspector"));
#else
      cur = cur.Append(FILE_PATH_LITERAL("resources"));
      cur = cur.Append(FILE_PATH_LITERAL("inspector"));
#endif
      break;
    case chrome::DIR_APP_DICTIONARIES:
#if defined(OS_LINUX) || defined(OS_MACOSX)
      // We can't write into the EXE dir on Linux, so keep dictionaries
      // alongside the safe browsing database in the user data dir.
      // And we don't want to write into the bundle on the Mac, so push
      // it to the user data dir there also.
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
#else
      if (!PathService::Get(base::DIR_EXE, &cur))
        return false;
#endif
      cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
      create_dir = true;
      break;
    case chrome::FILE_LOCAL_STATE:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      cur = cur.Append(chrome::kLocalStateFilename);
      break;
    case chrome::FILE_RECORDED_SCRIPT:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("script.log"));
      break;
    case chrome::FILE_GEARS_PLUGIN:
      if (!GetGearsPluginPathFromCommandLine(&cur)) {
#if defined(OS_WIN)
        // Search for gears.dll alongside chrome.dll first.  This new model
        // allows us to package gears.dll with the Chrome installer and update
        // it while Chrome is running.
        if (!PathService::Get(base::DIR_MODULE, &cur))
          return false;
        cur = cur.Append(FILE_PATH_LITERAL("gears.dll"));

        if (!file_util::PathExists(cur)) {
          if (!PathService::Get(base::DIR_EXE, &cur))
            return false;
          cur = cur.Append(FILE_PATH_LITERAL("plugins"));
          cur = cur.Append(FILE_PATH_LITERAL("gears"));
          cur = cur.Append(FILE_PATH_LITERAL("gears.dll"));
        }
#else
        // No gears.dll on non-Windows systems.
        return false;
#endif
      }
      break;
    // The following are only valid in the development environment, and
    // will fail if executed from an installed executable (because the
    // generated path won't exist).
    case chrome::DIR_TEST_DATA:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("chrome"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      cur = cur.Append(FILE_PATH_LITERAL("data"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::DIR_TEST_TOOLS:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("chrome"));
      cur = cur.Append(FILE_PATH_LITERAL("tools"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    default:
      return false;
  }

  if (create_dir && !file_util::PathExists(cur) &&
      !file_util::CreateDirectory(cur))
    return false;

  *result = cur;
  return true;
}

// This cannot be done as a static initializer sadly since Visual Studio will
// eliminate this object file if there is no direct entry point into it.
void RegisterPathProvider() {
  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
}

}  // namespace chrome
<|endoftext|>