mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix on rethrow + macros.
This commit is contained in:
@@ -375,7 +375,7 @@ fn void DString.reserve(DString* str, usz addition)
|
|||||||
*str = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator);
|
*str = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! DString.read_from_stream(DString* string, Stream* reader)
|
fn usz! DString.read_from_stream(DString* string, Stream reader)
|
||||||
{
|
{
|
||||||
if (reader.supports_available())
|
if (reader.supports_available())
|
||||||
{
|
{
|
||||||
|
|||||||
65
lib/std/encoding/csv.c3
Normal file
65
lib/std/encoding/csv.c3
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
module std::encoding::csv;
|
||||||
|
import std::io;
|
||||||
|
|
||||||
|
struct CsvReader
|
||||||
|
{
|
||||||
|
Stream stream;
|
||||||
|
String separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void CsvReader.init_file(CsvReader* csv, File* file, String separator = ",")
|
||||||
|
{
|
||||||
|
csv.stream = file.as_stream();
|
||||||
|
csv.separator = separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void CsvReader.init(CsvReader* csv, Stream stream, String separator = ",")
|
||||||
|
{
|
||||||
|
csv.stream = stream;
|
||||||
|
csv.separator = separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn String[]! CsvReader.read_row(CsvReader csv, Allocator* using = mem::heap())
|
||||||
|
{
|
||||||
|
@stack_mem(512; Allocator* mem)
|
||||||
|
{
|
||||||
|
return csv.stream.readline(mem).split(csv.separator, .using = using);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn String[]! CsvReader.tread_row(CsvReader csv)
|
||||||
|
{
|
||||||
|
return csv.read_row(mem::temp()) @inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void! CsvReader.skip_row(CsvReader csv) @maydiscard
|
||||||
|
{
|
||||||
|
@pool()
|
||||||
|
{
|
||||||
|
csv.stream.readline(mem::temp())!;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro CsvReader.@each_row(CsvReader csv, int rows = int.max; @body(String[] row))
|
||||||
|
{
|
||||||
|
Stream stream = csv.stream;
|
||||||
|
String sep = csv.separator;
|
||||||
|
while (rows--)
|
||||||
|
{
|
||||||
|
@stack_mem(512; Allocator* mem)
|
||||||
|
{
|
||||||
|
String[] parts;
|
||||||
|
@pool()
|
||||||
|
{
|
||||||
|
String! s = stream.readline(mem::temp());
|
||||||
|
if (catch err = s)
|
||||||
|
{
|
||||||
|
if (err == IoError.EOF) return;
|
||||||
|
return err?;
|
||||||
|
}
|
||||||
|
parts = s.split(sep, .using = mem);
|
||||||
|
};
|
||||||
|
@body(parts);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
module std::io;
|
module std::io;
|
||||||
|
|
||||||
def CloseStreamFn = fn void!(Stream*);
|
def CloseStreamFn = fn void!(Stream);
|
||||||
def FlushStreamFn = fn void!(Stream*);
|
def FlushStreamFn = fn void!(Stream);
|
||||||
def SeekStreamFn = fn usz!(Stream*, isz offset, Seek seek);
|
def SeekStreamFn = fn usz!(Stream, isz offset, Seek seek);
|
||||||
def LenStreamFn = fn usz(Stream*);
|
def LenStreamFn = fn usz(Stream);
|
||||||
def AvailableStreamFn = fn usz(Stream*);
|
def AvailableStreamFn = fn usz(Stream);
|
||||||
def ReadStreamFn = fn usz!(Stream*, char[] bytes);
|
def ReadStreamFn = fn usz!(Stream, char[] bytes);
|
||||||
def ReadFromStreamFn = fn usz!(Stream*, Stream*);
|
def ReadFromStreamFn = fn usz!(Stream, Stream);
|
||||||
def ReadByteStreamFn = fn char!(Stream*);
|
def ReadByteStreamFn = fn char!(Stream);
|
||||||
def PushbackByteStreamFn = fn void!(Stream*);
|
def PushbackByteStreamFn = fn void!(Stream);
|
||||||
def WriteStreamFn = fn usz!(Stream*, char[] bytes);
|
def WriteStreamFn = fn usz!(Stream, char[] bytes);
|
||||||
def WriteToStreamFn = fn usz!(Stream*, Stream* out);
|
def WriteToStreamFn = fn usz!(Stream, Stream out);
|
||||||
def WriteByteStreamFn = fn void!(Stream*, char c);
|
def WriteByteStreamFn = fn void!(Stream, char c);
|
||||||
def DestroyStreamFn = fn void!(Stream*);
|
def DestroyStreamFn = fn void!(Stream);
|
||||||
|
|
||||||
struct StreamInterface
|
struct StreamInterface
|
||||||
{
|
{
|
||||||
@@ -37,33 +37,33 @@ struct Stream
|
|||||||
void* data;
|
void* data;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bool Stream.supports_seek(Stream* s) @inline => (bool)s.fns.seek_fn;
|
fn bool Stream.supports_seek(Stream s) @inline => (bool)s.fns.seek_fn;
|
||||||
fn bool Stream.supports_available(Stream* s) @inline => s.fns.available_fn || s.fns.seek_fn;
|
fn bool Stream.supports_available(Stream s) @inline => s.fns.available_fn || s.fns.seek_fn;
|
||||||
fn bool Stream.supports_len(Stream* s) @inline => s.fns.len_fn || s.fns.seek_fn;
|
fn bool Stream.supports_len(Stream s) @inline => s.fns.len_fn || s.fns.seek_fn;
|
||||||
fn bool Stream.supports_read(Stream* s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
|
fn bool Stream.supports_read(Stream s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
|
||||||
fn bool Stream.supports_read_from(Stream* s) @inline => (bool)s.fns.read_stream_fn;
|
fn bool Stream.supports_read_from(Stream s) @inline => (bool)s.fns.read_stream_fn;
|
||||||
fn bool Stream.supports_write_to(Stream* s) @inline => (bool)s.fns.write_stream_fn;
|
fn bool Stream.supports_write_to(Stream s) @inline => (bool)s.fns.write_stream_fn;
|
||||||
fn bool Stream.supports_pushback_byte(Stream* s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
|
fn bool Stream.supports_pushback_byte(Stream s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
|
||||||
fn bool Stream.supports_write(Stream* s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
|
fn bool Stream.supports_write(Stream s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
|
||||||
|
|
||||||
fn void! Stream.destroy(Stream* s) @inline @maydiscard
|
fn void! Stream.destroy(Stream s) @inline @maydiscard
|
||||||
{
|
{
|
||||||
if (s.fns.destroy_fn) return s.fns.destroy_fn(s);
|
if (s.fns.destroy_fn) return s.fns.destroy_fn(s);
|
||||||
return s.close();
|
return s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Stream.close(Stream* s) @inline @maydiscard
|
fn void! Stream.close(Stream s) @inline @maydiscard
|
||||||
{
|
{
|
||||||
if (CloseStreamFn func = s.fns.close_fn) return func(s);
|
if (CloseStreamFn func = s.fns.close_fn) return func(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.seek(Stream* s, isz offset, Seek seek) @inline
|
fn usz! Stream.seek(Stream s, isz offset, Seek seek) @inline
|
||||||
{
|
{
|
||||||
if (SeekStreamFn func = s.fns.seek_fn) return func(s, offset, seek);
|
if (SeekStreamFn func = s.fns.seek_fn) return func(s, offset, seek);
|
||||||
return IoError.NOT_SEEKABLE?;
|
return IoError.NOT_SEEKABLE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.available(Stream* s) @inline
|
fn usz! Stream.available(Stream s) @inline
|
||||||
{
|
{
|
||||||
if (AvailableStreamFn func = s.fns.available_fn) return func(s);
|
if (AvailableStreamFn func = s.fns.available_fn) return func(s);
|
||||||
if (SeekStreamFn func = s.fns.seek_fn)
|
if (SeekStreamFn func = s.fns.seek_fn)
|
||||||
@@ -76,7 +76,7 @@ fn usz! Stream.available(Stream* s) @inline
|
|||||||
return IoError.NOT_SEEKABLE?;
|
return IoError.NOT_SEEKABLE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.read(Stream* s, char[] buffer)
|
fn usz! Stream.read(Stream s, char[] buffer)
|
||||||
{
|
{
|
||||||
if (ReadStreamFn func = s.fns.read_fn) return func(s, buffer);
|
if (ReadStreamFn func = s.fns.read_fn) return func(s, buffer);
|
||||||
if (ReadByteStreamFn func = s.fns.read_byte_fn)
|
if (ReadByteStreamFn func = s.fns.read_byte_fn)
|
||||||
@@ -97,13 +97,40 @@ fn usz! Stream.read(Stream* s, char[] buffer)
|
|||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn char! Stream.read_byte(Stream* s) @inline
|
fn char! Stream.read_byte(Stream s) @inline
|
||||||
{
|
{
|
||||||
if (ReadByteStreamFn func = s.fns.read_byte_fn) return func(s);
|
if (ReadByteStreamFn func = s.fns.read_byte_fn) return func(s);
|
||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.write(Stream* s, char[] bytes) @inline
|
fn String! Stream.readline(Stream s, Allocator* using = mem::heap())
|
||||||
|
{
|
||||||
|
ReadByteStreamFn func;
|
||||||
|
if (func = s.fns.read_byte_fn, !func) return IoError.UNSUPPORTED_OPERATION?;
|
||||||
|
bool read = false;
|
||||||
|
char val = func(s)!;
|
||||||
|
if (val == '\n') return "";
|
||||||
|
@stack_mem(256 + 64; Allocator* mem)
|
||||||
|
{
|
||||||
|
DString str = dstring::new_with_capacity(256, .using = mem);
|
||||||
|
if (val != '\r') str.append(val);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char! c = func(s);
|
||||||
|
if (catch err = c)
|
||||||
|
{
|
||||||
|
if (err == IoError.EOF) break;
|
||||||
|
return err?;
|
||||||
|
}
|
||||||
|
if (c == '\r') continue;
|
||||||
|
if (c == '\n') break;
|
||||||
|
str.append_char(c);
|
||||||
|
}
|
||||||
|
return str.copy_str(using);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usz! Stream.write(Stream s, char[] bytes) @inline
|
||||||
{
|
{
|
||||||
if (WriteStreamFn func = s.fns.write_fn) return func(s, bytes);
|
if (WriteStreamFn func = s.fns.write_fn) return func(s, bytes);
|
||||||
if (WriteByteStreamFn func = s.fns.write_byte_fn)
|
if (WriteByteStreamFn func = s.fns.write_byte_fn)
|
||||||
@@ -114,31 +141,31 @@ fn usz! Stream.write(Stream* s, char[] bytes) @inline
|
|||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Stream.write_byte(Stream* s, char b) @inline
|
fn void! Stream.write_byte(Stream s, char b) @inline
|
||||||
{
|
{
|
||||||
if (WriteByteStreamFn func = s.fns.write_byte_fn) return func(s, b);
|
if (WriteByteStreamFn func = s.fns.write_byte_fn) return func(s, b);
|
||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.write_to(Stream* s, Stream* to) @inline
|
fn usz! Stream.write_to(Stream s, Stream to) @inline
|
||||||
{
|
{
|
||||||
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, to);
|
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, to);
|
||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.read_from(Stream* s, Stream* from) @inline
|
fn usz! Stream.read_from(Stream s, Stream from) @inline
|
||||||
{
|
{
|
||||||
if (ReadFromStreamFn func = s.fns.read_stream_fn) return func(s, from);
|
if (ReadFromStreamFn func = s.fns.read_stream_fn) return func(s, from);
|
||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Stream.flush(Stream* s) @inline @maydiscard
|
fn void! Stream.flush(Stream s) @inline @maydiscard
|
||||||
{
|
{
|
||||||
if (FlushStreamFn func = s.fns.flush_fn) return func(s);
|
if (FlushStreamFn func = s.fns.flush_fn) return func(s);
|
||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! Stream.len(Stream* s) @inline
|
fn usz! Stream.len(Stream s) @inline
|
||||||
{
|
{
|
||||||
if (LenStreamFn func = s.fns.len_fn) return func(s);
|
if (LenStreamFn func = s.fns.len_fn) return func(s);
|
||||||
if (SeekStreamFn func = s.fns.seek_fn)
|
if (SeekStreamFn func = s.fns.seek_fn)
|
||||||
@@ -151,7 +178,7 @@ fn usz! Stream.len(Stream* s) @inline
|
|||||||
return IoError.NOT_SEEKABLE?;
|
return IoError.NOT_SEEKABLE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Stream.pushback_byte(Stream* s) @inline
|
fn void! Stream.pushback_byte(Stream s) @inline
|
||||||
{
|
{
|
||||||
if (PushbackByteStreamFn func = s.fns.pushback_byte_fn) return func(s);
|
if (PushbackByteStreamFn func = s.fns.pushback_byte_fn) return func(s);
|
||||||
if (SeekStreamFn func = s.fns.seek_fn)
|
if (SeekStreamFn func = s.fns.seek_fn)
|
||||||
@@ -162,9 +189,9 @@ fn void! Stream.pushback_byte(Stream* s) @inline
|
|||||||
return IoError.UNSUPPORTED_OPERATION?;
|
return IoError.UNSUPPORTED_OPERATION?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Stream.write_string(Stream* s, String str) @inline => (void)(s.write((char[])str)!);
|
fn void! Stream.write_string(Stream s, String str) @inline => (void)(s.write((char[])str)!);
|
||||||
|
|
||||||
fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {})
|
fn usz! Stream.copy_to(Stream s, Stream dst, char[] buffer = {})
|
||||||
{
|
{
|
||||||
if (buffer.len) return copy_through_buffer(s, dst, buffer);
|
if (buffer.len) return copy_through_buffer(s, dst, buffer);
|
||||||
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, dst);
|
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, dst);
|
||||||
@@ -186,7 +213,7 @@ fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {})
|
|||||||
$endswitch
|
$endswitch
|
||||||
}
|
}
|
||||||
|
|
||||||
macro usz! copy_through_buffer(Stream* s, Stream* dst, char[] buffer) @local
|
macro usz! copy_through_buffer(Stream s, Stream dst, char[] buffer) @local
|
||||||
{
|
{
|
||||||
usz total_copied;
|
usz total_copied;
|
||||||
while (true)
|
while (true)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ fn usz! ByteReader.seek(ByteReader* reader, isz offset, Seek seek)
|
|||||||
return new_index;
|
return new_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usz! ByteReader.write_stream(ByteReader* reader, Stream* writer)
|
fn usz! ByteReader.write_stream(ByteReader* reader, Stream writer)
|
||||||
{
|
{
|
||||||
if (reader.index >= reader.bytes.len) return 0;
|
if (reader.index >= reader.bytes.len) return 0;
|
||||||
usz written = writer.write(reader.bytes[reader.index..])!;
|
usz written = writer.write(reader.bytes[reader.index..])!;
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ fn void! ByteWriter.write_byte(ByteWriter* writer, char c)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param [&inout] writer
|
* @param [&inout] writer
|
||||||
* @param [&inout] reader
|
* @param reader
|
||||||
**/
|
**/
|
||||||
fn usz! ByteWriter.read_from(ByteWriter* writer, Stream* reader)
|
fn usz! ByteWriter.read_from(ByteWriter* writer, Stream reader)
|
||||||
{
|
{
|
||||||
usz start_index = writer.index;
|
usz start_index = writer.index;
|
||||||
if (reader.supports_available())
|
if (reader.supports_available())
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ def spawn = posix_spawn;
|
|||||||
|
|
||||||
extern fn CInt kill(Pid_t pid, CInt sig);
|
extern fn CInt kill(Pid_t pid, CInt sig);
|
||||||
extern fn Pid_t waitpid(Pid_t pid, CInt* stat_loc, int options);
|
extern fn Pid_t waitpid(Pid_t pid, CInt* stat_loc, int options);
|
||||||
|
extern fn CInt raise(CInt sig);
|
||||||
|
|
||||||
macro CInt wEXITSTATUS(CInt status) => (status & 0xff00) >> 8;
|
macro CInt wEXITSTATUS(CInt status) => (status & 0xff00) >> 8;
|
||||||
macro CInt wTERMSIG(CInt status) => status & 0x7f;
|
macro CInt wTERMSIG(CInt status) => status & 0x7f;
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
- `assert` may now take varargs for formatting.
|
- `assert` may now take varargs for formatting.
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
|
- `csv` package.
|
||||||
- Updated posix/win32 stdlib namespacing
|
- Updated posix/win32 stdlib namespacing
|
||||||
- `process` stdlib
|
- `process` stdlib
|
||||||
- Stdlib updates to string.
|
- Stdlib updates to string.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define COMPILER_VERSION "0.4.543"
|
#define COMPILER_VERSION "0.4.544"
|
||||||
@@ -17,9 +17,9 @@ fn void! bytestream()
|
|||||||
ws.write("helloworld")!;
|
ws.write("helloworld")!;
|
||||||
assert(w.as_str() == "helloworld");
|
assert(w.as_str() == "helloworld");
|
||||||
s.seek(0, SET)!;
|
s.seek(0, SET)!;
|
||||||
ws.read_from(&s)!;
|
ws.read_from(s)!;
|
||||||
s.seek(1, SET)!;
|
s.seek(1, SET)!;
|
||||||
s.write_to(&ws)!;
|
s.write_to(ws)!;
|
||||||
assert(w.as_str() == "helloworldabcbc");
|
assert(w.as_str() == "helloworldabcbc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ fn void! bytewriter_read_from()
|
|||||||
|
|
||||||
ByteWriter bw;
|
ByteWriter bw;
|
||||||
bw.tinit();
|
bw.tinit();
|
||||||
bw.read_from(&s)!;
|
bw.read_from(s)!;
|
||||||
|
|
||||||
assert(bw.as_str() == data);
|
assert(bw.as_str() == data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ fn void! test_writing()
|
|||||||
ByteReader r;
|
ByteReader r;
|
||||||
String test_str = "2134";
|
String test_str = "2134";
|
||||||
r.init(test_str);
|
r.init(test_str);
|
||||||
s.read_from(&&r.as_stream())!;
|
s.read_from(r.as_stream())!;
|
||||||
String o = foo.str();
|
String o = foo.str();
|
||||||
assert(o == "hello-what?2134");
|
assert(o == "hello-what?2134");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user