<commit_before>/*
 * Copyright © 2012 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *
 */

#include "brw_fs.h"
#include "brw_cfg.h"

/** @file brw_cfg.cpp
 *
 * Walks the shader instructions generated and creates a set of basic
 * blocks with successor/predecessor edges connecting them.
 */

static bblock_t *
pop_stack(exec_list *list)
{
   bblock_link *link = (bblock_link *)list->get_tail();
   bblock_t *block = link->block;
   link->remove();

   return block;
}

bblock_t::bblock_t() :
   start_ip(0), end_ip(0), block_num(0)
{
   start = NULL;
   end = NULL;

   parents.make_empty();
   children.make_empty();

   if_inst = NULL;
   else_inst = NULL;
   endif_inst = NULL;
}

void
bblock_t::add_successor(void *mem_ctx, bblock_t *successor)
{
   successor->parents.push_tail(this->make_list(mem_ctx));
   children.push_tail(successor->make_list(mem_ctx));
}

bblock_link *
bblock_t::make_list(void *mem_ctx)
{
   return new(mem_ctx) bblock_link(this);
}

void
bblock_t::dump(backend_visitor *v)
{
   int ip = this->start_ip;
   for (backend_instruction *inst = (backend_instruction *)this->start;
	inst != this->end->next;
	inst = (backend_instruction *) inst->next) {
      printf("%5d: ", ip);
      v->dump_instruction(inst);
      ip++;
   }
}

cfg_t::cfg_t(backend_visitor *v)
{
   create(v->mem_ctx, &v->instructions);
}

cfg_t::cfg_t(void *mem_ctx, exec_list *instructions)
{
   create(mem_ctx, instructions);
}

void
cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
{
   mem_ctx = ralloc_context(NULL);
   block_list.make_empty();
   blocks = NULL;
   num_blocks = 0;
   ip = 0;
   cur = NULL;

   bblock_t *entry = new_block();
   bblock_t *cur_if = NULL, *cur_else = NULL, *cur_endif = NULL;
   bblock_t *cur_do = NULL, *cur_while = NULL;
   exec_list if_stack, else_stack, endif_stack, do_stack, while_stack;
   bblock_t *next;

   set_next_block(entry);

   entry->start = (backend_instruction *) instructions->get_head();

   foreach_list(node, instructions) {
      backend_instruction *inst = (backend_instruction *)node;

      cur->end = inst;

      /* set_next_block wants the post-incremented ip */
      ip++;

      switch (inst->opcode) {
      case BRW_OPCODE_IF:
	 /* Push our information onto a stack so we can recover from
	  * nested ifs.
	  */
	 if_stack.push_tail(cur_if->make_list(mem_ctx));
	 else_stack.push_tail(cur_else->make_list(mem_ctx));
	 endif_stack.push_tail(cur_endif->make_list(mem_ctx));

	 cur_if = cur;
	 cur_else = NULL;
         cur_endif = NULL;

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_ELSE:
         cur_else = cur;

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_ENDIF: {
         if (cur->start == inst) {
            /* New block was just created; use it. */
            cur_endif = cur;
         } else {
            cur_endif = new_block();
            cur_endif->start = inst;

            cur->end = (backend_instruction *)inst->prev;
            cur->add_successor(mem_ctx, cur_endif);

            ip--;
            set_next_block(cur_endif);
            ip++;
         }

         backend_instruction *else_inst = NULL;
         if (cur_else) {
            else_inst = (backend_instruction *)cur_else->end;

            cur_else->add_successor(mem_ctx, cur_endif);
         } else {
            cur_if->add_successor(mem_ctx, cur_endif);
         }

         assert(cur_if->end->opcode == BRW_OPCODE_IF);
         assert(!else_inst || else_inst->opcode == BRW_OPCODE_ELSE);
         assert(inst->opcode == BRW_OPCODE_ENDIF);

         cur_if->if_inst = cur_if->end;
         cur_if->else_inst = else_inst;
         cur_if->endif_inst = inst;

	 if (cur_else) {
            cur_else->if_inst = cur_if->end;
            cur_else->else_inst = else_inst;
            cur_else->endif_inst = inst;
         }

         cur->if_inst = cur_if->end;
         cur->else_inst = else_inst;
         cur->endif_inst = inst;

	 /* Pop the stack so we're in the previous if/else/endif */
	 cur_if = pop_stack(&if_stack);
	 cur_else = pop_stack(&else_stack);
	 cur_endif = pop_stack(&endif_stack);
	 break;
      }
      case BRW_OPCODE_DO:
	 /* Push our information onto a stack so we can recover from
	  * nested loops.
	  */
	 do_stack.push_tail(cur_do->make_list(mem_ctx));
	 while_stack.push_tail(cur_while->make_list(mem_ctx));

	 /* Set up the block just after the while.  Don't know when exactly
	  * it will start, yet.
	  */
	 cur_while = new_block();

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur->add_successor(mem_ctx, next);
	 cur_do = next;

	 set_next_block(next);
	 break;

      case BRW_OPCODE_CONTINUE:
	 cur->add_successor(mem_ctx, cur_do);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_BREAK:
	 cur->add_successor(mem_ctx, cur_while);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_WHILE:
	 cur_while->start = (backend_instruction *)inst->next;

	 cur->add_successor(mem_ctx, cur_do);
	 set_next_block(cur_while);

	 /* Pop the stack so we're in the previous loop */
	 cur_do = pop_stack(&do_stack);
	 cur_while = pop_stack(&while_stack);
	 break;

      default:
	 break;
      }
   }

   cur->end_ip = ip;

   make_block_array();
}

cfg_t::~cfg_t()
{
   ralloc_free(mem_ctx);
}

bblock_t *
cfg_t::new_block()
{
   bblock_t *block = new(mem_ctx) bblock_t();

   return block;
}

void
cfg_t::set_next_block(bblock_t *block)
{
   if (cur) {
      assert(cur->end->next == block->start);
      cur->end_ip = ip - 1;
   }

   block->start_ip = ip;
   block->block_num = num_blocks++;
   block_list.push_tail(block->make_list(mem_ctx));
   cur = block;
}

void
cfg_t::make_block_array()
{
   blocks = ralloc_array(mem_ctx, bblock_t *, num_blocks);

   int i = 0;
   foreach_list(block_node, &block_list) {
      bblock_link *link = (bblock_link *)block_node;
      blocks[i++] = link->block;
   }
   assert(i == num_blocks);
}

void
cfg_t::dump(backend_visitor *v)
{
   for (int b = 0; b < this->num_blocks; b++) {
        bblock_t *block = this->blocks[b];
      printf("START B%d", b);
      foreach_list(node, &block->parents) {
         bblock_link *link = (bblock_link *)node;
         printf(" <-B%d", link->block->block_num);
      }
      printf("\n");
      block->dump(v);
      printf("END B%d", b);
      foreach_list(node, &block->children) {
         bblock_link *link = (bblock_link *)node;
         printf(" ->B%d", link->block->block_num);
      }
      printf("\n");
   }
}
<commit_msg>i965/cfg: Remove unnecessary endif_stack.<commit_after>/*
 * Copyright © 2012 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *
 */

#include "brw_fs.h"
#include "brw_cfg.h"

/** @file brw_cfg.cpp
 *
 * Walks the shader instructions generated and creates a set of basic
 * blocks with successor/predecessor edges connecting them.
 */

static bblock_t *
pop_stack(exec_list *list)
{
   bblock_link *link = (bblock_link *)list->get_tail();
   bblock_t *block = link->block;
   link->remove();

   return block;
}

bblock_t::bblock_t() :
   start_ip(0), end_ip(0), block_num(0)
{
   start = NULL;
   end = NULL;

   parents.make_empty();
   children.make_empty();

   if_inst = NULL;
   else_inst = NULL;
   endif_inst = NULL;
}

void
bblock_t::add_successor(void *mem_ctx, bblock_t *successor)
{
   successor->parents.push_tail(this->make_list(mem_ctx));
   children.push_tail(successor->make_list(mem_ctx));
}

bblock_link *
bblock_t::make_list(void *mem_ctx)
{
   return new(mem_ctx) bblock_link(this);
}

void
bblock_t::dump(backend_visitor *v)
{
   int ip = this->start_ip;
   for (backend_instruction *inst = (backend_instruction *)this->start;
	inst != this->end->next;
	inst = (backend_instruction *) inst->next) {
      printf("%5d: ", ip);
      v->dump_instruction(inst);
      ip++;
   }
}

cfg_t::cfg_t(backend_visitor *v)
{
   create(v->mem_ctx, &v->instructions);
}

cfg_t::cfg_t(void *mem_ctx, exec_list *instructions)
{
   create(mem_ctx, instructions);
}

void
cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
{
   mem_ctx = ralloc_context(NULL);
   block_list.make_empty();
   blocks = NULL;
   num_blocks = 0;
   ip = 0;
   cur = NULL;

   bblock_t *entry = new_block();
   bblock_t *cur_if = NULL, *cur_else = NULL, *cur_endif = NULL;
   bblock_t *cur_do = NULL, *cur_while = NULL;
   exec_list if_stack, else_stack, do_stack, while_stack;
   bblock_t *next;

   set_next_block(entry);

   entry->start = (backend_instruction *) instructions->get_head();

   foreach_list(node, instructions) {
      backend_instruction *inst = (backend_instruction *)node;

      cur->end = inst;

      /* set_next_block wants the post-incremented ip */
      ip++;

      switch (inst->opcode) {
      case BRW_OPCODE_IF:
	 /* Push our information onto a stack so we can recover from
	  * nested ifs.
	  */
	 if_stack.push_tail(cur_if->make_list(mem_ctx));
	 else_stack.push_tail(cur_else->make_list(mem_ctx));

	 cur_if = cur;
	 cur_else = NULL;
         cur_endif = NULL;

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_ELSE:
         cur_else = cur;

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_ENDIF: {
         if (cur->start == inst) {
            /* New block was just created; use it. */
            cur_endif = cur;
         } else {
            cur_endif = new_block();
            cur_endif->start = inst;

            cur->end = (backend_instruction *)inst->prev;
            cur->add_successor(mem_ctx, cur_endif);

            ip--;
            set_next_block(cur_endif);
            ip++;
         }

         backend_instruction *else_inst = NULL;
         if (cur_else) {
            else_inst = (backend_instruction *)cur_else->end;

            cur_else->add_successor(mem_ctx, cur_endif);
         } else {
            cur_if->add_successor(mem_ctx, cur_endif);
         }

         assert(cur_if->end->opcode == BRW_OPCODE_IF);
         assert(!else_inst || else_inst->opcode == BRW_OPCODE_ELSE);
         assert(inst->opcode == BRW_OPCODE_ENDIF);

         cur_if->if_inst = cur_if->end;
         cur_if->else_inst = else_inst;
         cur_if->endif_inst = inst;

	 if (cur_else) {
            cur_else->if_inst = cur_if->end;
            cur_else->else_inst = else_inst;
            cur_else->endif_inst = inst;
         }

         cur->if_inst = cur_if->end;
         cur->else_inst = else_inst;
         cur->endif_inst = inst;

	 /* Pop the stack so we're in the previous if/else/endif */
	 cur_if = pop_stack(&if_stack);
	 cur_else = pop_stack(&else_stack);
	 break;
      }
      case BRW_OPCODE_DO:
	 /* Push our information onto a stack so we can recover from
	  * nested loops.
	  */
	 do_stack.push_tail(cur_do->make_list(mem_ctx));
	 while_stack.push_tail(cur_while->make_list(mem_ctx));

	 /* Set up the block just after the while.  Don't know when exactly
	  * it will start, yet.
	  */
	 cur_while = new_block();

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur->add_successor(mem_ctx, next);
	 cur_do = next;

	 set_next_block(next);
	 break;

      case BRW_OPCODE_CONTINUE:
	 cur->add_successor(mem_ctx, cur_do);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_BREAK:
	 cur->add_successor(mem_ctx, cur_while);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(next);
	 break;

      case BRW_OPCODE_WHILE:
	 cur_while->start = (backend_instruction *)inst->next;

	 cur->add_successor(mem_ctx, cur_do);
	 set_next_block(cur_while);

	 /* Pop the stack so we're in the previous loop */
	 cur_do = pop_stack(&do_stack);
	 cur_while = pop_stack(&while_stack);
	 break;

      default:
	 break;
      }
   }

   cur->end_ip = ip;

   make_block_array();
}

cfg_t::~cfg_t()
{
   ralloc_free(mem_ctx);
}

bblock_t *
cfg_t::new_block()
{
   bblock_t *block = new(mem_ctx) bblock_t();

   return block;
}

void
cfg_t::set_next_block(bblock_t *block)
{
   if (cur) {
      assert(cur->end->next == block->start);
      cur->end_ip = ip - 1;
   }

   block->start_ip = ip;
   block->block_num = num_blocks++;
   block_list.push_tail(block->make_list(mem_ctx));
   cur = block;
}

void
cfg_t::make_block_array()
{
   blocks = ralloc_array(mem_ctx, bblock_t *, num_blocks);

   int i = 0;
   foreach_list(block_node, &block_list) {
      bblock_link *link = (bblock_link *)block_node;
      blocks[i++] = link->block;
   }
   assert(i == num_blocks);
}

void
cfg_t::dump(backend_visitor *v)
{
   for (int b = 0; b < this->num_blocks; b++) {
        bblock_t *block = this->blocks[b];
      printf("START B%d", b);
      foreach_list(node, &block->parents) {
         bblock_link *link = (bblock_link *)node;
         printf(" <-B%d", link->block->block_num);
      }
      printf("\n");
      block->dump(v);
      printf("END B%d", b);
      foreach_list(node, &block->children) {
         bblock_link *link = (bblock_link *)node;
         printf(" ->B%d", link->block->block_num);
      }
      printf("\n");
   }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(TARGET_OS_LINUX)

#include <errno.h>  // NOLINT
#include <stdio.h>  // NOLINT
#include <stdlib.h>  // NOLINT
#include <string.h>  // NOLINT
#include <sys/stat.h>  // NOLINT
#include <unistd.h>  // NOLINT
#include <netinet/tcp.h>  // NOLINT

#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/log.h"
#include "bin/socket.h"

#define SOCKADDR_STORAGE_SET_PORT(addr, port) \
    if (addr.ss_family == AF_INET) { \
      reinterpret_cast<struct sockaddr_in*>(&addr)->sin_port = htons(port); \
    } else { \
      reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_port = htons(port); \
    }

#define SOCKADDR_STORAGE_GET_PORT(addr) \
    addr.ss_family == AF_INET ? \
    ntohs(reinterpret_cast<struct sockaddr_in*>(&addr)->sin_port) : \
    ntohs(reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_port)

SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
  sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(addrinfo->ai_addr);
  const char* result = inet_ntop(addrinfo->ai_family,
                                 &sockaddr->sin_addr,
                                 as_string_,
                                 INET6_ADDRSTRLEN);
  if (result == NULL) as_string_[0] = 0;
  memmove(reinterpret_cast<void *>(&addr_),
          addrinfo->ai_addr,
          addrinfo->ai_addrlen);
}

bool Socket::Initialize() {
  // Nothing to do on Linux.
  return true;
}

intptr_t Socket::CreateConnect(sockaddr_storage addr, const intptr_t port) {
  intptr_t fd;

  fd = TEMP_FAILURE_RETRY(socket(addr.ss_family, SOCK_STREAM, 0));
  if (fd < 0) {
    Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
    return -1;
  }

  FDUtils::SetCloseOnExec(fd);
  Socket::SetNonBlocking(fd);

  SOCKADDR_STORAGE_SET_PORT(addr, port);
  intptr_t result = TEMP_FAILURE_RETRY(
      connect(fd,
              reinterpret_cast<struct sockaddr*>(&addr),
              SocketAddress::GetAddrLength(addr)));
  if (result == 0 || errno == EINPROGRESS) {
    return fd;
  }
  TEMP_FAILURE_RETRY(close(fd));
  return -1;
}

intptr_t Socket::Available(intptr_t fd) {
  return FDUtils::AvailableBytes(fd);
}

int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
  ASSERT(fd >= 0);
  ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
  ASSERT(EAGAIN == EWOULDBLOCK);
  if (read_bytes == -1 && errno == EWOULDBLOCK) {
    // If the read would block we need to retry and therefore return 0
    // as the number of bytes written.
    read_bytes = 0;
  }
  return read_bytes;
}

int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
  ASSERT(fd >= 0);
  ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
  ASSERT(EAGAIN == EWOULDBLOCK);
  if (written_bytes == -1 && errno == EWOULDBLOCK) {
    // If the would block we need to retry and therefore return 0 as
    // the number of bytes written.
    written_bytes = 0;
  }
  return written_bytes;
}

intptr_t Socket::GetPort(intptr_t fd) {
  ASSERT(fd >= 0);
  struct sockaddr_storage socket_address;
  socklen_t size = sizeof(socket_address);
  if (TEMP_FAILURE_RETRY(
          getsockname(fd,
                      reinterpret_cast<struct sockaddr *>(&socket_address),
                      &size))) {
    Log::PrintErr("Error getsockname: %s\n", strerror(errno));
    return 0;
  }
  return SOCKADDR_STORAGE_GET_PORT(socket_address);
}

bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
  ASSERT(fd >= 0);
  struct sockaddr_storage socket_address;
  socklen_t size = sizeof(socket_address);
  if (TEMP_FAILURE_RETRY(
          getpeername(fd,
                      reinterpret_cast<struct sockaddr *>(&socket_address),
                      &size))) {
    Log::PrintErr("Error getpeername: %s\n", strerror(errno));
    return false;
  }
  const void* src;
  if (socket_address.ss_family == AF_INET6) {
    const sockaddr_in6* in6 =
        reinterpret_cast<const sockaddr_in6*>(&socket_address);
    src = reinterpret_cast<const void*>(&in6->sin6_addr);
  } else {
    const sockaddr_in* in =
        reinterpret_cast<const sockaddr_in*>(&socket_address);
    src = reinterpret_cast<const void*>(&in->sin_addr);
  }
  if (inet_ntop(socket_address.ss_family,
                src,
                host,
                INET_ADDRSTRLEN) == NULL) {
    Log::PrintErr("Error inet_ntop: %s\n", strerror(errno));
    return false;
  }
  *port = SOCKADDR_STORAGE_GET_PORT(socket_address);
  return true;
}

void Socket::GetError(intptr_t fd, OSError* os_error) {
  int len = sizeof(errno);
  getsockopt(fd,
             SOL_SOCKET,
             SO_ERROR,
             &errno,
             reinterpret_cast<socklen_t*>(&len));
  os_error->SetCodeAndMessage(OSError::kSystem, errno);
}

int Socket::GetType(intptr_t fd) {
  struct stat buf;
  int result = fstat(fd, &buf);
  if (result == -1) return -1;
  if (S_ISCHR(buf.st_mode)) return File::kTerminal;
  if (S_ISFIFO(buf.st_mode)) return File::kPipe;
  if (S_ISREG(buf.st_mode)) return File::kFile;
  return File::kOther;
}

intptr_t Socket::GetStdioHandle(int num) {
  return static_cast<intptr_t>(num);
}

SocketAddresses* Socket::LookupAddress(const char* host,
                                       int type,
                                       OSError** os_error) {
  // Perform a name lookup for a host name.
  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = SocketAddress::FromType(type);
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = 0;
  hints.ai_protocol = IPPROTO_TCP;
  struct addrinfo* info = NULL;
  int status = getaddrinfo(host, 0, &hints, &info);
  if (status != 0) {
    ASSERT(*os_error == NULL);
    *os_error = new OSError(status,
                            gai_strerror(status),
                            OSError::kGetAddressInfo);
    return NULL;
  }
  intptr_t count = 0;
  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
  }
  SocketAddresses* addresses = new SocketAddresses(count);
  intptr_t i = 0;
  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
      addresses->SetAt(i, new SocketAddress(c));
      i++;
    }
  }
  freeaddrinfo(info);
  return addresses;
}

intptr_t ServerSocket::CreateBindListen(sockaddr_storage addr,
                                        intptr_t port,
                                        intptr_t backlog) {
  intptr_t fd;

  fd = TEMP_FAILURE_RETRY(socket(addr.ss_family, SOCK_STREAM, 0));
  if (fd < 0) return -1;

  FDUtils::SetCloseOnExec(fd);

  int optval = 1;
  TEMP_FAILURE_RETRY(
      setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));

  if (addr.ss_family == AF_INET6) {
    optval = 0;
    TEMP_FAILURE_RETRY(
        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
  }

  SOCKADDR_STORAGE_SET_PORT(addr, port);
  if (TEMP_FAILURE_RETRY(
          bind(fd,
               reinterpret_cast<struct sockaddr*>(&addr),
               SocketAddress::GetAddrLength(addr))) < 0) {
    TEMP_FAILURE_RETRY(close(fd));
    return -1;
  }

  if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
    TEMP_FAILURE_RETRY(close(fd));
    return -1;
  }

  Socket::SetNonBlocking(fd);
  return fd;
}

static bool IsTemporaryAcceptError(int error) {
  // On Linux a number of protocol errors should be treated as EAGAIN.
  // These are the ones for TCP/IP.
  return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) ||
      (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) ||
      (error == EHOSTUNREACH) || (error == EOPNOTSUPP) ||
      (error == ENETUNREACH);
}

intptr_t ServerSocket::Accept(intptr_t fd) {
  intptr_t socket;
  struct sockaddr clientaddr;
  socklen_t addrlen = sizeof(clientaddr);
  socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen));
  if (socket == -1) {
    if (IsTemporaryAcceptError(errno)) {
      // We need to signal to the caller that this is actually not an
      // error. We got woken up from the poll on the listening socket,
      // but there is no connection ready to be accepted.
      ASSERT(kTemporaryFailure != -1);
      socket = kTemporaryFailure;
    }
  } else {
    Socket::SetNonBlocking(socket);
  }
  return socket;
}

void Socket::Close(intptr_t fd) {
  ASSERT(fd >= 0);
  int err = TEMP_FAILURE_RETRY(close(fd));
  if (err != 0) {
    const int kBufferSize = 1024;
    char error_message[kBufferSize];
    strerror_r(errno, error_message, kBufferSize);
    Log::PrintErr("%s\n", error_message);
  }
}

bool Socket::SetNonBlocking(intptr_t fd) {
  return FDUtils::SetNonBlocking(fd);
}

bool Socket::SetBlocking(intptr_t fd) {
  return FDUtils::SetBlocking(fd);
}

bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
  int on = enabled ? 1 : 0;
  return TEMP_FAILURE_RETRY(setsockopt(fd,
                                       SOL_TCP,
                                       TCP_NODELAY,
                                       reinterpret_cast<char *>(&on),
                                       sizeof(on))) == 0;
}

#endif  // defined(TARGET_OS_LINUX)
<commit_msg>Try to avoid GCC strict-aliasing error<commit_after>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(TARGET_OS_LINUX)

#include <errno.h>  // NOLINT
#include <stdio.h>  // NOLINT
#include <stdlib.h>  // NOLINT
#include <string.h>  // NOLINT
#include <sys/stat.h>  // NOLINT
#include <unistd.h>  // NOLINT
#include <netinet/tcp.h>  // NOLINT

#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/log.h"
#include "bin/socket.h"

#define SOCKADDR_STORAGE_GET_PORT(addr) \
    addr.ss_family == AF_INET ? \
    ntohs(reinterpret_cast<struct sockaddr_in*>(&addr)->sin_port) : \
    ntohs(reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_port)

static void SetPort(sockaddr_storage* addr, int port) {
  char* ptr = reinterpret_cast<char*>(addr);
  if (addr->ss_family == AF_INET) {
    reinterpret_cast<struct sockaddr_in*>(ptr)->sin_port = htons(port);
  } else { \
    reinterpret_cast<struct sockaddr_in6*>(ptr)->sin6_port = htons(port);
  }
}

SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
  sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(addrinfo->ai_addr);
  const char* result = inet_ntop(addrinfo->ai_family,
                                 &sockaddr->sin_addr,
                                 as_string_,
                                 INET6_ADDRSTRLEN);
  if (result == NULL) as_string_[0] = 0;
  memmove(reinterpret_cast<void *>(&addr_),
          addrinfo->ai_addr,
          addrinfo->ai_addrlen);
}

bool Socket::Initialize() {
  // Nothing to do on Linux.
  return true;
}

intptr_t Socket::CreateConnect(sockaddr_storage addr, const intptr_t port) {
  intptr_t fd;

  fd = TEMP_FAILURE_RETRY(socket(addr.ss_family, SOCK_STREAM, 0));
  if (fd < 0) {
    Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
    return -1;
  }

  FDUtils::SetCloseOnExec(fd);
  Socket::SetNonBlocking(fd);

  SetPort(&addr, port);
  intptr_t result = TEMP_FAILURE_RETRY(
      connect(fd,
              reinterpret_cast<struct sockaddr*>(&addr),
              SocketAddress::GetAddrLength(addr)));
  if (result == 0 || errno == EINPROGRESS) {
    return fd;
  }
  TEMP_FAILURE_RETRY(close(fd));
  return -1;
}

intptr_t Socket::Available(intptr_t fd) {
  return FDUtils::AvailableBytes(fd);
}

int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
  ASSERT(fd >= 0);
  ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
  ASSERT(EAGAIN == EWOULDBLOCK);
  if (read_bytes == -1 && errno == EWOULDBLOCK) {
    // If the read would block we need to retry and therefore return 0
    // as the number of bytes written.
    read_bytes = 0;
  }
  return read_bytes;
}

int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
  ASSERT(fd >= 0);
  ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
  ASSERT(EAGAIN == EWOULDBLOCK);
  if (written_bytes == -1 && errno == EWOULDBLOCK) {
    // If the would block we need to retry and therefore return 0 as
    // the number of bytes written.
    written_bytes = 0;
  }
  return written_bytes;
}

intptr_t Socket::GetPort(intptr_t fd) {
  ASSERT(fd >= 0);
  struct sockaddr_storage socket_address;
  socklen_t size = sizeof(socket_address);
  if (TEMP_FAILURE_RETRY(
          getsockname(fd,
                      reinterpret_cast<struct sockaddr *>(&socket_address),
                      &size))) {
    Log::PrintErr("Error getsockname: %s\n", strerror(errno));
    return 0;
  }
  return SOCKADDR_STORAGE_GET_PORT(socket_address);
}

bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
  ASSERT(fd >= 0);
  struct sockaddr_storage socket_address;
  socklen_t size = sizeof(socket_address);
  if (TEMP_FAILURE_RETRY(
          getpeername(fd,
                      reinterpret_cast<struct sockaddr *>(&socket_address),
                      &size))) {
    Log::PrintErr("Error getpeername: %s\n", strerror(errno));
    return false;
  }
  const void* src;
  if (socket_address.ss_family == AF_INET6) {
    const sockaddr_in6* in6 =
        reinterpret_cast<const sockaddr_in6*>(&socket_address);
    src = reinterpret_cast<const void*>(&in6->sin6_addr);
  } else {
    const sockaddr_in* in =
        reinterpret_cast<const sockaddr_in*>(&socket_address);
    src = reinterpret_cast<const void*>(&in->sin_addr);
  }
  if (inet_ntop(socket_address.ss_family,
                src,
                host,
                INET_ADDRSTRLEN) == NULL) {
    Log::PrintErr("Error inet_ntop: %s\n", strerror(errno));
    return false;
  }
  *port = SOCKADDR_STORAGE_GET_PORT(socket_address);
  return true;
}

void Socket::GetError(intptr_t fd, OSError* os_error) {
  int len = sizeof(errno);
  getsockopt(fd,
             SOL_SOCKET,
             SO_ERROR,
             &errno,
             reinterpret_cast<socklen_t*>(&len));
  os_error->SetCodeAndMessage(OSError::kSystem, errno);
}

int Socket::GetType(intptr_t fd) {
  struct stat buf;
  int result = fstat(fd, &buf);
  if (result == -1) return -1;
  if (S_ISCHR(buf.st_mode)) return File::kTerminal;
  if (S_ISFIFO(buf.st_mode)) return File::kPipe;
  if (S_ISREG(buf.st_mode)) return File::kFile;
  return File::kOther;
}

intptr_t Socket::GetStdioHandle(int num) {
  return static_cast<intptr_t>(num);
}

SocketAddresses* Socket::LookupAddress(const char* host,
                                       int type,
                                       OSError** os_error) {
  // Perform a name lookup for a host name.
  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = SocketAddress::FromType(type);
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = 0;
  hints.ai_protocol = IPPROTO_TCP;
  struct addrinfo* info = NULL;
  int status = getaddrinfo(host, 0, &hints, &info);
  if (status != 0) {
    ASSERT(*os_error == NULL);
    *os_error = new OSError(status,
                            gai_strerror(status),
                            OSError::kGetAddressInfo);
    return NULL;
  }
  intptr_t count = 0;
  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
  }
  SocketAddresses* addresses = new SocketAddresses(count);
  intptr_t i = 0;
  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
      addresses->SetAt(i, new SocketAddress(c));
      i++;
    }
  }
  freeaddrinfo(info);
  return addresses;
}

intptr_t ServerSocket::CreateBindListen(sockaddr_storage addr,
                                        intptr_t port,
                                        intptr_t backlog) {
  intptr_t fd;

  fd = TEMP_FAILURE_RETRY(socket(addr.ss_family, SOCK_STREAM, 0));
  if (fd < 0) return -1;

  FDUtils::SetCloseOnExec(fd);

  int optval = 1;
  TEMP_FAILURE_RETRY(
      setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));

  if (addr.ss_family == AF_INET6) {
    optval = 0;
    TEMP_FAILURE_RETRY(
        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
  }

  SetPort(&addr, port);
  if (TEMP_FAILURE_RETRY(
          bind(fd,
               reinterpret_cast<struct sockaddr*>(&addr),
               SocketAddress::GetAddrLength(addr))) < 0) {
    TEMP_FAILURE_RETRY(close(fd));
    return -1;
  }

  if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
    TEMP_FAILURE_RETRY(close(fd));
    return -1;
  }

  Socket::SetNonBlocking(fd);
  return fd;
}

static bool IsTemporaryAcceptError(int error) {
  // On Linux a number of protocol errors should be treated as EAGAIN.
  // These are the ones for TCP/IP.
  return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) ||
      (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) ||
      (error == EHOSTUNREACH) || (error == EOPNOTSUPP) ||
      (error == ENETUNREACH);
}

intptr_t ServerSocket::Accept(intptr_t fd) {
  intptr_t socket;
  struct sockaddr clientaddr;
  socklen_t addrlen = sizeof(clientaddr);
  socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen));
  if (socket == -1) {
    if (IsTemporaryAcceptError(errno)) {
      // We need to signal to the caller that this is actually not an
      // error. We got woken up from the poll on the listening socket,
      // but there is no connection ready to be accepted.
      ASSERT(kTemporaryFailure != -1);
      socket = kTemporaryFailure;
    }
  } else {
    Socket::SetNonBlocking(socket);
  }
  return socket;
}

void Socket::Close(intptr_t fd) {
  ASSERT(fd >= 0);
  int err = TEMP_FAILURE_RETRY(close(fd));
  if (err != 0) {
    const int kBufferSize = 1024;
    char error_message[kBufferSize];
    strerror_r(errno, error_message, kBufferSize);
    Log::PrintErr("%s\n", error_message);
  }
}

bool Socket::SetNonBlocking(intptr_t fd) {
  return FDUtils::SetNonBlocking(fd);
}

bool Socket::SetBlocking(intptr_t fd) {
  return FDUtils::SetBlocking(fd);
}

bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
  int on = enabled ? 1 : 0;
  return TEMP_FAILURE_RETRY(setsockopt(fd,
                                       SOL_TCP,
                                       TCP_NODELAY,
                                       reinterpret_cast<char *>(&on),
                                       sizeof(on))) == 0;
}

#endif  // defined(TARGET_OS_LINUX)
<|endoftext|>


<commit_before>/*
 * main.cpp
 * Copyright (c) 2015 Markus Himmel. All rights reserved.
 * Distributed under the terms of the MIT license.
 */

#include <algorithm>
#include <iostream>

#include <String.h>
#include <Directory.h>

#include "BookmarksTree.h"
#include "BookmarksFormat.h"

int helpMessage(int code, BookmarksOutput* a, BookmarksInput* b)
{
	delete a;
	delete b;
	std::cout	<< "Converts browser bookmarks between a selection of formats."
				<< std::endl << std::endl
				<< "Usage: bookmarkconverter [options]"
				<< std::endl << std::endl
				<< "    -f --from    FORMAT   "
				<< "The source format (WEBPOSITIVE, QUPZILLA)" << std::endl
				<< "    -t --to      FORMAT   "
				<< "The destination format (HTML, CHROME, WEBPOSITIVE)"
				<< std::endl
				<< "    -i           PATH     "
				<< "The location of the input" << std::endl
				<< "    -o           PATH     "
				<< "Where the output will be written" << std::endl
				<< "    -h --help             "
				<< "Displays this help message." << std::endl;
	return code;
}

int main(int argc, char* argv[])
{
	BookmarksOutput* output = NULL;
	BookmarksInput* input = NULL;
	int mode;
	int curarg = 0;
	BString paths[2];
	int curpath = 0;

	while (curarg + 1 < argc) {
		curarg++;
		BString current(argv[curarg]);
		if (current == "-h" || current == "--help")
			return helpMessage(0, output, input);
		else if (current == "-f" || current == "--format") {
			if (curarg == argc - 1)
				return helpMessage(1, output, input);
			else {
				curarg++;
				BString format(argv[curarg]);
				if (format.ICompare("html") == 0)
					output = new HTMLOutput();
				else if (format.ICompare("chrome") == 0)
					output = new ChromeOutput();
				else if (format.ICompare("webpositive") == 0)
					output = new BeOutput();
				else if (format.ICompare("qupzilla") == 0)
					output = new QupZillaOutput();
				else
					return helpMessage(2, output, input);
			}
		} else if (current == "--webpositive-import") {
			input = new BeInput();
			paths[0] = "";
			curpath = std::max(curpath, 1);
		} else if (current == "--qupzilla-import") {
			input = new QupZillaInput();
			paths[0] = "";
			curpath == std::max(curpath, 1);
		} else if (curpath >= 2)
			return helpMessage(5, output, input);
		else
			paths[curpath++] = argv[curarg];

	}

	if (input == NULL) {
		BDirectory test(paths[0].String());
		input = (test.InitCheck() == B_OK) ?
			new BeInput() : new QupZillaInput();
	}

	if (output == NULL)
		return helpMessage(4, output, input);

	BookmarksEntry* read = input->Input(paths[0].String());
	if (read != NULL)
		output->Output(read, paths[1].String());
	else
		std::cerr << "There was an error reading the input" << std::endl;

	delete input;
	delete output;
	return 0;
}

<commit_msg>New help message<commit_after>/*
 * main.cpp
 * Copyright (c) 2015 Markus Himmel. All rights reserved.
 * Distributed under the terms of the MIT license.
 */

#include <algorithm>
#include <iostream>

#include <String.h>
#include <Directory.h>

#include "BookmarksTree.h"
#include "BookmarksFormat.h"

int helpMessage(int code, BookmarksOutput* a, BookmarksInput* b)
{
	delete a;
	delete b;
	std::cout	<< "Converts browser bookmarks between a selection of formats."
				<< std::endl << std::endl
				<< "Usage: bookmarkconverter -f [format] [inputpath]"
				<< " [outputpath]" << std::endl
				<< "       bookmarkconverter --webpositive-import -f [format]"
				<< " [outputpath]" << std::endl
				<< "       bookmarkconverter --qupzilla-import -f [format]"
				<< " [outputpath]" << std::endl << std::endl
				<< "       format                "
				<< "The destination format (HTML, CHROME, WEBPOSITIVE)"
				<< std::endl
				<< "       -h --help             "
				<< "Displays this help message." << std::endl;
	return code;
}

int main(int argc, char* argv[])
{
	BookmarksOutput* output = NULL;
	BookmarksInput* input = NULL;
	int mode;
	int curarg = 0;
	BString paths[2];
	int curpath = 0;

	while (curarg + 1 < argc) {
		curarg++;
		BString current(argv[curarg]);
		if (current == "-h" || current == "--help")
			return helpMessage(0, output, input);
		else if (current == "-f" || current == "--format") {
			if (curarg == argc - 1)
				return helpMessage(1, output, input);
			else {
				curarg++;
				BString format(argv[curarg]);
				if (format.ICompare("html") == 0)
					output = new HTMLOutput();
				else if (format.ICompare("chrome") == 0)
					output = new ChromeOutput();
				else if (format.ICompare("webpositive") == 0)
					output = new BeOutput();
				else if (format.ICompare("qupzilla") == 0)
					output = new QupZillaOutput();
				else
					return helpMessage(2, output, input);
			}
		} else if (current == "--webpositive-import") {
			input = new BeInput();
			paths[0] = "";
			curpath = std::max(curpath, 1);
		} else if (current == "--qupzilla-import") {
			input = new QupZillaInput();
			paths[0] = "";
			curpath == std::max(curpath, 1);
		} else if (curpath >= 2)
			return helpMessage(5, output, input);
		else
			paths[curpath++] = argv[curarg];

	}

	if (input == NULL) {
		BDirectory test(paths[0].String());
		input = (test.InitCheck() == B_OK) ?
			new BeInput() : new QupZillaInput();
	}

	if (output == NULL)
		return helpMessage(4, output, input);

	BookmarksEntry* read = input->Input(paths[0].String());
	if (read != NULL)
		output->Output(read, paths[1].String());
	else
		std::cerr << "There was an error reading the input" << std::endl;

	delete input;
	delete output;
	return 0;
}

<|endoftext|>


<commit_before>/**
 * @file lars_main.cpp
 * @author Nishant Mehta
 *
 * Executable for LARS.
 */
#include <mlpack/core.hpp>

#include "lars.hpp"

PROGRAM_INFO("LARS", "An implementation of LARS: Least Angle Regression "
    "(Stagewise/laSso).  This is a stage-wise homotopy-based algorithm for "
    "L1-regularized linear regression (LASSO) and L1+L2-regularized linear "
    "regression (Elastic Net).\n"
    "\n"
    "Let X be a matrix where each row is a point and each column is a "
    "dimension, and let y be a vector of targets.\n"
    "\n"
    "The Elastic Net problem is to solve\n\n"
    "  min_beta 0.5 || X * beta - y ||_2^2 + lambda_1 ||beta||_1 +\n"
    "      0.5 lambda_2 ||beta||_2^2\n\n"
    "If lambda_1 > 0 and lambda_2 = 0, the problem is the LASSO.\n"
    "If lambda_1 > 0 and lambda_2 > 0, the problem is the Elastic Net.\n"
    "If lambda_1 = 0 and lambda_2 > 0, the problem is ridge regression.\n"
    "If lambda_1 = 0 and lambda_2 = 0, the problem is unregularized linear "
    "regression.\n"
    "\n"
    "For efficiency reasons, it is not recommended to use this algorithm with "
    "lambda_1 = 0.  In that case, use the 'linear_regression' program, which "
    "implements both unregularized linear regression and ridge regression.\n");

PARAM_STRING_REQ("input_file", "File containing covariates (X).",
    "i");
PARAM_STRING_REQ("responses_file", "File containing y "
    "(responses/observations).", "r");

PARAM_STRING("output_file", "File to save beta (linear estimator) to.", "o",
    "output.csv");

PARAM_STRING("test_file", "File containing points to regress on (test points).",
    "t", "");
PARAM_STRING("output_predictions", "If --test_file is specified, this file is "
    "where the predicted responses will be saved.", "p", "predictions.csv");

PARAM_DOUBLE("lambda1", "Regularization parameter for l1-norm penalty.", "l",
    0);
PARAM_DOUBLE("lambda2", "Regularization parameter for l2-norm penalty.", "L",
    0);
PARAM_FLAG("use_cholesky", "Use Cholesky decomposition during computation "
    "rather than explicitly computing the full Gram matrix.", "c");

using namespace arma;
using namespace std;
using namespace mlpack;
using namespace mlpack::regression;

int main(int argc, char* argv[])
{
  // Handle parameters,
  CLI::ParseCommandLine(argc, argv);

  double lambda1 = CLI::GetParam<double>("lambda1");
  double lambda2 = CLI::GetParam<double>("lambda2");
  bool useCholesky = CLI::HasParam("use_cholesky");

  // Load covariates.  We can avoid LARS transposing our data by choosing to not
  // transpose this data.
  const string matXFilename = CLI::GetParam<string>("input_file");
  mat matX;
  data::Load(matXFilename, matX, true, false);

  // Load responses.  The responses should be a one-dimensional vector, and it
  // seems more likely that these will be stored with one response per line (one
  // per row).  So we should not transpose upon loading.
  const string yFilename = CLI::GetParam<string>("responses_file");
  mat matY; // Will be a vector.
  data::Load(yFilename, matY, true, false);

  // Make sure y is oriented the right way.
  if (matY.n_rows == 1)
    matY = trans(matY);
  if (matY.n_cols > 1)
    Log::Fatal << "Only one column or row allowed in responses file!" << endl;

  if (matY.n_elem != matX.n_rows)
    Log::Fatal << "Number of responses must be equal to number of rows of X!"
        << endl;

  // Do LARS.
  LARS lars(useCholesky, lambda1, lambda2);
  vec beta;
  lars.Regress(matX, matY.unsafe_col(0), beta, false /* do not transpose */);

  const string betaFilename = CLI::GetParam<string>("output_file");
  beta.save(betaFilename, raw_ascii);

  if (CLI::HasParam("test_file"))
  {
    Log::Info << "Regressing on test points." << endl;
    const string testFile = CLI::GetParam<string>("test_file");
    const string outputPredictionsFile =
        CLI::GetParam<string>("output_predictions");

    // Load test points.
    mat testPoints;
    data::Load(testFile, testPoints, true, false);

    arma::vec predictions;
    lars.Predict(testPoints.t(), predictions, false);

    // Save test predictions.  One per line, so, we need a rowvec.
    arma::rowvec predToSave = predictions.t();
    data::Save(outputPredictionsFile, predToSave);
  }
}
<commit_msg>Update for API change.<commit_after>/**
 * @file lars_main.cpp
 * @author Nishant Mehta
 *
 * Executable for LARS.
 */
#include <mlpack/core.hpp>

#include "lars.hpp"

PROGRAM_INFO("LARS", "An implementation of LARS: Least Angle Regression "
    "(Stagewise/laSso).  This is a stage-wise homotopy-based algorithm for "
    "L1-regularized linear regression (LASSO) and L1+L2-regularized linear "
    "regression (Elastic Net).\n"
    "\n"
    "Let X be a matrix where each row is a point and each column is a "
    "dimension, and let y be a vector of targets.\n"
    "\n"
    "The Elastic Net problem is to solve\n\n"
    "  min_beta 0.5 || X * beta - y ||_2^2 + lambda_1 ||beta||_1 +\n"
    "      0.5 lambda_2 ||beta||_2^2\n\n"
    "If lambda_1 > 0 and lambda_2 = 0, the problem is the LASSO.\n"
    "If lambda_1 > 0 and lambda_2 > 0, the problem is the Elastic Net.\n"
    "If lambda_1 = 0 and lambda_2 > 0, the problem is ridge regression.\n"
    "If lambda_1 = 0 and lambda_2 = 0, the problem is unregularized linear "
    "regression.\n"
    "\n"
    "For efficiency reasons, it is not recommended to use this algorithm with "
    "lambda_1 = 0.  In that case, use the 'linear_regression' program, which "
    "implements both unregularized linear regression and ridge regression.\n");

PARAM_STRING_REQ("input_file", "File containing covariates (X).",
    "i");
PARAM_STRING_REQ("responses_file", "File containing y "
    "(responses/observations).", "r");

PARAM_STRING("output_file", "File to save beta (linear estimator) to.", "o",
    "output.csv");

PARAM_STRING("test_file", "File containing points to regress on (test points).",
    "t", "");
PARAM_STRING("output_predictions", "If --test_file is specified, this file is "
    "where the predicted responses will be saved.", "p", "predictions.csv");

PARAM_DOUBLE("lambda1", "Regularization parameter for l1-norm penalty.", "l",
    0);
PARAM_DOUBLE("lambda2", "Regularization parameter for l2-norm penalty.", "L",
    0);
PARAM_FLAG("use_cholesky", "Use Cholesky decomposition during computation "
    "rather than explicitly computing the full Gram matrix.", "c");

using namespace arma;
using namespace std;
using namespace mlpack;
using namespace mlpack::regression;

int main(int argc, char* argv[])
{
  // Handle parameters,
  CLI::ParseCommandLine(argc, argv);

  double lambda1 = CLI::GetParam<double>("lambda1");
  double lambda2 = CLI::GetParam<double>("lambda2");
  bool useCholesky = CLI::HasParam("use_cholesky");

  // Load covariates.  We can avoid LARS transposing our data by choosing to not
  // transpose this data.
  const string matXFilename = CLI::GetParam<string>("input_file");
  mat matX;
  data::Load(matXFilename, matX, true, false);

  // Load responses.  The responses should be a one-dimensional vector, and it
  // seems more likely that these will be stored with one response per line (one
  // per row).  So we should not transpose upon loading.
  const string yFilename = CLI::GetParam<string>("responses_file");
  mat matY; // Will be a vector.
  data::Load(yFilename, matY, true, false);

  // Make sure y is oriented the right way.
  if (matY.n_rows == 1)
    matY = trans(matY);
  if (matY.n_cols > 1)
    Log::Fatal << "Only one column or row allowed in responses file!" << endl;

  if (matY.n_elem != matX.n_rows)
    Log::Fatal << "Number of responses must be equal to number of rows of X!"
        << endl;

  // Do LARS.
  LARS lars(useCholesky, lambda1, lambda2);
  vec beta;
  lars.Train(matX, matY.unsafe_col(0), beta, false /* do not transpose */);

  const string betaFilename = CLI::GetParam<string>("output_file");
  beta.save(betaFilename, raw_ascii);

  if (CLI::HasParam("test_file"))
  {
    Log::Info << "Regressing on test points." << endl;
    const string testFile = CLI::GetParam<string>("test_file");
    const string outputPredictionsFile =
        CLI::GetParam<string>("output_predictions");

    // Load test points.
    mat testPoints;
    data::Load(testFile, testPoints, true, false);

    arma::vec predictions;
    lars.Predict(testPoints.t(), predictions, false);

    // Save test predictions.  One per line, so, we need a rowvec.
    arma::rowvec predToSave = predictions.t();
    data::Save(outputPredictionsFile, predToSave);
  }
}
<|endoftext|>


<commit_before>#include <irrlicht/irrlicht.h>
#define IRR_INCLUDE
#include <irrlicht/driverChoice.h>
#include <dirent.h>
#include "controlterm.h"
#include "term.h"
#ifndef IDS_INCLUDE
#include "ids.h"
#define IDS_INCLUDE
#endif

#define VISIBLE 1
#define INVISIBLE 0

char* disp = NULL;

using namespace irr;

X11Display *currentDisp = NULL;
scene::ISceneNode* selectedSceneNode = NULL;

class VREventReceiver : public IEventReceiver {
  public:
    virtual bool OnEvent(const SEvent& event){
      if(currentDisp != NULL && selectedSceneNode && event.EventType == irr::EET_KEY_INPUT_EVENT){
        if(IsModKey(event.KeyInput.Key)){
          if(event.KeyInput.PressedDown){
            //FIXME: shit sometimes gets weird here
            CurrentMod |= mapKeyCode(event.KeyInput.Key);
          } else {
            CurrentMod &= ~mapKeyCode(event.KeyInput.Key);
          }
        } else {
          KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
          currentDisp->sendKeyEvent(mapKeyCode(event.KeyInput.Key), event.KeyInput.PressedDown, CurrentMod);
        }
      }
      return false;
    }
    virtual bool IsKeyDown(EKEY_CODE keyCode) const {
      return KeyIsDown[keyCode];
    }
  private:
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
    // FIXME: can initialise to nonzero
    int CurrentMod;
};

void setOutlineVisible(scene::ISceneNode *node, int visible){
  // Will set child scene node's that are outlines as invisible if they exist
  irr::core::list<irr::scene::ISceneNode*> children = node->getChildren();
  irr::core::list<irr::scene::ISceneNode*>::ConstIterator start = children.begin();
  const irr::core::list<irr::scene::ISceneNode*>::ConstIterator& end = children.end();

  for (; start != end; ++start)
  {
     irr::scene::ISceneNode* const node = (*start);

     if(node->getID() & IDFlag_IsOutline) node->setVisible(visible);
  }
}

int main(int argc, char** argv) {
  // Shouldn't need to check for -1... X11Display init should fail out
  int currDispNum = getNextAvailableXDisplayNumber() - 1;
  int dispNumDigits = 0;
  if(currDispNum == 0){
    dispNumDigits = 1;
  }else{
    dispNumDigits = floor(log10(currDispNum)) + 1;
  }
  disp = (char*)malloc((dispNumDigits + 2) * sizeof(char));
  sprintf(disp, ":%d", currDispNum);
  printf("Using display %s\n", disp);
  X11Display currentDisp(disp);
  // Uses driverChoiceConsole() from driverChoice.h
  bool yesQuake = false;
  if(argc > 1){
    if(strcmp(argv[1], "--quake") == 0) yesQuake = true;
  }

  const char* screenshotFile;
  DIR* dir;
  if((dir = opendir("/vrhs")) == NULL){
    screenshotFile = "/tmp/vrhs/shot.png";
  } else {
    screenshotFile = "/vrhs/shot.png";
  }

  VREventReceiver receiver;
  IrrlichtDevice *device = createDevice(driverChoiceConsole(), core::dimension2d<u32>(512, 384), 16, false, false, false, &receiver);
  device->setWindowCaption(L"Grimmware VRHackspace::Mk I");

  // set up video driver, scene manager and gui environment
  video::IVideoDriver* driver = device->getVideoDriver();
  scene::ISceneManager* smgr = device->getSceneManager();
  gui::IGUIEnvironment* guienv = device->getGUIEnvironment();

  scene::IMeshSceneNode* terminal = addTerminal(smgr);

  // Add lighting
  scene::ISceneNode* light = smgr->addLightSceneNode(0, core::vector3df(10,10,10),
      video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f);
  light->addAnimator(smgr->createFlyCircleAnimator(core::vector3df(0,150,0),250.0f));

  light = smgr->addBillboardSceneNode(light, core::dimension2d<f32>(50, 50));
  light->setMaterialFlag(video::EMF_LIGHTING, false);
  light->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
  light->setMaterialTexture(0, driver->getTexture("media/particle.bmp"));
  light->setID(ID_IsNotPickable); // This ensures that we don't accidentally ray-pick it

  core::list<scene::ITriangleSelector*> collideables;
  collideables.push_back(terminal->getTriangleSelector());

  scene::IMetaTriangleSelector* cameraCollisionSelector =
    smgr->createMetaTriangleSelector();
  if(yesQuake){
    // Create the level and the collision levelSelector
    device->getFileSystem()->addFileArchive("models/map-20kdm2.pk3");
    scene::IAnimatedMesh* levelMesh = smgr->getMesh("20kdm2.bsp");
    scene::IMeshSceneNode* levelNode = 0;
    scene::ITriangleSelector* levelSelector = 0;
    if (levelMesh) {
      levelNode = smgr->addOctreeSceneNode(levelMesh->getMesh(0), 0, IDFlag_IsSolid);
//        node = smgr->addMeshSceneNode(mesh->getMesh(0));
      if(levelNode){
        levelNode->setMaterialFlag(video::EMF_LIGHTING, true);
        levelNode->setPosition(core::vector3df(-1350,-130,-1400));
        levelSelector = smgr->createOctreeTriangleSelector(
                   levelNode->getMesh(), levelNode, 128);
        collideables.push_back(levelSelector);
        levelNode->setTriangleSelector(levelSelector);
        levelSelector->drop(); // As soon as we're done with the levelSelector, drop it.
      }
    }
  } else {
    // Metal room
    scene::IMeshSceneNode *room = smgr->addCubeSceneNode(15.0f, 0, IDFlag_IsSolid, core::vector3df(10,160,30), core::vector3df(0,0,0), core::vector3df(30, 30, 30));
    smgr->getMeshManipulator()->flipSurfaces(room->getMesh());
    smgr->getMeshManipulator()->recalculateNormals(room->getMesh());
    room->setMaterialFlag(video::EMF_LIGHTING, true);
    room->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
    room->setMaterialTexture(0, driver->getTexture("media/texture.jpg"));
    room->setTriangleSelector(smgr->createTriangleSelector( room->getMesh(), room ));

    collideables.push_back(room->getTriangleSelector());
  }
  for(
      core::list<scene::ITriangleSelector*>::ConstIterator coll = collideables.begin();
      coll != collideables.end();
      ++coll
     ) cameraCollisionSelector->addTriangleSelector((*coll));

  //Create camera and pin it to the floor
  scene::ICameraSceneNode *camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f);
  camera->setPosition(core::vector3df(50,50,-60));

  //Add collision to the camera
  scene::ISceneNodeAnimator* levelAnim = smgr->createCollisionResponseAnimator(
    cameraCollisionSelector, camera, core::vector3df(30,50,30),
    core::vector3df(0,-10,0), core::vector3df(0,30,0));
  camera->addAnimator(levelAnim);
  levelAnim->drop();  // And likewise, drop the animator when we're done referring to it.

  device->getCursorControl()->setVisible(false);
  //camera->setTarget(terminal->getAbsolutePosition());
  int lastFPS = -1;
  video::ITexture * texture;
  scene::ISceneNode* lastSelectedSceneNode = NULL;
  while(device->run()) {
    device->getVideoDriver()->removeTexture(texture);
    texture = driver->getTexture(screenshotFile);
    terminal->setMaterialTexture(0, texture);
    // Make the pointy pointer thingy
    core::line3d<f32> ray;
    ray.start = camera->getPosition();
    ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 100.0f;

    scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();

    core::vector3df intersection;
    core::triangle3df hitTriangle;

    driver->beginScene(true, true, video::SColor(255,100,101,140));
    selectedSceneNode =
      collMan->getSceneNodeAndCollisionPointFromRay(
          ray,
          intersection,
          hitTriangle,
          IDFlag_IsInteractable,
          0);

    if(lastSelectedSceneNode) setOutlineVisible(lastSelectedSceneNode, INVISIBLE);
    if(selectedSceneNode)
    {
      setOutlineVisible(selectedSceneNode, VISIBLE);
      lastSelectedSceneNode = selectedSceneNode;
    }

    smgr->drawAll();
    guienv->drawAll();
    driver->endScene();
  }
  device->drop();
  return 0;
}
<commit_msg>Restored previous functionality before refactor<commit_after>#include <irrlicht/irrlicht.h>
#define IRR_INCLUDE
#include <irrlicht/driverChoice.h>
#include <dirent.h>
#include "controlterm.h"
#include "term.h"
#ifndef IDS_INCLUDE
#include "ids.h"
#define IDS_INCLUDE
#endif

#define VISIBLE 1
#define INVISIBLE 0

char* disp = NULL;

using namespace irr;

X11Display *currentDisp = NULL;
scene::ISceneNode* selectedSceneNode = NULL;

class VREventReceiver : public IEventReceiver {
  public:
    virtual bool OnEvent(const SEvent& event){
      if(currentDisp != NULL && selectedSceneNode && event.EventType == irr::EET_KEY_INPUT_EVENT){
        if(IsModKey(event.KeyInput.Key)){
          if(event.KeyInput.PressedDown){
            CurrentMod |= mapKeyCode(event.KeyInput.Key);
          } else {
            CurrentMod &= ~mapKeyCode(event.KeyInput.Key);
          }
        } else {
          KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
          currentDisp->sendKeyEvent(mapKeyCode(event.KeyInput.Key), event.KeyInput.PressedDown, CurrentMod);
        }
      }
      return false;
    }
    virtual bool IsKeyDown(EKEY_CODE keyCode) const {
      return KeyIsDown[keyCode];
    }
  private:
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
    int CurrentMod = 0;
};

void setOutlineVisible(scene::ISceneNode *node, int visible){
  // Will set child scene node's that are outlines as invisible if they exist
  irr::core::list<irr::scene::ISceneNode*> children = node->getChildren();
  irr::core::list<irr::scene::ISceneNode*>::ConstIterator start = children.begin();
  const irr::core::list<irr::scene::ISceneNode*>::ConstIterator& end = children.end();

  for (; start != end; ++start)
  {
     irr::scene::ISceneNode* const node = (*start);

     if(node->getID() & IDFlag_IsOutline) node->setVisible(visible);
  }
}

int main(int argc, char** argv) {
  // Shouldn't need to check for -1... X11Display init should fail out
  int currDispNum = getNextAvailableXDisplayNumber() - 1;
  int dispNumDigits = 0;
  if(currDispNum == 0){
    dispNumDigits = 1;
  }else{
    dispNumDigits = floor(log10(currDispNum)) + 1;
  }
  disp = (char*)malloc((dispNumDigits + 2) * sizeof(char));
  sprintf(disp, ":%d", currDispNum);
  printf("Using display %s\n", disp);
  X11Display currentDisp(disp);
  //X11Display aDisp(disp);
  //currentDisp = &aDisp;
  // Uses driverChoiceConsole() from driverChoice.h
  bool yesQuake = false;
  if(argc > 1){
    if(strcmp(argv[1], "--quake") == 0) yesQuake = true;
  }

  const char* screenshotFile;
  DIR* dir;
  if((dir = opendir("/vrhs")) == NULL){
    screenshotFile = "/tmp/vrhs/shot.png";
  } else {
    screenshotFile = "/vrhs/shot.png";
  }

  VREventReceiver receiver;
  IrrlichtDevice *device = createDevice(driverChoiceConsole(), core::dimension2d<u32>(512, 384), 16, false, false, false, &receiver);
  device->setWindowCaption(L"Grimmware VRHackspace::Mk I");

  // set up video driver, scene manager and gui environment
  video::IVideoDriver* driver = device->getVideoDriver();
  scene::ISceneManager* smgr = device->getSceneManager();
  gui::IGUIEnvironment* guienv = device->getGUIEnvironment();

  scene::IMeshSceneNode* terminal = addTerminal(smgr);

  // Add lighting
  scene::ISceneNode* light = smgr->addLightSceneNode(0, core::vector3df(10,10,10),
      video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f);
  light->addAnimator(smgr->createFlyCircleAnimator(core::vector3df(0,150,0),250.0f));

  light = smgr->addBillboardSceneNode(light, core::dimension2d<f32>(50, 50));
  light->setMaterialFlag(video::EMF_LIGHTING, false);
  light->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
  light->setMaterialTexture(0, driver->getTexture("media/particle.bmp"));
  light->setID(ID_IsNotPickable); // This ensures that we don't accidentally ray-pick it

  core::list<scene::ITriangleSelector*> collideables;
  collideables.push_back(terminal->getTriangleSelector());

  scene::IMetaTriangleSelector* cameraCollisionSelector =
    smgr->createMetaTriangleSelector();
  if(yesQuake){
    // Create the level and the collision levelSelector
    device->getFileSystem()->addFileArchive("models/map-20kdm2.pk3");
    scene::IAnimatedMesh* levelMesh = smgr->getMesh("20kdm2.bsp");
    scene::IMeshSceneNode* levelNode = 0;
    scene::ITriangleSelector* levelSelector = 0;
    if (levelMesh) {
      levelNode = smgr->addOctreeSceneNode(levelMesh->getMesh(0), 0, IDFlag_IsSolid);
//        node = smgr->addMeshSceneNode(mesh->getMesh(0));
      if(levelNode){
        levelNode->setMaterialFlag(video::EMF_LIGHTING, true);
        levelNode->setPosition(core::vector3df(-1350,-130,-1400));
        levelSelector = smgr->createOctreeTriangleSelector(
                   levelNode->getMesh(), levelNode, 128);
        collideables.push_back(levelSelector);
        levelNode->setTriangleSelector(levelSelector);
        levelSelector->drop(); // As soon as we're done with the levelSelector, drop it.
      }
    }
  } else {
    // Metal room
    scene::IMeshSceneNode *room = smgr->addCubeSceneNode(15.0f, 0, IDFlag_IsSolid, core::vector3df(10,160,30), core::vector3df(0,0,0), core::vector3df(30, 30, 30));
    smgr->getMeshManipulator()->flipSurfaces(room->getMesh());
    smgr->getMeshManipulator()->recalculateNormals(room->getMesh());
    room->setMaterialFlag(video::EMF_LIGHTING, true);
    room->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
    room->setMaterialTexture(0, driver->getTexture("media/texture.jpg"));
    room->setTriangleSelector(smgr->createTriangleSelector( room->getMesh(), room ));

    collideables.push_back(room->getTriangleSelector());
  }
  for(
      core::list<scene::ITriangleSelector*>::ConstIterator coll = collideables.begin();
      coll != collideables.end();
      ++coll
     ) cameraCollisionSelector->addTriangleSelector((*coll));

  //Create camera and pin it to the floor
  scene::ICameraSceneNode *camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f);
  camera->setPosition(core::vector3df(50,50,-60));

  //Add collision to the camera
  scene::ISceneNodeAnimator* levelAnim = smgr->createCollisionResponseAnimator(
    cameraCollisionSelector, camera, core::vector3df(30,50,30),
    core::vector3df(0,-10,0), core::vector3df(0,30,0));
  camera->addAnimator(levelAnim);
  levelAnim->drop();  // And likewise, drop the animator when we're done referring to it.

  device->getCursorControl()->setVisible(false);
  //camera->setTarget(terminal->getAbsolutePosition());
  int lastFPS = -1;
  video::ITexture * texture;
  scene::ISceneNode* lastSelectedSceneNode = NULL;
  while(device->run()) {
    device->getVideoDriver()->removeTexture(texture);
    texture = driver->getTexture(screenshotFile);
    terminal->setMaterialTexture(0, texture);
    // Make the pointy pointer thingy
    core::line3d<f32> ray;
    ray.start = camera->getPosition();
    ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 100.0f;

    scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();

    core::vector3df intersection;
    core::triangle3df hitTriangle;

    driver->beginScene(true, true, video::SColor(255,100,101,140));
    selectedSceneNode =
      collMan->getSceneNodeAndCollisionPointFromRay(
          ray,
          intersection,
          hitTriangle,
          IDFlag_IsInteractable,
          0);

    if(lastSelectedSceneNode) setOutlineVisible(lastSelectedSceneNode, INVISIBLE);
    if(selectedSceneNode)
    {
      setOutlineVisible(selectedSceneNode, VISIBLE);
      lastSelectedSceneNode = selectedSceneNode;
    }

    smgr->drawAll();
    guienv->drawAll();
    driver->endScene();
  }
  device->drop();
  return 0;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2017 Tristan Brindle <tcbrindle@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 */

#include <tcb/sudoku.hpp>

#include <iostream>
#include <iterator>
#include <fstream>

int main(int argc, char** argv)
{
    if (argc < 2) {
        std::cout << "Give me a puzzle!\n";
        return 1;
    }

    std::ifstream file{argv[1]};

    std::string str(std::istream_iterator<char>{file}, std::istream_iterator<char>{});

    auto grid = tcb::sudoku::grid::parse(str);

    std::cout << *grid << std::endl;

    auto out_grid = tcb::sudoku::solve(*grid);

    std::cout << *out_grid << std::endl;
}<commit_msg>Add more functionality to main executable<commit_after>/*
Copyright (c) 2017 Tristan Brindle <tcbrindle@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 */

#include <tcb/sudoku.hpp>

#include <chrono>
#include <iostream>
#include <iterator>
#include <fstream>

struct timer {
    using clock_type = std::chrono::high_resolution_clock;

    timer() = default;

    template <typename DurationType = std::chrono::microseconds>
    DurationType elapsed() const
    {
        return std::chrono::duration_cast<DurationType>(clock_type::now() - start_);
    }

private:
    clock_type::time_point start_ = clock_type::now();
};

auto solve_one(const tcb::sudoku::grid& grid, bool interactive)
{
    timer t{};
    auto solution = tcb::sudoku::solve(grid);
    auto e = t.elapsed();

    if (interactive) {
        std::cout << grid << "\n\n";

        if (solution) {
            std::cout << *solution << "\n";
        }
        else {
            std::cout << "Could not find solution\n";
        }
        std::cout << e.count() / 1000.00 << "ms elapsed\n";
    }

    return e;
}

auto solve_from_stream(std::istream& stream, bool interactive)
{
    std::string s;
    std::chrono::microseconds total_elapsed{};
    int num_solved = 0;
    while(std::getline(stream, s)) {
        auto grid = tcb::sudoku::grid::parse(s);
        if (!grid) {
            continue;
        }
        total_elapsed += solve_one(*grid, interactive);
        ++num_solved;
    }

    return std::make_pair(num_solved, total_elapsed);
}

int main(int argc, char** argv)
{
    std::chrono::microseconds total_elapsed{};
    int num_solved = 0;

    if (argc == 1) {
        std::tie(num_solved, total_elapsed) = solve_from_stream(std::cin, true);
    } else {
        std::ifstream file{argv[1]};
        std::tie(num_solved, total_elapsed) = solve_from_stream(file, false);
    }

    std::cout << "Solved " << num_solved << " puzzles in " << total_elapsed.count()/1000.0 << "ms\n";
    std::cout << "(Average " << total_elapsed.count()/(1000.0 * num_solved) << "ms per puzzle)\n";
}<|endoftext|>


<commit_before>#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>
#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <hadouken/application.hpp>
#include <hadouken/logging.hpp>
#include <hadouken/platform.hpp>
#include <hadouken/hosting/host.hpp>
#include <hadouken/hosting/console_host.hpp>

#ifdef WIN32
#include <hadouken/hosting/service_host.hpp>
#endif

namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace pt = boost::property_tree;

po::variables_map load_options(int argc,char *argv[])
{
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Display available commandline options")
        ("config", po::value<std::string>(), "Set path to a JSON configuration file. The default is %appdir%/hadouken.json")
        ("daemon", "Start Hadouken in daemon/service mode.")
#ifdef WIN32
        ("install-service", "Install Hadouken in the SCM.")
        ("uninstall-service", "Uninstall Hadouken from the SCM.")
#endif
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        cout << desc << "\n";
        return 1;
    }

    return vm;
}

fs::path get_config_path(const po::variables_map& options)
{
    if (options.count("config"))
    {
        return options["config"].as<std::string>();
    }
    else if (options.count("daemon"))
    {
        return (hadouken::platform::data_path() / "hadouken.json");
    }
    else
    {
        return (hadouken::platform::get_current_directory() / "hadouken.json");
    }
}

std::unique_ptr<hadouken::hosting::host> get_host(const po::variables_map& options)
{
    if (options.count("daemon"))
    {
#ifdef WIN32
        return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::service_host());
#endif
    }

    return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::console_host());
}

int main(int argc, char *argv[])
{
    po::variables_map vm = load_options(argc, argv);
    hadouken::logging::setup(vm);

    // Do platform-specific initialization as early as possible.
    hadouken::platform::init();

#ifdef WIN32
    if (vm.count("install-service"))
    {
        hadouken::platform::install_service();
        return 0;
    }
    else if (vm.count("uninstall-service"))
    {
        hadouken::platform::uninstall_service();
        return 0;
    }
#endif

    fs::path config_file = get_config_path(vm);
    pt::ptree config;

    if (!fs::exists(config_file))
    {
        BOOST_LOG_TRIVIAL(warning) << "Could not find config file at " << config_file;
    }
    else
    {
        try
        {
            pt::read_json(config_file.string(), config);
            BOOST_LOG_TRIVIAL(info) << "Loaded config file " << config_file;
        }
        catch (const std::exception& ex)
        {
            // To meet expectations, fail if the configuration file cannot be parsed. Otherwise,
            // we will revert to the default config which might be totally wrong.
            BOOST_LOG_TRIVIAL(fatal) << "Error when loading config file " << config_file << ": " << ex.what();
            return EXIT_FAILURE;
        }
    }

    boost::shared_ptr<boost::asio::io_service> io(new boost::asio::io_service());

    hadouken::application app(io, config);
    app.script_host().define_global("__CONFIG__", config_file.string());
    app.script_host().define_global("__CONFIG_PATH__", config_file.parent_path().string());

    app.start();
    int result = get_host(vm)->wait_for_exit(io);
    app.stop();

    return result;
}
<commit_msg>Helps when you declare the right namespace.<commit_after>#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>
#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <hadouken/application.hpp>
#include <hadouken/logging.hpp>
#include <hadouken/platform.hpp>
#include <hadouken/hosting/host.hpp>
#include <hadouken/hosting/console_host.hpp>

#ifdef WIN32
#include <hadouken/hosting/service_host.hpp>
#endif

namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace pt = boost::property_tree;

po::variables_map load_options(int argc,char *argv[])
{
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Display available commandline options")
        ("config", po::value<std::string>(), "Set path to a JSON configuration file. The default is %appdir%/hadouken.json")
        ("daemon", "Start Hadouken in daemon/service mode.")
#ifdef WIN32
        ("install-service", "Install Hadouken in the SCM.")
        ("uninstall-service", "Uninstall Hadouken from the SCM.")
#endif
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 1;
    }

    return vm;
}

fs::path get_config_path(const po::variables_map& options)
{
    if (options.count("config"))
    {
        return options["config"].as<std::string>();
    }
    else if (options.count("daemon"))
    {
        return (hadouken::platform::data_path() / "hadouken.json");
    }
    else
    {
        return (hadouken::platform::get_current_directory() / "hadouken.json");
    }
}

std::unique_ptr<hadouken::hosting::host> get_host(const po::variables_map& options)
{
    if (options.count("daemon"))
    {
#ifdef WIN32
        return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::service_host());
#endif
    }

    return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::console_host());
}

int main(int argc, char *argv[])
{
    po::variables_map vm = load_options(argc, argv);
    hadouken::logging::setup(vm);

    // Do platform-specific initialization as early as possible.
    hadouken::platform::init();

#ifdef WIN32
    if (vm.count("install-service"))
    {
        hadouken::platform::install_service();
        return 0;
    }
    else if (vm.count("uninstall-service"))
    {
        hadouken::platform::uninstall_service();
        return 0;
    }
#endif

    fs::path config_file = get_config_path(vm);
    pt::ptree config;

    if (!fs::exists(config_file))
    {
        BOOST_LOG_TRIVIAL(warning) << "Could not find config file at " << config_file;
    }
    else
    {
        try
        {
            pt::read_json(config_file.string(), config);
            BOOST_LOG_TRIVIAL(info) << "Loaded config file " << config_file;
        }
        catch (const std::exception& ex)
        {
            // To meet expectations, fail if the configuration file cannot be parsed. Otherwise,
            // we will revert to the default config which might be totally wrong.
            BOOST_LOG_TRIVIAL(fatal) << "Error when loading config file " << config_file << ": " << ex.what();
            return EXIT_FAILURE;
        }
    }

    boost::shared_ptr<boost::asio::io_service> io(new boost::asio::io_service());

    hadouken::application app(io, config);
    app.script_host().define_global("__CONFIG__", config_file.string());
    app.script_host().define_global("__CONFIG_PATH__", config_file.parent_path().string());

    app.start();
    int result = get_host(vm)->wait_for_exit(io);
    app.stop();

    return result;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
//added by arun
#include <SDL/SDL_timer.h>
#include <GL/glut.h>

#include "main_game.h"
#include "game_state.h"
#include "menu_state.h"
#include "globals.h"
#include "defs.h"
#include "audio.h"
#include "render_world.h" //added by arun

#define DEBUG false

/*The current game state - Menu, main game state etc...*/
int CURRENT_STATE;
/* Should the game be running?*/
bool exit_game_loop = false;

/* Initialise the sdl surface and set all SDL parameters */
int initSDL(){
  if(SDL_Init(SDL_INIT_VIDEO) !=0){
    fprintf(stderr,"Unable to init sdl: %s\n",SDL_GetError());
    return 1;
  }
  atexit(SDL_Quit);
  //To use OpenGL, you need to get some information first,
  const SDL_VideoInfo *info = SDL_GetVideoInfo();
  if(!info) {
    /* This should never happen, if it does PANIC! */
    fprintf(stderr, "Video query failed: %s\n", SDL_GetError());
    return 1;
  }
  int bpp = info->vfmt->BitsPerPixel;

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
    if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, bpp,
		       SDL_OPENGL | SDL_SWSURFACE) == 0) {
    fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
    return 1;
  }
  SDL_WM_SetCaption("The maze game",0);

  //anti aliasing consider letting people change this
  if(!strstr((char*)glGetString(GL_EXTENSIONS),
  	    "GL_ARB_multisample")){
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,true);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4);
  }
  //initialise SDL_mixer here to
  if(initAudio() !=0){
    fprintf(stderr,"Something went wrong with audio initialising");
    return 1;
  }
  return 0;
}

/*Initalize all the openGL state*/
int initGl(){
  CURRENT_STATE =-1;
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);
  //check for anistropic filtering extensions
  if(!strstr((char*)glGetString(GL_EXTENSIONS),
	     "GL_EXT_texture_filter_anisotropic")){
    anisotropic_filtering = false;
  }else{
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anistropy);
    anisotropic_filtering = true;
  }
  std::cout << "max anistropy " << max_anistropy <<std::endl;
  //start off in menu state
  set_game_state(MENU_STATE_NUMBER);
  /*No idea what this does?*/
  glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,GL_FASTEST);
  return 0;
}

void handleInput(){
  SDL_Event event;
  while(SDL_PollEvent(&event)){
    switch(event.type){
    case SDL_KEYDOWN:
      if(DEBUG)
	printf("The %s key was pressed!\n",
	       SDL_GetKeyName(event.key.keysym.sym));

      if(event.key.keysym.sym == SDLK_ESCAPE){
	exit_game_loop=true;
	break;
      }
      gameStateKeyboardDown(event.key.keysym.sym);
      break;
    case SDL_KEYUP:
      gameStateKeyboardUp(event.key.keysym.sym);
      break;
    case SDL_QUIT:
      exit_game_loop = true;
      break;
      /** mouse stuff if we ever need it
	  case SDL_MOUSEMOTION:
	  MouseMoved(
	  event.button.button,
	  event.motion.x,
	  event.motion.y,
	  event.motion.xrel,
	  event.motion.yrel);
	  break;

	  case SDL_MOUSEBUTTONUP:
	  MouseButtonUp(
	  event.button.button,
	  event.motion.x,
	  event.motion.y,
	  event.motion.xrel,
	  event.motion.yrel);
	  break;

	  case SDL_MOUSEBUTTONDOWN:
	  MouseButtonDown(
	  event.button.button,
	  event.motion.x,
	  event.motion.y,
	  event.motion.xrel,
	  event.motion.yrel);
	  break;
      */
    }
  }
}

void update(){
 SDL_Delay(5); //added by arun
  handleInput();
  gameStateTimerFunc(5, NULL); //added by arun
  gameStateUpdate();

}

void render(){
  gameStateRender();
}

void gameMainLoop(){
  while(!exit_game_loop){
    update();
    render();
  }
  gameStateFreeAll();
}

int main (int argc,char **argv){
  std::cout << "Starting Game" << std::endl;
  //game code goes here
  if(initSDL()!=0)
    exit(-1);
  if(initGl()!=0)
    exit(-1);
  gameMainLoop();
  return EXIT_SUCCESS;
}
<commit_msg>removing glut include in main as were not using glut anymore<commit_after>#include <iostream>
#include <cstdlib>

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_timer.h>

#include "main_game.h"
#include "game_state.h"
#include "menu_state.h"
#include "globals.h"
#include "defs.h"
#include "audio.h"
#include "render_world.h" //added by arun

#define DEBUG false

/*The current game state - Menu, main game state etc...*/
int CURRENT_STATE;
/* Should the game be running?*/
bool exit_game_loop = false;

/* Initialise the sdl surface and set all SDL parameters */
int initSDL(){
  if(SDL_Init(SDL_INIT_VIDEO) !=0){
    fprintf(stderr,"Unable to init sdl: %s\n",SDL_GetError());
    return 1;
  }
  atexit(SDL_Quit);
  //To use OpenGL, you need to get some information first,
  const SDL_VideoInfo *info = SDL_GetVideoInfo();
  if(!info) {
    /* This should never happen, if it does PANIC! */
    fprintf(stderr, "Video query failed: %s\n", SDL_GetError());
    return 1;
  }
  int bpp = info->vfmt->BitsPerPixel;

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
    if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, bpp,
		       SDL_OPENGL | SDL_SWSURFACE) == 0) {
    fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
    return 1;
  }
  SDL_WM_SetCaption("The maze game",0);

  //anti aliasing consider letting people change this
  if(!strstr((char*)glGetString(GL_EXTENSIONS),
  	    "GL_ARB_multisample")){
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,true);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4);
  }
  //initialise SDL_mixer here to
  if(initAudio() !=0){
    fprintf(stderr,"Something went wrong with audio initialising");
    return 1;
  }
  return 0;
}

/*Initalize all the openGL state*/
int initGl(){
  CURRENT_STATE =-1;
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);
  //check for anistropic filtering extensions
  if(!strstr((char*)glGetString(GL_EXTENSIONS),
	     "GL_EXT_texture_filter_anisotropic")){
    anisotropic_filtering = false;
  }else{
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anistropy);
    anisotropic_filtering = true;
  }
  std::cout << "max anistropy " << max_anistropy <<std::endl;
  //start off in menu state
  set_game_state(MENU_STATE_NUMBER);
  /*No idea what this does?*/
  glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,GL_FASTEST);
  return 0;
}

void handleInput(){
  SDL_Event event;
  while(SDL_PollEvent(&event)){
    switch(event.type){
    case SDL_KEYDOWN:
      if(DEBUG)
	printf("The %s key was pressed!\n",
	       SDL_GetKeyName(event.key.keysym.sym));

      if(event.key.keysym.sym == SDLK_ESCAPE){
	exit_game_loop=true;
	break;
      }
      gameStateKeyboardDown(event.key.keysym.sym);
      break;
    case SDL_KEYUP:
      gameStateKeyboardUp(event.key.keysym.sym);
      break;
    case SDL_QUIT:
      exit_game_loop = true;
      break;
      /** mouse stuff if we ever need it
	  case SDL_MOUSEMOTION:
	  MouseMoved(
	  event.button.button,
	  event.motion.x,
	  event.motion.y,
	  event.motion.xrel,
	  event.motion.yrel);
	  break;

	  case SDL_MOUSEBUTTONUP:
	  MouseButtonUp(
	  event.button.button,
	  event.motion.x,
	  event.motion.y,
	  event.motion.xrel,
	  event.motion.yrel);
	  break;

	  case SDL_MOUSEBUTTONDOWN:
	  MouseButtonDown(
	  event.button.button,
	  event.motion.x,
	  event.motion.y,
	  event.motion.xrel,
	  event.motion.yrel);
	  break;
      */
    }
  }
}

void update(){
 SDL_Delay(5); //added by arun
 handleInput();
 gameStateTimerFunc(5, NULL); //added by arun
 gameStateUpdate();
}

void render(){
  gameStateRender();
}

void gameMainLoop(){
  while(!exit_game_loop){
    update();
    render();
  }
  gameStateFreeAll();
}

int main (int argc,char **argv){
  std::cout << "Starting Game" << std::endl;
  //game code goes here
  if(initSDL()!=0)
    exit(-1);
  if(initGl()!=0)
    exit(-1);
  gameMainLoop();
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>using namespace std;

#include <iostream>
#include <string>
#include <vector>
//need these?
#include <unistd.h>     // getpid(), getcwd()
#include <sys/types.h>  // type definitions, e.g., pid_t
#include <sys/wait.h>   // wait()
#include <signal.h>     // signal name constants and kill()
#include <boost/algorithm/string.hpp>   // boost::trim_left(string s);

//Here goes the #include "files"
#include "Command.h"
#include "Connector.h"
#include "Connector.cpp"        //and / or
#include "Command.cpp"

/*

ls; lsf && echo a; echo a && lsf; lfs || echo a && echo b; echo a || lsf && echo b
*/

int main()
{

    while(true)                                     //each newline
    {
        string input = "";
        string com = "";                          //each command
        cout << "$ ";
        getline (cin,input);
        vector <string> v;                        //vector of inputs: normal, &&, ||, ;
        for(unsigned i = 0; i < input.size(); i++)       //reads input
        {
            if(input.at(i) == '#')                  //comments out the rest
            {
                break;
            }
            if(input.at(i) == ';')
            {
                v.push_back(com);
                v.push_back(";");
                com = "";
            }
            else
            {
                if(i < input.size()-1 && input.at(i) == '&' && input.at(i+1)=='&')  //&&
                {
                    i++;
                    v.push_back(com);
                    v.push_back("&&");
                    com = "";
                }
                else if(i < input.size()-1 && input.at(i) == '|' && input.at(i+1)=='|')     //||
                {
                    i++;
                    v.push_back(com);
                    v.push_back("||");
                    com = "";
                }
                else
                    com += input.at(i);               //adds to the string to be read
            }
        }
        cin.clear();
        v.push_back(com);
        bool checker = false;                           //last command's truth value

        for(unsigned i = 0; i< v.size(); i++)                         //read through v
        {
            if(v.at(i) == "exit" )
            {
                return 0;
            }
            if(v.at(i) == ";")
            {

            }
            else if(v.at(i) == "&&" )
            {
                boost::trim_left(v.at(i+1));
                andConnector* a = new andConnector(checker, v.at(i+1));
                i++;                                   //skips v.at(i+1)
                checker = a->getValidity();              //truth value of &&
            }
            else if(v.at(i) == "||" )
            {
                boost::trim_left(v.at(i+1));
                orConnector* o = new orConnector(checker, v.at(i+1));
                i++;                                    //skips v.at(i+1)
                checker = o->getValidity();             //truth value of ||
            }
            else
            {
                boost::trim_left(v.at(i));
                if(v.at(i) == "exit")
                {
                    return 0;
                }
                Command c(v.at(i));
                c.launch();
                checker = c.isValid();
            }

        }
    }
    return 0;
}

<commit_msg>cleaned up<commit_after>using namespace std;

#include <iostream>
#include <string>
#include <vector>
//need these?
#include <unistd.h>     // getpid(), getcwd()
#include <sys/types.h>  // type definitions, e.g., pid_t
#include <sys/wait.h>   // wait()
#include <signal.h>     // signal name constants and kill()
#include <boost/algorithm/string.hpp>   // boost::trim_left(string s);

//Here goes the #include "files"
#include "Command.h"
#include "Connector.h"
#include "Connector.cpp"        //and / or
#include "Command.cpp"

/*

ls; lsf && echo a; echo a && lsf; lfs || echo a && echo b; echo a || lsf && echo b
*/

int main()
{
    bool terminate = false;
    cout<<"START"<<endl;
    while(!terminate)                                     //each newline
    {
        string input = "";
        string com = "";                          //each command
        cout << "$ ";
        getline (cin,input);
        vector <string> v;                        //vector of inputs: normal, &&, ||, ;
        if(terminate)
        {
            break;
        }
        for(unsigned i = 0; i < input.size() && !terminate; i++)       //reads input
        {
            if(input.at(i) == '#')                  //comments out the rest
            {
                break;
            }
            if(input.at(i) == ';')
            {
                v.push_back(com);
                v.push_back(";");
                com = "";
            }
            else
            {
                if(i < input.size()-1 && input.at(i) == '&' && input.at(i+1)=='&')  //&&
                {
                    i++;
                    v.push_back(com);
                    v.push_back("&&");
                    com = "";
                }
                else if(i < input.size()-1 && input.at(i) == '|' && input.at(i+1)=='|')     //||
                {
                    i++;
                    v.push_back(com);
                    v.push_back("||");
                    com = "";
                }
                else
                    com += input.at(i);               //adds to the string to be read
            }
        }
        cin.clear();
        cout<<"Input Size: "<<input.size()<<endl;
        v.push_back(com);
        com = "";
        bool checker = false;                           //last command's truth value

        for(unsigned i = 0; i< v.size() && !terminate; i++)                         //read through v
        {
            cout<<">>>>>>>> "<< v.at(i)<<" <<<<<<<<<"<<endl;
            if(v.at(i) == "exit" || terminate)
            {
                cout<<"EXIT"<<endl;
                terminate = true;
                return 0;
            }
            else if(v.at(i) == ";")
            {

            }
            else if(v.at(i) == "&&" && !terminate)
            {
                boost::trim_left(v.at(i+1));
                andConnector* a = new andConnector(checker, v.at(i+1));
                i++;                                   //skips v.at(i+1)
                checker = a->getValidity();              //truth value of &&
            }
            else if(v.at(i) == "||" && !terminate)
            {
                boost::trim_left(v.at(i+1));
                orConnector* o = new orConnector(checker, v.at(i+1));
                i++;                                    //skips v.at(i+1)
                checker = o->getValidity();             //truth value of ||
            }
            else if(!terminate)
            {
                boost::trim_left(v.at(i));
                if(v.at(i) == "exit")
                {
                    terminate = true;
                    return 0;
                }
                Command c(v.at(i));
                c.launch();
                checker = c.isValid();
            }
            else
            {
                cout<<"TERMINATE"<<endl;
                return 0;
            }
        }
        if(terminate)
        {
            break;
        }
    }
    return 0;
}

<|endoftext|>