From fad2a035cbd3194faf7b03ff7fd6e47720827ff1 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Mon, 7 Feb 2022 03:07:52 -0500 Subject: Add missing files to self-hosted directory ... Someone forgot to add them into the repo for a while. --- std/file.cup | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 std/file.cup (limited to 'std/file.cup') diff --git a/std/file.cup b/std/file.cup new file mode 100644 index 0000000..91b02e7 --- /dev/null +++ b/std/file.cup @@ -0,0 +1,99 @@ +import "std/common.cup" + +const __FILE_BUFFER_CAP = 1024; + +struct File { + fd: int; + name: char*; + // Buffer + buffer: char[__FILE_BUFFER_CAP]; + buffer_size: int; +}; + +fn fopen(name: char*, mode: char): File* { + let open_mode: int; + if (mode == 'w') open_mode = O_WRONLY | O_CREAT | O_TRUNC; + else if (mode == 'r') open_mode = O_RDONLY; + else die("Unknown file open mode"); + + let f: File* = malloc(sizeof(File)); + f.name = name; + f.fd = open(name, open_mode, 438); // 438 = 0o666 + if (f.fd < 0) + die("Could not open file"); + f.buffer_size = 0; + return f; +} + +fn fflush(f: File*) { + if (f.buffer_size > 0) { + let n = write(f.fd, f.buffer, f.buffer_size); + if (n < 0) + die("Could not write to file"); + f.buffer_size = 0; + } +} + +fn fwrite(f: File*, buf: char*, size: int) { + if (f.buffer_size + size > __FILE_BUFFER_CAP) + fflush(f); + if (size > __FILE_BUFFER_CAP) { + write(f.fd, buf, size); + } else { + memcpy(f.buffer + f.buffer_size, buf, size); + f.buffer_size = f.buffer_size + size; + } +} + +fn fread(f: File*, buf: char*, size: int): int { + let n = read(f.fd, buf, size); + if (n < 0) + die("Could not read from file"); + return n; +} + +fn fclose(f: File*) { + fflush(f); + close(f.fd); +} + +fn fputs(f: File*, s: char*) { + fwrite(f, s, strlen(s)); +} + +fn fputc(f: File*, c: char) { + fwrite(f, &c, 1); +} + +fn fputu(f: File*, n: int) { + let buf: char[32]; + let len = putu_buffer(n, buf); + fwrite(f, buf, len); +} + +// Resets file position to the beginning of the file +fn fsize(f: File*): int { + let pos = lseek(f.fd, 0, SEEK_CUR); + let size = lseek(f.fd, 0, SEEK_END); + lseek(f.fd, pos, SEEK_SET); + return size; +} + +// Map file to memory and return pointer +fn fmap(f: File*, sizeptr: int*): char* { + let size = fsize(f); + let ptr = mmap(null, size, PROT_READ, MAP_PRIVATE, f.fd, 0); + if (ptr == MAP_FAILED) + die("Could not map file"); + if (sizeptr) *sizeptr = size; + return ptr; +} + +fn fread_to_string(f: File*, sizeptr: int*): char* { + let size = fsize(f); + let text: char* = malloc(size + 1); + fread(f, text, size); + text[size] = 0; + if (sizeptr) *sizeptr = size; + return text; +} \ No newline at end of file -- cgit v1.2.3