Skip to content

Commit

Permalink
Get rid of ROLLBACK_ALL.
Browse files Browse the repository at this point in the history
This code is mess, consequences of its use for caller are very hard to
grasp correctly, and it also have strange corner cases.

The need to use it more or less always means there's something stinky in
the code calling it.
  • Loading branch information
mity committed Jan 15, 2024
1 parent 481230f commit 199a17a
Showing 1 changed file with 21 additions and 42 deletions.
63 changes: 21 additions & 42 deletions src/md4c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2644,9 +2644,6 @@ md_resolve_range(MD_CTX* ctx, MD_MARKCHAIN* chain, int opener_index, int closer_
}


#define MD_ROLLBACK_ALL 0
#define MD_ROLLBACK_CROSSING 1

/* In the range ctx->marks[opener_index] ... [closer_index], undo some or all
* resolvings accordingly to these rules:
*
Expand All @@ -2655,15 +2652,12 @@ md_resolve_range(MD_CTX* ctx, MD_MARKCHAIN* chain, int opener_index, int closer_
* of unresolved openers. This ensures we can reuse the opener for closers
* AFTER the range.
*
* (2) If 'how' is MD_ROLLBACK_ALL, then ALL resolved marks inside the range
* are discarded.
*
* (3) If 'how' is MD_ROLLBACK_CROSSING, only closers with openers handled
* in (1) are discarded. I.e. pairs of openers and closers which are both
* inside the range are retained as well as any unpaired marks.
* (2) Closers with openers handled in (1) are discarded. I.e. pairs of openers
* and closers which are both inside the range are retained as well as any
* unpaired marks.
*/
static void
md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how)
md_rollback(MD_CTX* ctx, int opener_index, int closer_index)
{
int i;
int mark_index;
Expand All @@ -2687,7 +2681,6 @@ md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how)
while(mark_index > opener_index) {
MD_MARK* mark = &ctx->marks[mark_index];
int mark_flags = mark->flags;
int discard_flag = (how == MD_ROLLBACK_ALL);

if(mark->flags & MD_MARK_CLOSER) {
int mark_opener_index = mark->prev;
Expand All @@ -2701,34 +2694,18 @@ md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how)
chain = md_mark_chain(ctx, opener_index);
if(chain != NULL) {
md_mark_chain_append(ctx, chain, mark_opener_index);
discard_flag = 1;
}
}
}

/* And reset our flags. */
if(discard_flag) {
/* Make zero-length closer a dummy mark as that's how it was born */
if((mark->flags & MD_MARK_CLOSER) && mark->beg == mark->end)
mark->ch = 'D';

mark->flags &= ~(MD_MARK_OPENER | MD_MARK_CLOSER | MD_MARK_RESOLVED);
}

/* Jump as far as we can over unresolved or non-interesting marks. */
switch(how) {
case MD_ROLLBACK_CROSSING:
if((mark_flags & MD_MARK_CLOSER) && mark->prev > opener_index) {
/* If we are closer with opener INSIDE the range, there may
* not be any other crosser inside the subrange. */
mark_index = mark->prev;
break;
}
MD_FALLTHROUGH();
default:
mark_index--;
break;
if((mark_flags & MD_MARK_CLOSER) && mark->prev > opener_index) {
/* If we are closer with opener INSIDE the range, there may
* not be any other crosser inside the subrange. */
mark_index = mark->prev;
break;
}
mark_index--;
}
}

Expand Down Expand Up @@ -3500,16 +3477,21 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)

/* We don't allow destination to be longer than 100 characters.
* Lets scan to see whether there is '|'. (If not then the whole
* wiki-link has to be below the 100 characters.) */
* wiki-link has to be below the 100 characters.)
*/
delim_index = opener_index + 1;
while(delim_index < closer_index) {
MD_MARK* m = &ctx->marks[delim_index];
if(m->ch == '|') {
delim = m;
break;
}
if(m->ch != 'D' && m->beg - opener->end > 100)
break;
if(m->ch != 'D') {
if(m->beg - opener->end > 100)
break;

Check warning on line 3491 in src/md4c.c

View check run for this annotation

Codecov / codecov/patch

src/md4c.c#L3491

Added line #L3491 was not covered by tests
if(m->ch != 'D' && (m->flags & MD_MARK_OPENER))
delim_index = m->next;

Check warning on line 3493 in src/md4c.c

View check run for this annotation

Codecov / codecov/patch

src/md4c.c#L3493

Added line #L3493 was not covered by tests
}
delim_index++;
}
dest_beg = opener->end;
Expand All @@ -3531,13 +3513,10 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
if(is_link) {
if(delim != NULL) {
if(delim->end < closer->beg) {
md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL);
md_rollback(ctx, delim_index, closer_index, MD_ROLLBACK_CROSSING);
delim->flags |= MD_MARK_RESOLVED;
opener->end = delim->beg;
} else {
/* The pipe is just before the closer: [[foo|]] */
md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL);
closer->beg = delim->beg;
delim = NULL;
}
Expand Down Expand Up @@ -3810,7 +3789,7 @@ md_analyze_emph(MD_CTX* ctx, int mark_index)
md_split_emph_mark(ctx, mark_index, closer_size - opener_size);
}

md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING);
md_rollback(ctx, opener_index, mark_index);
md_resolve_range(ctx, opener_chain, opener_index, mark_index);
return;
}
Expand All @@ -3834,7 +3813,7 @@ md_analyze_tilde(MD_CTX* ctx, int mark_index)
if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && chain->head >= 0) {
int opener_index = chain->head;

md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING);
md_rollback(ctx, opener_index, mark_index);
md_resolve_range(ctx, chain, opener_index, mark_index);
return;
}
Expand All @@ -3859,9 +3838,9 @@ md_analyze_dollar(MD_CTX* ctx, int mark_index)
MD_MARK* close = &ctx->marks[mark_index];

int opener_index = DOLLAR_OPENERS.head;
md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_ALL);
if (open->end - open->beg == close->end - close->beg) {
/* We are the matching closer */
md_rollback(ctx, opener_index, mark_index);
md_resolve_range(ctx, &DOLLAR_OPENERS, opener_index, mark_index);
return;
}
Expand Down

0 comments on commit 199a17a

Please sign in to comment.