mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-19 01:15:21 +00:00
[csv iterate] string-builder iterate
This commit is contained in:
parent
e5c8f53e3c
commit
5da855c331
2 changed files with 19 additions and 9 deletions
|
|
@ -1,6 +1,13 @@
|
|||
|
||||
================================================================
|
||||
--> parser option: write a grammar like the below. be careful to
|
||||
preserve the streaming property!
|
||||
--> I don't see a way to line-at-a-time it in the formal grammar.
|
||||
Other option is to find end of line via string arithmetic,
|
||||
then pass that (null-terminated) string to the parser. But
|
||||
correctly determining EOL in the presence of double-quote
|
||||
semantics *is* the problem; nothing interesting left for the
|
||||
parser to do.
|
||||
|
||||
--> state-machine option:
|
||||
* each field either does or does not begin & end w/ "
|
||||
|
|
@ -24,6 +31,8 @@
|
|||
public fcn append_char, public fcn append_string,
|
||||
private fcn realloc resizing with minimal copy, public fcn zterm & produce.
|
||||
|
||||
================================================================
|
||||
Offlineable (subway-tunnelable) excerpt from https://tools.ietf.org/html/rfc4180
|
||||
================================================================
|
||||
Definition of the CSV Format
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,10 @@
|
|||
#include "../lib/mlrutil.h"
|
||||
#include "../lib/mlr_globals.h"
|
||||
|
||||
// Private method:
|
||||
static void sb_enlarge(string_builder_t* psb);
|
||||
|
||||
// typedef struct _string_builder_t {
|
||||
// int used_length;
|
||||
// int alloc_length;
|
||||
// char* buffer;
|
||||
// } string_builder_t;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void sb_init(string_builder_t* psb, int alloc_length) {
|
||||
if (alloc_length < 1) {
|
||||
fprintf(stderr, "%s: string_builder alloc_length must be >= 1; got %d.\n",
|
||||
|
|
@ -23,26 +19,31 @@ void sb_init(string_builder_t* psb, int alloc_length) {
|
|||
psb->buffer = mlr_malloc_or_die(alloc_length); // xxx malloc ...
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void sb_append_char(string_builder_t* psb, char c) {
|
||||
if (psb->used_length >= psb->alloc_length)
|
||||
sb_enlarge(psb);
|
||||
psb->buffer[psb->used_length++] = c;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void sb_append_string(string_builder_t* psb, char* s) {
|
||||
for (char* p = s; *p; p++)
|
||||
sb_append_char(psb, *p);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Keep and reuse the internal buffer. Allocate to the caller only
|
||||
// the size needed.
|
||||
char* sb_finish(string_builder_t* psb) {
|
||||
sb_append_char(psb, '\0');
|
||||
char* rv = psb->buffer;
|
||||
char* rv = mlr_malloc_or_die(psb->used_length);
|
||||
memcpy(rv, psb->buffer, psb->used_length);
|
||||
psb->used_length = 0;
|
||||
psb->alloc_length = 0;
|
||||
psb->buffer = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
static void sb_enlarge(string_builder_t* psb) {
|
||||
int new_alloc_length = psb->alloc_length * 2;
|
||||
char* new_buffer = mlr_malloc_or_die(new_alloc_length);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue