~andyc/oil

dfad5a4f0411836cacf1e3b13041d6d9c5a0b70d — Andy C 2 months ago 731af92
[refactor] Move code to .cc files.

In preparation for GC bindings.

- Remove unused code.
- Fix #include of qsn.h.
M cpp/leaky_frontend_tdop.cc => cpp/leaky_frontend_tdop.cc +1 -1
@@ 1,4 1,4 @@
#include "leaky_osh.h"
#include "leaky_osh.h"  // for arith_parse

// This code structure is odd because frontend/tdop.py would allow multiple
// TDOP parser.  Since we only have one, we just hard-code it in C++.

M cpp/leaky_frontend_tdop.h => cpp/leaky_frontend_tdop.h +1 -3
@@ 4,13 4,12 @@
#define FRONTEND_TDOP_H

#include "_build/cpp/id_kind_asdl.h"
using id_kind_asdl::Id_t;
#include "_build/cpp/syntax_asdl.h"

using id_kind_asdl::Id_t;
using syntax_asdl::arith_expr_t;
using syntax_asdl::word_t;

// move to tdop.h?
namespace tdop {

class TdopParser;  // forward declaration


@@ 35,7 34,6 @@ struct NullInfo {

class ParserSpec {
 public:
  // TODO: initialize from a table
  ParserSpec() {
  }
  LeftInfo* LookupLed(Id_t id);

M cpp/leaky_posix.cc => cpp/leaky_posix.cc +62 -0
@@ 30,5 30,67 @@ void dup2(int oldfd, int newfd) {
    throw new OSError(errno);
  }
}
void putenv(Str* name, Str* value) {
  assert(name->IsNulTerminated());
  assert(value->IsNulTerminated());
  int overwrite = 1;
  int ret = ::setenv(name->data_, value->data_, overwrite);
  if (ret < 0) {
    throw new IOError(errno);
  }
}

mylib::LineReader* fdopen(int fd, Str* c_mode) {
  mylib::Str0 c_mode0(c_mode);
  FILE* f = ::fdopen(fd, c_mode0.Get());

  // TODO: raise exception
  assert(f);

  return new mylib::CFileLineReader(f);
}

void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ) {
  mylib::Str0 _argv0(argv0);

  int n_args = len(argv);
  // never deallocated
  char** _argv = static_cast<char**>(malloc((n_args + 1) * sizeof(char*)));

  // Annoying const_cast
  // https://stackoverflow.com/questions/190184/execv-and-const-ness
  for (int i = 0; i < n_args; ++i) {
    _argv[i] = const_cast<char*>(argv->index_(i)->data_);
  }
  _argv[n_args] = nullptr;

  // Convert environ into an array of pointers to strings of the form: "k=v".
  int n_env = len(environ);
  char** envp = static_cast<char**>(malloc((n_env + 1) * sizeof(char*)));
  int i = 0;
  for (const auto& kv : environ->items_) {
    Str* k = kv.first;
    Str* v = kv.second;
    int joined_len = k->len_ + v->len_ + 1;
    char* buf = static_cast<char*>(malloc(joined_len + 1));
    memcpy(buf, k->data_, k->len_);
    buf[k->len_] = '=';
    memcpy(buf + k->len_ + 1, v->data_, v->len_);
    buf[joined_len] = '\0';
    envp[i++] = buf;
  }
  envp[n_env] = nullptr;

  int ret = ::execve(_argv0.Get(), _argv, envp);
  if (ret == -1) {
    throw new OSError(errno);
  }

  // NOTE(Jesse): ::execve() is specified to never return on success.  If we
  // hit this assertion, it returned successfully (or at least something other
  // than -1) but should have overwritten our address space with the invoked
  // process'
  InvalidCodePath();
}

}  // namespace posix

M cpp/leaky_posix.h => cpp/leaky_posix.h +3 -76
@@ 3,12 3,6 @@
#ifndef POSIX_H
#define POSIX_H

// clang-format off
#include "mycpp/myerror.h"  // for OSError; must come first
// clang-format on

#include <errno.h>
#include <stdlib.h>  // putenv
#include <unistd.h>

#include "mycpp/mylib_leaky.h"


@@ 63,16 57,6 @@ inline Str* strerror(int err_num) {
  return new Str(::strerror(err_num));
}

// TODO: write proper signatures
// stat returns stat_result
inline void stat() {
  NotImplemented();  // Uncalled
}

inline void lstat() {
  NotImplemented();  // Uncalled
}

inline Tuple2<int, int> pipe() {
  int fd[2];
  if (::pipe(fd) < 0) {


@@ 87,15 71,7 @@ inline int close(int fd) {
  return ::close(fd);
}

inline void putenv(Str* name, Str* value) {
  assert(name->IsNulTerminated());
  assert(value->IsNulTerminated());
  int overwrite = 1;
  int ret = ::setenv(name->data_, value->data_, overwrite);
  if (ret < 0) {
    throw new IOError(errno);
  }
}
void putenv(Str* name, Str* value);

inline int fork() {
  return ::fork();


@@ 114,58 90,9 @@ void dup2(int oldfd, int newfd);

int open(Str* path, int flags, int perms);

inline mylib::LineReader* fdopen(int fd, Str* c_mode) {
  mylib::Str0 c_mode0(c_mode);
  FILE* f = ::fdopen(fd, c_mode0.Get());

  // TODO: raise exception
  assert(f);

  return new mylib::CFileLineReader(f);
}

inline void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ) {
  mylib::Str0 _argv0(argv0);

  int n_args = len(argv);
  // never deallocated
  char** _argv = static_cast<char**>(malloc((n_args + 1) * sizeof(char*)));
mylib::LineReader* fdopen(int fd, Str* c_mode);

  // Annoying const_cast
  // https://stackoverflow.com/questions/190184/execv-and-const-ness
  for (int i = 0; i < n_args; ++i) {
    _argv[i] = const_cast<char*>(argv->index_(i)->data_);
  }
  _argv[n_args] = nullptr;

  // Convert environ into an array of pointers to strings of the form: "k=v".
  int n_env = len(environ);
  char** envp = static_cast<char**>(malloc((n_env + 1) * sizeof(char*)));
  int i = 0;
  for (const auto& kv : environ->items_) {
    Str* k = kv.first;
    Str* v = kv.second;
    int joined_len = k->len_ + v->len_ + 1;
    char* buf = static_cast<char*>(malloc(joined_len + 1));
    memcpy(buf, k->data_, k->len_);
    buf[k->len_] = '=';
    memcpy(buf + k->len_ + 1, v->data_, v->len_);
    buf[joined_len] = '\0';
    envp[i++] = buf;
  }
  envp[n_env] = nullptr;

  int ret = ::execve(_argv0.Get(), _argv, envp);
  if (ret == -1) {
    throw new OSError(errno);
  }

  // NOTE(Jesse): ::execve() is specified to never return on success.  If we
  // hit this assertion, it returned successfully (or at least something other
  // than -1) but should have overwritten our address space with the invoked
  // process'
  InvalidCodePath();
}
void execve(Str* argv0, List<Str*>* argv, Dict<Str*, Str*>* environ);

}  // namespace posix


M mycpp/examples/parse_preamble.h => mycpp/examples/parse_preamble.h +1 -1
@@ 1,5 1,5 @@
#include "_test/asdl/expr_asdl.h"
#include "cpp/qsn_qsn.h"
#include "cpp/qsn.h"

// For hnode::External in asdl/format.py
inline Str* repr(void* obj) {