Skip to content

Commit

Permalink
[cpp] Add RootsFrame to libc bindings (#1411)
Browse files Browse the repository at this point in the history
  • Loading branch information
melvinw committed Nov 14, 2022
1 parent 0ec4805 commit 8d11ad1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
15 changes: 14 additions & 1 deletion cpp/libc.cc
Expand Up @@ -12,6 +12,7 @@
namespace libc {

Str* gethostname() {
NO_ROOTS_FRAME(FUNC_NAME); // OverAllocatedStr() does it
Str* result = OverAllocatedStr(HOST_NAME_MAX);
int status = ::gethostname(result->data_, HOST_NAME_MAX);
if (status != 0) {
Expand All @@ -23,6 +24,7 @@ Str* gethostname() {
}

int fnmatch(Str* pat, Str* str) {
NO_ROOTS_FRAME(FUNC_NAME); // No allocaitons here
int flags = FNM_EXTMATCH;
int result = ::fnmatch(pat->data_, str->data_, flags);
switch (result) {
Expand All @@ -37,6 +39,7 @@ int fnmatch(Str* pat, Str* str) {
}

List<Str*>* glob(Str* pat) {
RootsFrame _r{FUNC_NAME};
glob_t results;
// Hm, it's weird that the first one can't be called with GLOB_APPEND. You
// get a segfault.
Expand Down Expand Up @@ -75,17 +78,20 @@ List<Str*>* glob(Str* pat) {
// Print array of results
size_t i;
for (i = 0; i < n; i++) {
NO_ROOTS_FRAME(LOOP); // Allocations are retained through `matches`
const char* m = results.gl_pathv[i];
matches->append(StrFromC(m));
}
globfree(&results);

gHeap.RootOnReturn(matches);
return matches;
}

// Raises RuntimeError if the pattern is invalid. TODO: Use a different
// exception?
List<Str*>* regex_match(Str* pattern, Str* str) {
RootsFrame _r{FUNC_NAME};
List<Str*>* results = NewList<Str*>();

regex_t pat;
Expand All @@ -103,6 +109,7 @@ List<Str*>* regex_match(Str* pattern, Str* str) {
if (match) {
int i;
for (i = 0; i < outlen; i++) {
NO_ROOTS_FRAME(LOOP); // Allocations are retained through `results`
int len = pmatch[i].rm_eo - pmatch[i].rm_so;
Str* m = StrFromC(s0 + pmatch[i].rm_so, len);
results->append(m);
Expand All @@ -116,6 +123,7 @@ List<Str*>* regex_match(Str* pattern, Str* str) {
return nullptr;
}

gHeap.RootOnReturn(results);
return results;
}

Expand All @@ -128,6 +136,7 @@ const int NMATCH = 2;

// Odd: This a Tuple2* not Tuple2 because it's Optional[Tuple2]!
Tuple2<int, int>* regex_first_group_match(Str* pattern, Str* str, int pos) {
RootsFrame _r{FUNC_NAME};
regex_t pat;
regmatch_t m[NMATCH];

Expand Down Expand Up @@ -158,7 +167,11 @@ Tuple2<int, int>* regex_first_group_match(Str* pattern, Str* str, int pos) {
// Assume there is a match
regoff_t start = m[1].rm_so;
regoff_t end = m[1].rm_eo;
return Alloc<Tuple2<int, int>>(pos + start, pos + end);
Tuple2<int, int>* tup = Alloc<Tuple2<int, int>>(pos + start, pos + end);

// Tuple2<...> uses the OBJ_HEADER macro
gHeap.RootOnReturn(reinterpret_cast<Obj*>(tup));
return tup;
}

} // namespace libc
14 changes: 14 additions & 0 deletions cpp/libc_test.cc
@@ -1,8 +1,21 @@
#include "cpp/libc.h"

#include <unistd.h> // gethostname()

#include "mycpp/runtime.h"
#include "vendor/greatest.h"

TEST hostname_test() {
Str* s0 = libc::gethostname();
ASSERT(s0 != nullptr);

char buf[1024];
ASSERT(gethostname(buf, HOST_NAME_MAX) == 0);
ASSERT(str_equals(s0, StrFromC(buf)));

PASS();
}

TEST libc_test() {
Str* s1 = (StrFromC("foo.py "))->strip();
ASSERT(libc::fnmatch(StrFromC("*.py"), s1));
Expand Down Expand Up @@ -65,6 +78,7 @@ int main(int argc, char** argv) {

RUN_TEST(libc_test);
RUN_TEST(libc_glob_test);
RUN_TEST(hostname_test);

gHeap.CleanProcessExit();

Expand Down

0 comments on commit 8d11ad1

Please sign in to comment.