diff options
author | Adrian Thurston <thurston@colm.net> | 2018-12-12 12:32:49 +0200 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2018-12-12 12:32:49 +0200 |
commit | 14feafceb89dd36663e65f8907e3c3d87b5dae84 (patch) | |
tree | 736a0fbd0ae582cc39393feb09010784d1626e8e /src | |
parent | 46afc4c66c0075d01646df65d0939571c91e9050 (diff) | |
download | colm-14feafceb89dd36663e65f8907e3c3d87b5dae84.tar.gz |
stream: track line lengths and use to restore during push back
Diffstat (limited to 'src')
-rw-r--r-- | src/input.h | 6 | ||||
-rw-r--r-- | src/stream.c | 37 |
2 files changed, 39 insertions, 4 deletions
diff --git a/src/input.h b/src/input.h index fc100313..9b91a7b5 100644 --- a/src/input.h +++ b/src/input.h @@ -192,8 +192,14 @@ struct stream_impl_data /* Indentation. */ int level; int indent; + + int *line_len; + int lines_alloc; }; +void stream_impl_push_line( struct stream_impl_data *ss, int line, int ll ); +int stream_impl_pop_line( struct stream_impl_data *ss, int line ); + struct input_impl *colm_impl_new_generic( char *name ); void update_position( struct stream_impl *input_stream, const char *data, long length ); diff --git a/src/stream.c b/src/stream.c index 6fb3901b..37433ee4 100644 --- a/src/stream.c +++ b/src/stream.c @@ -42,6 +42,28 @@ DEF_STREAM_FUNCS( stream_funcs_data, stream_impl_data ); extern struct stream_funcs_data file_funcs; extern struct stream_funcs_data accum_funcs; +void stream_impl_push_line( struct stream_impl_data *ss, int line, int ll ) +{ + if ( ss->line_len == 0 ) { + ss->lines_alloc = 16; + ss->line_len = malloc( sizeof(int) * ss->lines_alloc ); + } + else if ( line > ss->lines_alloc ) { + int lines_alloc_new = ss->lines_alloc * 2; + int *line_len_new = malloc( sizeof(int) * lines_alloc_new ); + memcpy( line_len_new, ss->line_len, sizeof(int) * ss->lines_alloc ); + ss->lines_alloc = lines_alloc_new; + ss->line_len = line_len_new; + } + + ss->line_len[ line - 1 ] = ll; +} + +int stream_impl_pop_line( struct stream_impl_data *ss, int line ) +{ + return ss->line_len[line - 1]; +} + static void dump_contents( struct colm_program *prg, struct stream_impl_data *sid ) { struct run_buf *rb = sid->queue.head; @@ -141,12 +163,14 @@ void update_position_data( struct stream_impl_data *is, const char *data, long l { int i; for ( i = 0; i < length; i++ ) { - if ( data[i] != '\n' ) - is->column += 1; - else { + if ( data[i] == '\n' ) { + stream_impl_push_line( is, is->line, is->column ); is->line += 1; is->column = 1; } + else { + is->column += 1; + } } is->byte += length; @@ -159,8 +183,13 @@ void undo_position_data( struct stream_impl_data *is, const char *data, long len * token and restore based on that.. */ int i; for ( i = 0; i < length; i++ ) { - if ( data[i] == '\n' ) + if ( data[i] == '\n' ) { is->line -= 1; + is->column = stream_impl_pop_line( is, is->line ); + } + else { + is->column -= 1; + } } is->byte -= length; |