diff options
| author | gingerBill <bill@gingerbill.org> | 2021-08-31 22:21:13 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-08-31 22:21:13 +0100 |
| commit | 251da264ed6e0f039931683c7b0d4b97e88c8d99 (patch) | |
| tree | c7a9a088477d2452c2cf850458c62d994a211df6 /core/encoding/csv | |
| parent | b176af27427a6c39448a71a8023e4a9877f0a51c (diff) | |
Remove unneeded semicolons from the core library
Diffstat (limited to 'core/encoding/csv')
| -rw-r--r-- | core/encoding/csv/reader.odin | 278 | ||||
| -rw-r--r-- | core/encoding/csv/writer.odin | 64 |
2 files changed, 171 insertions, 171 deletions
diff --git a/core/encoding/csv/reader.odin b/core/encoding/csv/reader.odin index 4c28ea9f3..aecb73d7b 100644 --- a/core/encoding/csv/reader.odin +++ b/core/encoding/csv/reader.odin @@ -68,7 +68,7 @@ reader_error_kind_string := [Reader_Error_Kind]string{ .Quote = "extra or missing \" in quoted field", .Field_Count = "wrong field count", .Invalid_Delim = "invalid delimiter", -}; +} Reader_Error :: struct { kind: Reader_Error_Kind, @@ -83,35 +83,35 @@ Error :: union { io.Error, } -DEFAULT_RECORD_BUFFER_CAPACITY :: 256; +DEFAULT_RECORD_BUFFER_CAPACITY :: 256 // reader_init initializes a new Reader from r reader_init :: proc(reader: ^Reader, r: io.Reader, buffer_allocator := context.allocator) { - reader.comma = ','; - - context.allocator = buffer_allocator; - reserve(&reader.record_buffer, DEFAULT_RECORD_BUFFER_CAPACITY); - reserve(&reader.raw_buffer, 0); - reserve(&reader.field_indices, 0); - reserve(&reader.last_record, 0); - bufio.reader_init(&reader.r, r); + reader.comma = ',' + + context.allocator = buffer_allocator + reserve(&reader.record_buffer, DEFAULT_RECORD_BUFFER_CAPACITY) + reserve(&reader.raw_buffer, 0) + reserve(&reader.field_indices, 0) + reserve(&reader.last_record, 0) + bufio.reader_init(&reader.r, r) } // reader_init_with_string initializes a new Reader from s reader_init_with_string :: proc(reader: ^Reader, s: string, buffer_allocator := context.allocator) { - strings.reader_init(&reader.sr, s); - r, _ := io.to_reader(strings.reader_to_stream(&reader.sr)); - reader_init(reader, r, buffer_allocator); + strings.reader_init(&reader.sr, s) + r, _ := io.to_reader(strings.reader_to_stream(&reader.sr)) + reader_init(reader, r, buffer_allocator) } // reader_destroy destroys a Reader reader_destroy :: proc(r: ^Reader) { - delete(r.raw_buffer); - delete(r.record_buffer); - delete(r.field_indices); - delete(r.last_record); - bufio.reader_destroy(&r.r); + delete(r.raw_buffer) + delete(r.record_buffer) + delete(r.field_indices) + delete(r.last_record) + bufio.reader_destroy(&r.r) } // read reads a single record (a slice of fields) from r @@ -119,21 +119,21 @@ reader_destroy :: proc(r: ^Reader) { // All \r\n sequences are normalized to \n, including multi-line field read :: proc(r: ^Reader, allocator := context.allocator) -> (record: []string, err: Error) { if r.reuse_record { - record, err = _read_record(r, &r.last_record, allocator); - resize(&r.last_record, len(record)); - copy(r.last_record[:], record); + record, err = _read_record(r, &r.last_record, allocator) + resize(&r.last_record, len(record)) + copy(r.last_record[:], record) } else { - record, err = _read_record(r, nil, allocator); + record, err = _read_record(r, nil, allocator) } - return; + return } // is_io_error checks where an Error is a specific io.Error kind is_io_error :: proc(err: Error, io_err: io.Error) -> bool { if v, ok := err.(io.Error); ok { - return v == io_err; + return v == io_err } - return false; + return false } @@ -141,97 +141,97 @@ is_io_error :: proc(err: Error, io_err: io.Error) -> bool { // Each record is a slice of fields. // read_all is defined to read until an EOF, and does not treat, and does not treat EOF as an error read_all :: proc(r: ^Reader, allocator := context.allocator) -> ([][]string, Error) { - context.allocator = allocator; - records: [dynamic][]string; + context.allocator = allocator + records: [dynamic][]string for { - record, rerr := _read_record(r, nil, allocator); + record, rerr := _read_record(r, nil, allocator) if is_io_error(rerr, .EOF) { - return records[:], nil; + return records[:], nil } if rerr != nil { - return nil, rerr; + return nil, rerr } - append(&records, record); + append(&records, record) } } // read reads a single record (a slice of fields) from the provided input. read_from_string :: proc(input: string, record_allocator := context.allocator, buffer_allocator := context.allocator) -> (record: []string, n: int, err: Error) { - ir: strings.Reader; - strings.reader_init(&ir, input); - input_reader, _ := io.to_reader(strings.reader_to_stream(&ir)); - - r: Reader; - reader_init(&r, input_reader, buffer_allocator); - defer reader_destroy(&r); - record, err = read(&r, record_allocator); - n = int(r.r.r); - return; + ir: strings.Reader + strings.reader_init(&ir, input) + input_reader, _ := io.to_reader(strings.reader_to_stream(&ir)) + + r: Reader + reader_init(&r, input_reader, buffer_allocator) + defer reader_destroy(&r) + record, err = read(&r, record_allocator) + n = int(r.r.r) + return } // read_all reads all the remaining records from the provided input. read_all_from_string :: proc(input: string, records_allocator := context.allocator, buffer_allocator := context.allocator) -> ([][]string, Error) { - ir: strings.Reader; - strings.reader_init(&ir, input); - input_reader, _ := io.to_reader(strings.reader_to_stream(&ir)); - - r: Reader; - reader_init(&r, input_reader, buffer_allocator); - defer reader_destroy(&r); - return read_all(&r, records_allocator); + ir: strings.Reader + strings.reader_init(&ir, input) + input_reader, _ := io.to_reader(strings.reader_to_stream(&ir)) + + r: Reader + reader_init(&r, input_reader, buffer_allocator) + defer reader_destroy(&r) + return read_all(&r, records_allocator) } @private is_valid_delim :: proc(r: rune) -> bool { switch r { case 0, '"', '\r', '\n', utf8.RUNE_ERROR: - return false; + return false } - return utf8.valid_rune(r); + return utf8.valid_rune(r) } @private _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.allocator) -> ([]string, Error) { read_line :: proc(r: ^Reader) -> ([]byte, io.Error) { - line, err := bufio.reader_read_slice(&r.r, '\n'); + line, err := bufio.reader_read_slice(&r.r, '\n') if err == .Buffer_Full { - clear(&r.raw_buffer); - append(&r.raw_buffer, ..line); + clear(&r.raw_buffer) + append(&r.raw_buffer, ..line) for err == .Buffer_Full { - line, err = bufio.reader_read_slice(&r.r, '\n'); - append(&r.raw_buffer, ..line); + line, err = bufio.reader_read_slice(&r.r, '\n') + append(&r.raw_buffer, ..line) } - line = r.raw_buffer[:]; + line = r.raw_buffer[:] } if len(line) > 0 && err == .EOF { - err = nil; + err = nil if line[len(line)-1] == '\r' { - line = line[:len(line)-1]; + line = line[:len(line)-1] } } - r.line_count += 1; + r.line_count += 1 // normalize \r\n to \n - n := len(line); + n := len(line) for n >= 2 && string(line[n-2:]) == "\r\n" { - line[n-2] = '\n'; - line = line[:n-1]; + line[n-2] = '\n' + line = line[:n-1] } - return line, err; + return line, err } length_newline :: proc(b: []byte) -> int { if len(b) > 0 && b[len(b)-1] == '\n' { - return 1; + return 1 } - return 0; + return 0 } next_rune :: proc(b: []byte) -> rune { - r, _ := utf8.decode_rune(b); - return r; + r, _ := utf8.decode_rune(b) + return r } if r.comma == r.comment || @@ -240,152 +240,152 @@ _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.all err := Reader_Error{ kind = .Invalid_Delim, line = r.line_count, - }; - return nil, err; + } + return nil, err } - line, full_line: []byte; - err_read: io.Error; + line, full_line: []byte + err_read: io.Error for err_read == nil { - line, err_read = read_line(r); + line, err_read = read_line(r) if r.comment != 0 && next_rune(line) == r.comment { - line = nil; - continue; + line = nil + continue } if err_read == nil && len(line) == length_newline(line) { - line = nil; - continue; + line = nil + continue } - full_line = line; - break; + full_line = line + break } if is_io_error(err_read, .EOF) { - return nil, err_read; + return nil, err_read } - err: Error; - quote_len :: len(`"`); - comma_len := utf8.rune_size(r.comma); - record_line := r.line_count; - clear(&r.record_buffer); - clear(&r.field_indices); + err: Error + quote_len :: len(`"`) + comma_len := utf8.rune_size(r.comma) + record_line := r.line_count + clear(&r.record_buffer) + clear(&r.field_indices) parse_field: for { if r.trim_leading_space { - line = bytes.trim_left_space(line); + line = bytes.trim_left_space(line) } if len(line) == 0 || line[0] != '"' { - i := bytes.index_rune(line, r.comma); - field := line; + i := bytes.index_rune(line, r.comma) + field := line if i >= 0 { - field = field[:i]; + field = field[:i] } else { - field = field[:len(field) - length_newline(field)]; + field = field[:len(field) - length_newline(field)] } if !r.lazy_quotes { if j := bytes.index_byte(field, '"'); j >= 0 { - column := utf8.rune_count(full_line[:len(full_line) - len(line[j:])]); + column := utf8.rune_count(full_line[:len(full_line) - len(line[j:])]) err = Reader_Error{ kind = .Bare_Quote, start_line = record_line, line = r.line_count, column = column, - }; - break parse_field; + } + break parse_field } } - append(&r.record_buffer, ..field); - append(&r.field_indices, len(r.record_buffer)); + append(&r.record_buffer, ..field) + append(&r.field_indices, len(r.record_buffer)) if i >= 0 { - line = line[i+comma_len:]; - continue parse_field; + line = line[i+comma_len:] + continue parse_field } - break parse_field; + break parse_field } else { - line = line[quote_len:]; + line = line[quote_len:] for { - i := bytes.index_byte(line, '"'); + i := bytes.index_byte(line, '"') switch { case i >= 0: - append(&r.record_buffer, ..line[:i]); - line = line[i+quote_len:]; + append(&r.record_buffer, ..line[:i]) + line = line[i+quote_len:] switch ch := next_rune(line); { case ch == '"': // append quote - append(&r.record_buffer, '"'); - line = line[quote_len:]; + append(&r.record_buffer, '"') + line = line[quote_len:] case ch == r.comma: // end of field - line = line[comma_len:]; - append(&r.field_indices, len(r.record_buffer)); - continue parse_field; + line = line[comma_len:] + append(&r.field_indices, len(r.record_buffer)) + continue parse_field case length_newline(line) == len(line): // end of line - append(&r.field_indices, len(r.record_buffer)); - break parse_field; + append(&r.field_indices, len(r.record_buffer)) + break parse_field case r.lazy_quotes: // bare quote - append(&r.record_buffer, '"'); + append(&r.record_buffer, '"') case: // invalid non-escaped quote - column := utf8.rune_count(full_line[:len(full_line) - len(line) - quote_len]); + column := utf8.rune_count(full_line[:len(full_line) - len(line) - quote_len]) err = Reader_Error{ kind = .Quote, start_line = record_line, line = r.line_count, column = column, - }; - break parse_field; + } + break parse_field } case len(line) > 0: - append(&r.record_buffer, ..line); + append(&r.record_buffer, ..line) if err_read != nil { - break parse_field; + break parse_field } - line, err_read = read_line(r); + line, err_read = read_line(r) if is_io_error(err_read, .EOF) { - err_read = nil; + err_read = nil } - full_line = line; + full_line = line case: if !r.lazy_quotes && err_read == nil { - column := utf8.rune_count(full_line); + column := utf8.rune_count(full_line) err = Reader_Error{ kind = .Quote, start_line = record_line, line = r.line_count, column = column, - }; - break parse_field; + } + break parse_field } - append(&r.field_indices, len(r.record_buffer)); - break parse_field; + append(&r.field_indices, len(r.record_buffer)) + break parse_field } } } } if err == nil && err_read != nil { - err = err_read; + err = err_read } - context.allocator = allocator; - dst := dst; - str := string(r.record_buffer[:]); + context.allocator = allocator + dst := dst + str := string(r.record_buffer[:]) if dst == nil { // use local variable - dst = &([dynamic]string){}; + dst = &([dynamic]string){} } - clear(dst); - resize(dst, len(r.field_indices)); - pre_idx: int; + clear(dst) + resize(dst, len(r.field_indices)) + pre_idx: int for idx, i in r.field_indices { - field := str[pre_idx:idx]; + field := str[pre_idx:idx] if !r.reuse_record_buffer { - field = strings.clone(field); + field = strings.clone(field) } - dst[i] = field; - pre_idx = idx; + dst[i] = field + pre_idx = idx } if r.fields_per_record > 0 { @@ -396,11 +396,11 @@ _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.all line = r.line_count, expected = r.fields_per_record, got = len(dst), - }; + } } } else if r.fields_per_record == 0 { - r.fields_per_record = len(dst); + r.fields_per_record = len(dst) } - return dst[:], err; + return dst[:], err } diff --git a/core/encoding/csv/writer.odin b/core/encoding/csv/writer.odin index 2176e6781..3a0038916 100644 --- a/core/encoding/csv/writer.odin +++ b/core/encoding/csv/writer.odin @@ -17,8 +17,8 @@ Writer :: struct { // writer_init initializes a Writer that writes to w writer_init :: proc(writer: ^Writer, w: io.Writer) { - writer.comma = ','; - writer.w = w; + writer.comma = ',' + writer.w = w } // write writes a single CSV records to w with any of the necessarily quoting. @@ -26,101 +26,101 @@ writer_init :: proc(writer: ^Writer, w: io.Writer) { // // If the underlying io.Writer requires flushing, make sure to call io.flush write :: proc(w: ^Writer, record: []string) -> io.Error { - CHAR_SET :: "\n\r\""; + CHAR_SET :: "\n\r\"" field_needs_quoting :: proc(w: ^Writer, field: string) -> bool { switch { case field == "": // No need to quote empty strings - return false; + return false case field == `\.`: // Postgres is weird - return true; + return true case w.comma < utf8.RUNE_SELF: // ASCII optimization for i in 0..<len(field) { switch field[i] { case '\n', '\r', '"', byte(w.comma): - return true; + return true } } case: if strings.contains_rune(field, w.comma) >= 0 { - return true; + return true } if strings.contains_any(field, CHAR_SET) { - return true; + return true } } // Leading spaces need quoting - r, _ := utf8.decode_rune_in_string(field); - return strings.is_space(r); + r, _ := utf8.decode_rune_in_string(field) + return strings.is_space(r) } if !is_valid_delim(w.comma) { - return .No_Progress; // TODO(bill): Is this a good error? + return .No_Progress // TODO(bill): Is this a good error? } for _, field_idx in record { // NOTE(bill): declared like this so that the field can be modified later if necessary - field := record[field_idx]; + field := record[field_idx] if field_idx > 0 { - io.write_rune(w.w, w.comma) or_return; + io.write_rune(w.w, w.comma) or_return } if !field_needs_quoting(w, field) { - io.write_string(w.w, field) or_return; - continue; + io.write_string(w.w, field) or_return + continue } - io.write_byte(w.w, '"') or_return; + io.write_byte(w.w, '"') or_return for len(field) > 0 { - i := strings.index_any(field, CHAR_SET); + i := strings.index_any(field, CHAR_SET) if i < 0 { - i = len(field); + i = len(field) } - io.write_string(w.w, field[:i]) or_return; - field = field[i:]; + io.write_string(w.w, field[:i]) or_return + field = field[i:] if len(field) > 0 { switch field[0] { case '\r': if !w.use_crlf { - io.write_byte(w.w, '\r') or_return; + io.write_byte(w.w, '\r') or_return } case '\n': if w.use_crlf { - io.write_string(w.w, "\r\n") or_return; + io.write_string(w.w, "\r\n") or_return } else { - io.write_byte(w.w, '\n') or_return; + io.write_byte(w.w, '\n') or_return } case '"': - io.write_string(w.w, `""`) or_return; + io.write_string(w.w, `""`) or_return } - field = field[1:]; + field = field[1:] } } - io.write_byte(w.w, '"') or_return; + io.write_byte(w.w, '"') or_return } if w.use_crlf { - _, err := io.write_string(w.w, "\r\n"); - return err; + _, err := io.write_string(w.w, "\r\n") + return err } - return io.write_byte(w.w, '\n'); + return io.write_byte(w.w, '\n') } // write_all writes multiple CSV records to w using write, and then flushes (if necessary). write_all :: proc(w: ^Writer, records: [][]string) -> io.Error { for record in records { - write(w, record) or_return; + write(w, record) or_return } - return writer_flush(w); + return writer_flush(w) } // writer_flush flushes the underlying io.Writer. // If the underlying io.Writer does not support flush, nil is returned. writer_flush :: proc(w: ^Writer) -> io.Error { - return io.flush(auto_cast w.w); + return io.flush(auto_cast w.w) } |