diff options
author | Adrian Thurston <thurston@colm.net> | 2018-06-25 10:34:35 +0700 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2018-06-25 10:34:35 +0700 |
commit | 2c3a53fcc12e2435cb8950c146c1f7fe63949b72 (patch) | |
tree | 2988c71ee8294bff43b8c8fe830d25f021634a06 /src | |
parent | 58fe99bfaa90bd59cc28a69d36407b06cbaac560 (diff) | |
download | colm-2c3a53fcc12e2435cb8950c146c1f7fe63949b72.tar.gz |
limit the undoing of consumed data
When undoing the consume of make sure we don't send back more than we took out.
Once we hit the limit then move backwards to the previous stream, which we now
stash.
Diffstat (limited to 'src')
-rw-r--r-- | src/input.c | 53 | ||||
-rw-r--r-- | src/input.h | 3 | ||||
-rw-r--r-- | src/pdarun.c | 2 |
3 files changed, 41 insertions, 17 deletions
diff --git a/src/input.c b/src/input.c index 6cdb7738..cd80d550 100644 --- a/src/input.c +++ b/src/input.c @@ -480,14 +480,21 @@ static int data_consume_data( struct stream_impl_data *ss, int length, location_ return consumed; } -static int data_undo_consume_data( struct stream_impl_data *ss, const char *data, int length ) +static int data_undo_consume_data( struct stream_impl_data *si, const char *data, int length ) { - struct run_buf *new_buf = new_run_buf( 0 ); - new_buf->length = length; - memcpy( new_buf->data, data, length ); - source_stream_data_prepend( ss, new_buf ); - undo_position_data( ss, data, length ); - ss->consumed -= length; + //printf( "data-undo-consume-data %p, undoing consume of %d bytes, consumed: %d\n", si, length, si->consumed ); + + if ( length > si->consumed ) + length = si->consumed; + + if ( length > 0 ) { + struct run_buf *new_buf = new_run_buf( 0 ); + new_buf->length = length; + memcpy( new_buf->data, data, length ); + source_stream_data_prepend( si, new_buf ); + undo_position_data( si, data, length ); + si->consumed -= length; + } return length; } @@ -547,6 +554,19 @@ void init_stream_impl_data( struct stream_impl_data *is, char *name ) is->level = COLM_INDENT_OFF; } +static void input_stream_stash_head( struct stream_impl_seq *si, struct seq_buf *seq_buf ) +{ + seq_buf->next = si->stash; + si->stash = seq_buf; +} + +static struct seq_buf *input_stream_pop_stash( struct stream_impl_seq *si ) +{ + struct seq_buf *seq_buf = si->stash; + si->stash = si->stash->next; + return seq_buf; +} + static struct seq_buf *input_stream_seq_pop_head( struct stream_impl_seq *is ) { struct seq_buf *ret = is->queue; @@ -880,11 +900,7 @@ static int stream_consume_data( struct stream_impl_seq *is, int length, location } struct seq_buf *seq_buf = input_stream_seq_pop_head( is ); - //if ( run_Buf->type == RUN_BUF_SOURCE_TYPE ) { - // stream_t *stream = runBuf->stream; - // colm_tree_downref( prg, sp, (tree_t*) stream ); - //} - free( seq_buf ); + input_stream_stash_head( is, seq_buf ); } return consumed; @@ -892,12 +908,19 @@ static int stream_consume_data( struct stream_impl_seq *is, int length, location static int stream_undo_consume_data( struct stream_impl_seq *is, const char *data, int length ) { - //debug( REALM_INPUT, "undoing consume of %ld bytes\n", length ); + //debug( REALM_INPUT, "stream %p, undoing consume of %ld bytes\n", is, length ); if ( is->consumed == 0 && is_source_stream( is ) ) { struct stream_impl *si = is->queue->si; - int len = si->funcs->undo_consume_data( si, data, length ); - return len; + int pushed_back = si->funcs->undo_consume_data( si, data, length ); + + if ( pushed_back < length ) { + struct seq_buf *b = input_stream_pop_stash( is ); + input_stream_seq_prepend( is, b ); + pushed_back += stream_undo_consume_data( is, data + pushed_back, length - pushed_back ); + } + + return pushed_back; } else { struct seq_buf *new_buf = new_seq_buf( 0 ); diff --git a/src/input.h b/src/input.h index 0cf77566..fbe2ec01 100644 --- a/src/input.h +++ b/src/input.h @@ -77,7 +77,6 @@ struct run_buf { enum run_buf_type type; long length; - struct colm_tree *tree; long offset; struct run_buf *next, *prev; @@ -145,6 +144,8 @@ struct stream_impl_seq struct seq_buf *queue; struct seq_buf *queue_tail; + struct seq_buf *stash; + long line; long column; long byte; diff --git a/src/pdarun.c b/src/pdarun.c index 43676949..212e3a10 100644 --- a/src/pdarun.c +++ b/src/pdarun.c @@ -1969,7 +1969,7 @@ long colm_parse_loop( program_t *prg, tree_t **sp, struct pda_run *pda_run, pda_run->stop = false; while ( true ) { - debug( prg, REALM_PARSE, "parse loop start" ); + debug( prg, REALM_PARSE, "parse loop start\n" ); /* Pull the current scanner from the parser. This can change during * parsing due to inputStream pushes, usually for the purpose of includes. |