• R/O
  • SSH
  • HTTPS

yash: Commit


Commit MetaInfo

Revision3857 (tree)
Time2018-09-15 00:57:12
Authormagicant

Log Message

Count line number correctly after rewinding index (#38586)

This commit adds two test cases, the second of which is commented out as
I am not going to fix it soon. Since line continuations are entirely
removed from ps->src' on the first pass, we cannot re-increment the
line number when incrementing the index over the removed line
continuation on the second pass.

Change Summary

Incremental Difference

--- yash/trunk/parser.c (revision 3856)
+++ yash/trunk/parser.c (revision 3857)
@@ -401,6 +401,8 @@
401401 __attribute__((nonnull));
402402 static void line_continuation(parsestate_T *ps, size_t index)
403403 __attribute__((nonnull));
404+static void rewind_index(parsestate_T *ps, size_t to)
405+ __attribute__((nonnull));
404406 static void ensure_buffer(parsestate_T *ps, size_t n)
405407 __attribute__((nonnull));
406408 static size_t count_name_length(parsestate_T *ps, bool isnamechar(wchar_t c))
@@ -660,6 +662,31 @@
660662 read_more_input(ps);
661663 }
662664
665+/* Rewind `ps->index` to `oldindex' and decrease `ps->info->lineno' accordingly.
666+ *
667+ * You MUST use this function when rewinding the index in order to correctly
668+ * rewind the line number. The following pattern of code does not work because
669+ * it does not account for line continuations that have been removed from
670+ * `ps->src'.
671+ *
672+ * size_t oldindex = ps->index;
673+ * unsigned long oldlineno = ps->info->lineno;
674+ *
675+ * do_something_incrementing_index_and_lineno(ps);
676+ *
677+ * ps->index = oldindex;
678+ * ps->info->lineno = oldlineno;
679+ * */
680+void rewind_index(parsestate_T *ps, size_t oldindex)
681+{
682+ while (oldindex < ps->index) {
683+ ps->index--;
684+ assert(ps->index < ps->src.length);
685+ if (ps->src.contents[ps->index] == L'\n')
686+ ps->info->lineno--;
687+ }
688+}
689+
663690 /* If a line continuation is found within `n' characters from the current
664691 * position `ps->index', removes the backslash-newline pair and reads the next
665692 * line.
@@ -700,7 +727,7 @@
700727 ps->index++;
701728
702729 size_t result = ps->index - saveindex;
703- ps->index = saveindex;
730+ rewind_index(ps, saveindex);
704731 return result;
705732 }
706733
@@ -1978,7 +2005,7 @@
19782005
19792006 fail:
19802007 wordfree(first);
1981- ps->index = saveindex;
2008+ rewind_index(ps, saveindex);
19822009 return NULL;
19832010 }
19842011
@@ -2398,7 +2425,7 @@
23982425 else if (psubstitute_alias(ps, AF_NONGLOBAL))
23992426 goto parse_close_parenthesis;
24002427 else
2401- ps->index = saveindex;
2428+ rewind_index(ps, saveindex);
24022429 }
24032430 skip_to_next_token(ps);
24042431
Show on old repository browser