summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2018-12-12 12:32:49 +0200
committerAdrian Thurston <thurston@colm.net>2018-12-12 12:32:49 +0200
commit14feafceb89dd36663e65f8907e3c3d87b5dae84 (patch)
tree736a0fbd0ae582cc39393feb09010784d1626e8e /src
parent46afc4c66c0075d01646df65d0939571c91e9050 (diff)
downloadcolm-14feafceb89dd36663e65f8907e3c3d87b5dae84.tar.gz
stream: track line lengths and use to restore during push back
Diffstat (limited to 'src')
-rw-r--r--src/input.h6
-rw-r--r--src/stream.c37
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;