bool found = false;
// Trap the deletion of the paragraph the cursor is in.
- // It should be almost impossible for the new cursor par to be
- // deleted later on in this function.
- // This is the way to segfault this now. Although you may have to do this
- // multiple times: Have an InsetERT with an unknown command in it.
- // View->DVI, move cursor between Error box and InsetERT and hit <Enter>,
- // <down-arrow>, <Enter> again, View->DVI, BANG!
- //
+ // Iterate until we find a paragraph that won't be immediately deleted.
+ // In reality this should mean we only execute the body of the while
+ // loop once at most. However for safety we iterate rather than just
+ // make this an if() conditional.
while ((cur_par_prev || cur_par_next)
&& text->setCursor(this,
cur_par_prev ? cur_par_prev : cur_par_next,
0)) {
- // we just removed cur_par so have to fix the "cursor"
+ // We just removed cur_par so have to fix the "cursor"
if (cur_par_prev) {
+ // '.' = cur_par
+ // a -> a.
+ // .
cur_par = cur_par_prev;
cur_pos = cur_par->size();
} else {
+ // . -> .a
+ // a
cur_par = cur_par_next;
cur_pos = 0;
}
Paragraph * par_prev = par ? par->previous() : 0;
bool removed = false;
- bool dead = text->setCursor(this, par, 0);
+ if (text->setCursor(this, par, 0)
+ && cur_par == par_prev) {
+ // The previous setCursor line was deleted and that
+ // was the cur_par line. This can only happen if an
+ // error box was the sole item on cur_par.
+ if (cur_par_prev) {
+ // '|' = par, '.' = cur_par, 'E' = error box
+ // First step below may occur before while{}
+ // a |a a a a.
+ // E -> .E -> |.E -> . -> |b
+ // . b b |b
+ // b
+ cur_par = cur_par_prev;
+ cur_pos = cur_par_prev->size();
+ cur_par_prev = cur_par->previous();
+ // cur_par_next remains the same
+ } else if (cur_par_next) {
+ // First step below may occur before while{}
+ // .
+ // E -> |.E -> |. -> . -> .|a
+ // a a a |a
+ cur_par = cur_par_next;
+ cur_pos = 0;
+ // cur_par_prev remains unset
+ cur_par_next = cur_par->next();
+ } else {
+ // I can't find a way to trigger this
+ // so it should be unreachable code
+ // unless the buffer is corrupted.
+ lyxerr << "BufferView::removeAutoInsets() is bad\n";
+ }
+ }
Paragraph::inset_iterator pit = par->inset_iterator_begin();
Paragraph::inset_iterator pend = par->inset_iterator_end();
found = true;
text->redoParagraph(this);
}
- if (dead) {
- // Error box paragraphs appear to have a bad next_ pointer
- // especially when that's all that's in the paragraph..
- // Then if you are in an empty paragraph after an error box
- // which is in its own paragraph this will fail because
- // cur_prev_par was the one just deleted (I think).
- // That's the main reason why this clause makes almost no difference.
- // Feel free to delete this whole clause as my brain is asleep now.
- while ((cur_par_prev || cur_par_next)
- && text->setCursor(this,
- cur_par_prev ? cur_par_prev : cur_par_next,
- 0)) {
- // we just removed cur_par so have to fix the "cursor"
- if (cur_par_prev == par) {
- // attempting to solve the "prev par was deleted
- // because it had only an error inset in it" problem
- if (par_prev) {
- cur_par = par_prev;
- cur_pos = cur_par->size();
- } else {
- cur_par = cur_par_next;
- cur_pos = 0;
- }
- } else if (cur_par_prev) {
- cur_par = cur_par_prev;
- cur_pos = cur_par->size();
- } else {
- cur_par = cur_par_next;
- cur_pos = 0;
- }
- cur_par_prev = cur_par->previous();
- cur_par_next = cur_par->next();
- }
- }
}
text->setCursorIntern(this, cur_par, cur_pos);
{
// Check if the label 'from' appears more than once
vector<string> labels = buffer()->getLabelList();
- // count is broken on some systems, so use the HP version
- int res;
- count(labels.begin(), labels.end(), from, res);
+ // count is broken on some systems, so use the HP version (anon)
+ // Which does not exist on certain systems, so _we_
+ // use the standard version. (Lgb)
+ int res = count(labels.begin(), labels.end(), from);
if (res > 1)
return false;