Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason2605 committed Nov 1, 2023
2 parents ceaa85d + 85f061f commit 667dce4
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 53 deletions.
10 changes: 10 additions & 0 deletions docs/docs/standard-lib/io.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,13 @@ Prints a given list of values to stdout with an appended newline character.
IO.println("Dictu!");
// Dictu!
```

### IO.copyFile(String: src, String: dst) -> Result\<Nil>

Copies the contents from the source file to the destination file.

Returns a Result type and on success will unwrap to nil.

```cs
IO.copyFile(src, dst);
```
10 changes: 0 additions & 10 deletions docs/docs/standard-lib/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,3 @@ Note: This is not available on Windows systems.
System.mkdirTemp().unwrap(); // "VOO16s"
System.mkdirTemp("test_XXXXXX").unwrap(); // "test_0bL2qS"
```

### System.copyFile(String: src, String: dst) -> Result\<Nil>

Copies the contents from the source file to the destination file.

Returns a Result type and on success will unwrap to nil.

```cs
System.copyFile(src, dst);
```
3 changes: 2 additions & 1 deletion examples/copyFile.du
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import IO;
import Path;
import System;

Expand Down Expand Up @@ -36,7 +37,7 @@ def cleanup(tmpDir) {
print(file.read());
}

System.copyFile(Path.join(tmpDir, srcFile), Path.join(tmpDir, dstFile)).match(
IO.copyFile(Path.join(tmpDir, srcFile), Path.join(tmpDir, dstFile)).match(
def(result) => result,
def(error) => {
print(error);
Expand Down
91 changes: 91 additions & 0 deletions src/optionals/io.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
#include <fcntl.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <copyfile.h>
#elif defined(__linux__)
#include <sys/sendfile.h>
#endif

#include "io.h"


Expand Down Expand Up @@ -28,6 +38,86 @@ static Value printlnIO(DictuVM *vm, int argCount, Value *args) {
return NIL_VAL;
}

#ifdef _WIN32
static Value copyFileIO(DictuVM *vm, int argCount, Value *args) {
if (argCount != 2) {
runtimeError(vm, "copyFile() takes 2 arguments (%d given).", argCount);
return EMPTY_VAL;
}

if (!IS_STRING(args[0]) || !IS_STRING(args[1])) {
runtimeError(vm, "copyFile() arguments must be strings.");
return EMPTY_VAL;
}

char *srcFile = AS_STRING(args[0])->chars;
char *dstFile = AS_STRING(args[1])->chars;

FILE *sf = fopen(srcFile, "r");
if (sf == NULL) {
return newResultError(vm, "cannot open src file");
}

FILE *df = fopen(dstFile, "w");
if (df == NULL) {
fclose(sf);
return newResultError(vm, "cannot open dst file");
}

int buffer = fgetc(sf);
while (buffer != EOF) {
fputc(buffer, df);
buffer = fgetc(sf);
}

fclose(sf);
fclose(df);

return newResultSuccess(vm, NIL_VAL);
}
#endif

#ifndef _WIN32
static Value copyFileIO(DictuVM *vm, int argCount, Value *args) {
if (argCount != 2) {
runtimeError(vm, "copyFile() takes 2 arguments (%d given)", argCount);
return EMPTY_VAL;
}

if (!IS_STRING(args[0]) || !IS_STRING(args[1])) {
runtimeError(vm, "copyFile() arguments must be strings.");
return EMPTY_VAL;
}

char *src = AS_STRING(args[0])->chars;
char *dst = AS_STRING(args[1])->chars;

int in = 0;
int out = 0;

if ((in = open(src, O_RDONLY)) == -1) {
return newResultError(vm, "failed to open src file");
}
if ((out = creat(dst, 0660)) == -1) {
close(in);
return newResultError(vm, "failed to create/open dst file");
}

#if defined(__APPLE__) || defined(__FreeBSD__)
fcopyfile(in, out, 0, COPYFILE_ALL);
#elif defined(__linux__)
off_t bytes = 0;
struct stat fileinfo = {0};
fstat(in, &fileinfo);
sendfile(out, in, &bytes, fileinfo.st_size);
#endif
close(in);
close(out);

return newResultSuccess(vm, NIL_VAL);
}
#endif

Value createIOModule(DictuVM *vm) {
ObjString *name = copyString(vm, "IO", 2);
push(vm, OBJ_VAL(name));
Expand All @@ -43,6 +133,7 @@ Value createIOModule(DictuVM *vm) {
*/
defineNative(vm, &module->values, "print", printIO);
defineNative(vm, &module->values, "println", printlnIO);
defineNative(vm, &module->values, "copyFile", copyFileIO);

pop(vm);
pop(vm);
Expand Down
38 changes: 0 additions & 38 deletions src/optionals/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,43 +490,6 @@ static Value chmodNative(DictuVM *vm, int argCount, Value *args) {
return newResultSuccess(vm, NIL_VAL);
}

static Value copyFileNative(DictuVM *vm, int argCount, Value *args) {
if (argCount != 2) {
runtimeError(vm, "copyFile() takes 2 arguments (%d given).", argCount);
return EMPTY_VAL;
}

if (!IS_STRING(args[0]) || !IS_STRING(args[1])) {
runtimeError(vm, "copyFile() arguments must be strings.");
return EMPTY_VAL;
}

char *srcFile = AS_STRING(args[0])->chars;
char *dstFile = AS_STRING(args[1])->chars;

FILE *sf = fopen(srcFile, "r");
if (sf == NULL) {
return newResultError(vm, "cannot open src file");
}

FILE *df = fopen(dstFile, "w");
if (df == NULL) {
fclose(sf);
return newResultError(vm, "cannot open dst file");
}

int buffer = fgetc(sf);
while (buffer != EOF) {
fputc(buffer, df);
buffer = fgetc(sf);
}

fclose(sf);
fclose(df);

return newResultSuccess(vm, NIL_VAL);
}

void initArgv(DictuVM *vm, Table *table, int argc, char **argv) {
ObjList *list = newList(vm);
push(vm, OBJ_VAL(list));
Expand Down Expand Up @@ -627,7 +590,6 @@ Value createSystemModule(DictuVM *vm) {
defineNative(vm, &module->values, "sleep", sleepNative);
defineNative(vm, &module->values, "exit", exitNative);
defineNative(vm, &module->values, "chmod", chmodNative);
defineNative(vm, &module->values, "copyFile", copyFileNative);

/**
* Define System properties
Expand Down
7 changes: 4 additions & 3 deletions tests/system/copyFile.du → tests/io/copyFile.du
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/**
* copyFile.du
*
* Testing the System.copyFile() function
* Testing the IO.copyFile() function
*
* copyFile() copies the contents from the source file to the
* destination file.
*/
from UnitTest import UnitTest;

import IO;
import Path;
import System;

Expand Down Expand Up @@ -42,11 +43,11 @@ class TestSystemCopyFile < UnitTest {
const srcFullPath = Path.join(this.tmpDir, srcFile);
const dstFullPath = Path.join(this.tmpDir, dstFile);

const res = System.copyFile(srcFullPath, dstFullPath);
const res = IO.copyFile(srcFullPath, dstFullPath);

this.assertNotNil(res);
this.assertSuccess(res);
}
}

TestSystemCopyFile().run();
TestSystemCopyFile().run();
7 changes: 7 additions & 0 deletions tests/io/import.du
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* import.du
*
* General import file for the IO module tests
*/

import "copyFile.du";
1 change: 1 addition & 0 deletions tests/runTests.du
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import "base64/import.du";
import "sqlite/import.du";
import "process/import.du";
import "inspect/import.du";
import "io/import.du";
import "unittest/import.du";

if (isDefined("HTTP")) {
Expand Down
1 change: 0 additions & 1 deletion tests/system/import.du
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import "access.du";
import "copyFile.du";
import "version.du";
import "sleep.du";
import "getCWD.du";
Expand Down

0 comments on commit 667dce4

Please sign in to comment.