~andyc/oil

43e170d7e36beb819d4dc184fb9b7d4d4cae9fde — Andy C 2 months ago a2c2cd2
[refactor] Consolidate small files into cpp/leaky_core.{cc,h}

Also move more code into .cc files.
9 files changed, 189 insertions(+), 199 deletions(-)

M cpp/NINJA_subgraph.py
M cpp/leaky_binding_test.cc
R cpp/{leaky_core_pyos.cc => leaky_core.cc}
R cpp/{leaky_core_pyos.h => leaky_core.h}
D cpp/leaky_core_pyutil.cc
D cpp/leaky_core_pyutil.h
M cpp/leaky_preamble.h
M cpp/leaky_pylib.h
M cpp/test.sh
M cpp/NINJA_subgraph.py => cpp/NINJA_subgraph.py +1 -2
@@ 79,8 79,7 @@ def log(msg, *args):


DEPS_CC = [
    'cpp/leaky_core_pyos.cc',
    'cpp/leaky_core_pyutil.cc',
    'cpp/leaky_core.cc',
    'cpp/leaky_frontend_flag_spec.cc',
    'cpp/leaky_frontend_match.cc',
    'cpp/leaky_frontend_tdop.cc',

M cpp/leaky_binding_test.cc => cpp/leaky_binding_test.cc +1 -2
@@ 7,10 7,9 @@

#include "_build/cpp/runtime_asdl.h"  // cell, etc
#include "_devbuild/gen/id.h"
#include "leaky_core.h"  // Chdir
#include "leaky_core_error.h"
#include "leaky_core_pyerror.h"
#include "leaky_core_pyos.h"  // Chdir
#include "leaky_core_pyutil.h"
#include "leaky_frontend_match.h"
#include "leaky_libc.h"
#include "leaky_osh_bool_stat.h"

R cpp/leaky_core_pyos.cc => cpp/leaky_core.cc +146 -4
@@ 1,11 1,19 @@
// core_pyos.cc

#include "leaky_core_pyos.h"  // undefined errno
// clang-format off
#include "mycpp/myerror.h"
// clang-format on

#include <pwd.h>
#include "leaky_core.h"

#include <errno.h>
#include <pwd.h>  // passwd
#include <signal.h>
#include <sys/wait.h>  // waitpid()
#include <unistd.h>    // getuid(), environ
#include <sys/resource.h>  // getrusage
#include <sys/times.h>     // tms / times()
#include <sys/utsname.h>   // uname
#include <sys/wait.h>      // waitpid()
#include <unistd.h>        // getuid(), environ

namespace pyos {



@@ 116,6 124,73 @@ Str* GetHomeDir(Str* user_name) {
  return CopyStr(entry->pw_dir);
}

Str* GetUserName(int uid) {
  Str* result = kEmptyString;

  if (passwd* pw = getpwuid(uid)) {
    result = new Str(pw->pw_name);
  } else {
    throw new IOError(errno);
  }

  return result;
}

Str* OsType() {
  Str* result = kEmptyString;

  utsname un = {};
  if (::uname(&un) == 0) {
    result = new Str(un.sysname);
  } else {
    throw new IOError(errno);
  }

  return result;
}

Tuple3<double, double, double> Time() {
  rusage ru;  // NOTE(Jesse): Doesn't have to be cleared to 0.  The kernel
              // clears unused fields.
  if (::getrusage(RUSAGE_SELF, &ru) == -1) {
    throw new IOError(errno);
  }

  time_t t = time_::time();
  auto result = Tuple3<double, double, double>(
      (double)t, (double)ru.ru_utime.tv_sec, (double)ru.ru_stime.tv_sec);
  return result;
}

void PrintTimes() {
  tms t;
  if (times(&t) == -1) {
    throw new IOError(errno);
  } else {
    {
      int user_minutes = t.tms_utime / 60;
      float user_seconds = t.tms_utime % 60;
      int system_minutes = t.tms_stime / 60;
      float system_seconds = t.tms_stime % 60;
      printf("%dm%1.3fs %dm%1.3fs", user_minutes, user_seconds, system_minutes,
             system_seconds);
    }

    {
      int child_user_minutes = t.tms_cutime / 60;
      float child_user_seconds = t.tms_cutime % 60;
      int child_system_minutes = t.tms_cstime / 60;
      float child_system_seconds = t.tms_cstime % 60;
      printf("%dm%1.3fs %dm%1.3fs", child_user_minutes, child_user_seconds,
             child_system_minutes, child_system_seconds);
    }
  }
}

bool InputAvailable(int fd) {
  NotImplemented();
}

void SignalState_AfterForkingChild() {
  signal(SIGQUIT, SIG_DFL);
  signal(SIGPIPE, SIG_DFL);


@@ 123,3 198,70 @@ void SignalState_AfterForkingChild() {
}

}  // namespace pyos

namespace pyutil {

bool IsValidCharEscape(int c) {
  if (c == '/' || c == '.' || c == '-') {
    return false;
  }
  if (c == ' ') {  // foo\ bar is idiomatic
    return true;
  }
  return ispunct(c);
}

Str* ChArrayToString(List<int>* ch_array) {
  int n = len(ch_array);
  unsigned char* buf = static_cast<unsigned char*>(malloc(n + 1));
  for (int i = 0; i < n; ++i) {
    buf[i] = ch_array->index_(i);
  }
  buf[n] = '\0';
  return new Str(reinterpret_cast<char*>(buf), n);
}

Str* _ResourceLoader::Get(Str* path) {
  return new Str("TODO");
}

_ResourceLoader* GetResourceLoader() {
  return new _ResourceLoader();
}

void CopyFile(Str* in_path, Str* out_path) {
  assert(0);
}

Str* GetVersion(_ResourceLoader* loader) {
  return new Str("TODO");
}

Str* ShowAppVersion(Str* app_name, _ResourceLoader* loader) {
  assert(0);
}

Str* BackslashEscape(Str* s, Str* meta_chars) {
  int upper_bound = s->len_ * 2;
  char* buf = static_cast<char*>(malloc(upper_bound));
  char* p = buf;

  for (int i = 0; i < s->len_; ++i) {
    char c = s->data_[i];
    if (memchr(meta_chars->data_, c, meta_chars->len_)) {
      *p++ = '\\';
    }
    *p++ = c;
  }
  int len = p - buf;
  return new Str(buf, len);
}

// Hack so e->errno will work below
#undef errno

Str* strerror(_OSError* e) {
  return new Str(::strerror(e->errno));
}

}  // namespace pyutil

R cpp/leaky_core_pyos.h => cpp/leaky_core.h +35 -80
@@ 1,20 1,10 @@
// leaky_core_pyos.h: Replacement for core/pyos.py
// leaky_core.h: Replacement for core/*.py

#ifndef CORE_PYOS_H
#define CORE_PYOS_H
#ifndef LEAKY_CORE_H
#define LEAKY_CORE_H

// clang-format off
#include "mycpp/myerror.h"
// clang-format on

#include <pwd.h>           // passwd
#include <sys/resource.h>  // getrusage
#include <sys/times.h>     // tms / times()
#include <sys/utsname.h>   // uname
#include <termios.h>

#include <cerrno>

#include "_build/cpp/syntax_asdl.h"
#include "leaky_time_.h"
#include "mycpp/mylib_leaky.h"


@@ 47,68 37,11 @@ class ReadError {
  int err_num;
};

inline Str* GetUserName(int uid) {
  Str* result = kEmptyString;

  if (passwd* pw = getpwuid(uid)) {
    result = new Str(pw->pw_name);
  } else {
    throw new IOError(errno);
  }

  return result;
}

inline Str* OsType() {
  Str* result = kEmptyString;

  utsname un = {};
  if (::uname(&un) == 0) {
    result = new Str(un.sysname);
  } else {
    throw new IOError(errno);
  }

  return result;
}

inline Tuple3<double, double, double> Time() {
  rusage ru;  // NOTE(Jesse): Doesn't have to be cleared to 0.  The kernel
              // clears unused fields.
  if (::getrusage(RUSAGE_SELF, &ru) == -1) {
    throw new IOError(errno);
  }

  time_t t = time_::time();
  auto result = Tuple3<double, double, double>(
      (double)t, (double)ru.ru_utime.tv_sec, (double)ru.ru_stime.tv_sec);
  return result;
}

inline void PrintTimes() {
  tms t;
  if (times(&t) == -1) {
    throw new IOError(errno);
  } else {
    {
      int user_minutes = t.tms_utime / 60;
      float user_seconds = t.tms_utime % 60;
      int system_minutes = t.tms_stime / 60;
      float system_seconds = t.tms_stime % 60;
      printf("%dm%1.3fs %dm%1.3fs", user_minutes, user_seconds, system_minutes,
             system_seconds);
    }

    {
      int child_user_minutes = t.tms_cutime / 60;
      float child_user_seconds = t.tms_cutime % 60;
      int child_system_minutes = t.tms_cstime / 60;
      float child_system_seconds = t.tms_cstime % 60;
      printf("%dm%1.3fs %dm%1.3fs", child_user_minutes, child_user_seconds,
             child_system_minutes, child_system_seconds);
    }
  }
}
Str* GetUserName(int uid);
Str* OsType();
Tuple3<double, double, double> Time();
void PrintTimes();
bool InputAvailable(int fd);

class TermState {
 public:


@@ 120,10 53,6 @@ class TermState {
  }
};

inline bool InputAvailable(int fd) {
  assert(0);
}

void SignalState_AfterForkingChild();

class SignalState {


@@ 145,4 74,30 @@ class SignalState {

}  // namespace pyos

#endif  // CORE_PYOS_H
class _OSError;  // declaration from mycpp/myerror.h

namespace pyutil {

bool IsValidCharEscape(int c);
Str* ChArrayToString(List<int>* ch_array);

class _ResourceLoader {
 public:
  virtual Str* Get(Str* path);
};

_ResourceLoader* GetResourceLoader();

void CopyFile(Str* in_path, Str* out_path);

Str* GetVersion(_ResourceLoader* loader);

Str* ShowAppVersion(Str* app_name, _ResourceLoader* loader);

Str* strerror(_OSError* e);

Str* BackslashEscape(Str* s, Str* meta_chars);

}  // namespace pyutil

#endif  // LEAKY_CORE_H

D cpp/leaky_core_pyutil.cc => cpp/leaky_core_pyutil.cc +0 -55
@@ 1,55 0,0 @@
// core_pyutil.cc

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

#include "leaky_core_pyutil.h"

namespace pyutil {

bool IsValidCharEscape(int c) {
  if (c == '/' || c == '.' || c == '-') {
    return false;
  }
  if (c == ' ') {  // foo\ bar is idiomatic
    return true;
  }
  return ispunct(c);
}

Str* ChArrayToString(List<int>* ch_array) {
  int n = len(ch_array);
  unsigned char* buf = static_cast<unsigned char*>(malloc(n + 1));
  for (int i = 0; i < n; ++i) {
    buf[i] = ch_array->index_(i);
  }
  buf[n] = '\0';
  return new Str(reinterpret_cast<char*>(buf), n);
}

Str* _ResourceLoader::Get(Str* path) {
  return new Str("TODO");
}

_ResourceLoader* GetResourceLoader() {
  return new _ResourceLoader();
}

void CopyFile(Str* in_path, Str* out_path) {
  assert(0);
}

Str* GetVersion(_ResourceLoader* loader) {
  return new Str("TODO");
}

Str* ShowAppVersion(Str* app_name, _ResourceLoader* loader) {
  assert(0);
}

Str* strerror(_OSError* e) {
  return new Str(::strerror(e->errno));
}

}  // namespace pyutil

D cpp/leaky_core_pyutil.h => cpp/leaky_core_pyutil.h +0 -48
@@ 1,48 0,0 @@
// leaky_core_pyutil.h

#ifndef CORE_PYUTIL_H
#define CORE_PYUTIL_H

#include "mycpp/mylib_leaky.h"

class _OSError;  // declaration from mycpp/myerror.h

namespace pyutil {

bool IsValidCharEscape(int c);
Str* ChArrayToString(List<int>* ch_array);

class _ResourceLoader {
 public:
  virtual Str* Get(Str* path);
};

_ResourceLoader* GetResourceLoader();

void CopyFile(Str* in_path, Str* out_path);

Str* GetVersion(_ResourceLoader* loader);

Str* ShowAppVersion(Str* app_name, _ResourceLoader* loader);

Str* strerror(_OSError* e);

inline Str* BackslashEscape(Str* s, Str* meta_chars) {
  int upper_bound = s->len_ * 2;
  char* buf = static_cast<char*>(malloc(upper_bound));
  char* p = buf;

  for (int i = 0; i < s->len_; ++i) {
    char c = s->data_[i];
    if (memchr(meta_chars->data_, c, meta_chars->len_)) {
      *p++ = '\\';
    }
    *p++ = c;
  }
  int len = p - buf;
  return new Str(buf, len);
}

}  // namespace pyutil

#endif  // CORE_PYUTIL_H

M cpp/leaky_preamble.h => cpp/leaky_preamble.h +1 -2
@@ 27,9 27,8 @@ using id_kind_asdl::Kind_t;
// oil/cpp
#include "leaky_core_error.h"
//#include "core_process.h"
#include "leaky_core.h"
#include "leaky_core_pyerror.h"
#include "leaky_core_pyos.h"
#include "leaky_core_pyutil.h"
#include "leaky_fcntl_.h"
#include "leaky_frontend_flag_spec.h"
#include "leaky_frontend_match.h"

M cpp/leaky_pylib.h => cpp/leaky_pylib.h +4 -4
@@ 1,7 1,7 @@
// leaky_pylib_os_path.h
// leaky_pylib.h: Replacement for pylib/*.py

#ifndef PYLIB_OS_PATH_H
#define PYLIB_OS_PATH_H
#ifndef LEAKY_PYLIB_H
#define LEAKY_PYLIB_H

#if 1  // TODO: switch this off
#include "mycpp/mylib_leaky.h"


@@ 21,4 21,4 @@ bool exists(Str* path);

}  // namespace path_stat

#endif  // PYLIB_OS_PATH_H
#endif  // LEAKY_PYLIB_H

M cpp/test.sh => cpp/test.sh +1 -2
@@ 52,8 52,7 @@ leaky-flag-spec-test() {

readonly LEAKY_TEST_SRC=(
    cpp/leaky_binding_test.cc \
    cpp/leaky_core_pyos.cc \
    cpp/leaky_core_pyutil.cc \
    cpp/leaky_core.cc \
    cpp/leaky_frontend_match.cc \
    cpp/leaky_libc.cc \
    cpp/leaky_osh_bool_stat.cc \