I attach a diff of my local tree against current CVS. The changes in math_iter.[hC] are purely cosmetical. The crucial difference is the removel of MathedRowSt and the use of a std::vector<MathedRowStrict> instead of the handcrafted list of MathedRowSt's. I also removed the insert_after() function in favour of a more standard- like insert. The insert_after was sometimes off by one so that might have been the reason for the spurious crashes Lars has seen. Behaviour _has_ changed, e.g. hitting Ctrl-Return in an array gives a new line with the cursor placed at the end of the new line, whereas it used to stay at the beginning. This can be fixed easily now, I just did not want to blow up the patch. The only "real" problem I am aware of (apart from the old macro issue) is \nolimits, it is saved properly but not read back. Chasing this bug should be easier with this patch applied since MathedRowContainer is _much_ simpler now. The Userguide is read and displayed properly as far as I can tell, there are quite a few changes after saving but seemingly only whitespace and (text-) table differences. There is a message about a missing \end_inset when reading in the first time. I have not checked yet why, it does not abort reading anyway and the result looks ok. Andre' -- André Pönitz ........................................ [EMAIL PROTECTED]
Index: ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/ChangeLog,v retrieving revision 1.63 diff -u -p -r1.63 ChangeLog --- ChangeLog 2001/03/12 13:58:11 1.63 +++ ChangeLog 2001/03/15 09:04:26 @@ -1,6 +1,12 @@ +2001-03-15 André Pönitz <[EMAIL PROTECTED]> + * math_rowst.h: Finally remove MathedRowSt + + * math_parser.C: + math_xiter.C: changed accordingly + 2001-03-12 André Pönitz <[EMAIL PROTECTED]> - * math_rowst.h: replace MathedRowSt with MathedRowSt, + * math_rowst.h: replace MathedRowSt with MathedRowStruct, more robust MathedRowSt::[gs]etTab (to get rid of the constructor arg) 2001-03-10 André Pönitz <[EMAIL PROTECTED]> Index: math_cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_cursor.C,v retrieving revision 1.44 diff -u -p -r1.44 math_cursor.C --- math_cursor.C 2001/03/09 08:45:10 1.44 +++ math_cursor.C 2001/03/15 09:04:26 @@ -82,7 +82,9 @@ struct MathStackXIter { } MathedXIter * Item(int idx) { - return (idx + 1 <= i) ? &item[i - idx - 1] : 0; + if (idx + 1 > i) + cerr << "Wrong index: " << idx << " i: " << i << endl; + return &item[i - idx - 1]; } void Reset() { Index: math_iter.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_iter.C,v retrieving revision 1.41 diff -u -p -r1.41 math_iter.C --- math_iter.C 2001/03/06 10:24:45 1.41 +++ math_iter.C 2001/03/15 09:04:26 @@ -60,6 +60,15 @@ void MathedIter::fcode(short c) const fcode_ = c; } +byte MathedIter::at(int p) const +{ + return (*array)[p]; +} + +byte & MathedIter::at(int p) +{ + return (*array)[p]; +} int MathedIter::Empty() const { @@ -75,8 +84,8 @@ int MathedIter::OK() const void MathedIter::Reset() { - if (array->last() > 0 && MathIsFont((*array)[0])) { - fcode((*array)[0]); + if (array->last() > 0 && MathIsFont(at(0))) { + fcode(at(0)); pos = 1; } else { fcode(-1); @@ -90,23 +99,23 @@ void MathedIter::Reset() byte MathedIter::GetChar() const { if (IsFont()) { - fcode((*array)[pos]); + fcode(at(pos)); ++pos; } - return (*array)[pos]; + return at(pos); } string const MathedIter::GetString() const { if (IsFont()) { - fcode((*array)[++pos]); + fcode(at(++pos)); ++pos; } string s; - for (; (*array)[pos] >= ' ' && pos < array->last(); ++pos) - s += (*array)[pos]; + for (; at(pos) >= ' ' && pos < array->last(); ++pos) + s += at(pos); return s; } @@ -120,7 +129,7 @@ MathedInset * MathedIter::GetInset() con return p; } else { lyxerr << "Math Error: This is not an inset[" - << (*array)[pos] << "]" << endl; + << at(pos) << "]" << endl; return 0; } } @@ -143,7 +152,7 @@ bool MathedIter::Next() if (!OK()) return false; - if ((*array)[pos] < ' ') { + if (at(pos) < ' ') { fcode(-1); if (IsTab()) ++col; @@ -159,7 +168,7 @@ bool MathedIter::Next() ++pos; if (IsFont()) - fcode((*array)[pos++]); + fcode(at(pos++)); return true; } @@ -168,7 +177,7 @@ bool MathedIter::Next() bool MathedIter::goNextCode(MathedTextCodes code) { while (Next()) { - if ((*array)[pos] == code) + if (at(pos) == code) return true; } @@ -198,23 +207,23 @@ void MathedIter::insert(byte c, MathedTe // Address 0x47b857 is 1 byte before start of malloc'd block at // 0x47b858 of 16 bytes. - if (c == ' ' && ((*array)[pos] == ' ' || (*array)[pos - 1] == ' ')) + if (c == ' ' && (at(pos) == ' ' || at(pos - 1) == ' ')) return; - if (IsFont() && (*array)[pos] == t) { + if (IsFont() && at(pos) == t) { fcode(t); ++pos; } else { - if (t != fcode() && pos > 0 && MathIsFont((*array)[pos - 1])) { + if (t != fcode() && pos > 0 && MathIsFont(at(pos - 1))) { --pos; int k = pos - 1; - for (; k >= 0 && (*array)[k] >= ' '; --k) + for (; k >= 0 && at(k) >= ' '; --k) ; - fcode( (k >= 0 && MathIsFont((*array)[k])) ? (*array)[k] : -1 ); + fcode( (k >= 0 && MathIsFont(at(k))) ? at(k) : -1 ); } } - short const f = ((*array)[pos] < ' ') ? 0 : fcode(); + short const f = (at(pos) < ' ') ? 0 : fcode(); int shift = (t == fcode()) ? 1 : ((f) ? 3 : 2); if (t == LM_TC_TAB || t == LM_TC_CR) { @@ -232,21 +241,21 @@ void MathedIter::insert(byte c, MathedTe else { array->need_size(array->last() + shift); array->last(array->last() + shift); - (*array)[array->last()] = '\0'; + at(array->last()) = '\0'; } if (t != fcode()) { if (f) - (*array)[pos + shift - 1] = fcode(); + at(pos + shift - 1) = fcode(); if (c >= ' ') { - (*array)[pos++] = t; + at(pos++) = t; fcode(t); } else fcode(0); } - (*array)[pos++] = c; + at(pos++) = c; } @@ -256,8 +265,8 @@ void MathedIter::split(int shift) if (pos < array->last()) { bool fg = false; - if ((*array)[pos] >= ' ') { - if (pos> 0 && MathIsFont((*array)[pos - 1])) + if (at(pos) >= ' ') { + if (pos> 0 && MathIsFont(at(pos - 1))) --pos; else { fg = true; @@ -268,7 +277,7 @@ void MathedIter::split(int shift) array->move(pos, shift); if (fg) - (*array)[pos + shift - 1] = fcode(); + at(pos + shift - 1) = fcode(); } else { @@ -276,7 +285,7 @@ void MathedIter::split(int shift) array->last(array->last() + shift); } - (*array)[array->last()] = '\0'; + at(array->last()) = '\0'; } @@ -287,20 +296,20 @@ void MathedIter::join(int pos2) return; short f = fcode(); - if (pos > 0 && (*array)[pos] >= ' ' && MathIsFont((*array)[pos - 1])) + if (pos > 0 && at(pos) >= ' ' && MathIsFont(at(pos - 1))) --pos; - if (MathIsFont((*array)[pos2 - 1])) + if (MathIsFont(at(pos2 - 1))) --pos2; - if ((*array)[pos2] >= ' ') { + if (at(pos2) >= ' ') { for (int p = pos2; p > 0; --p) { - if (MathIsFont((*array)[p])) { - f = (*array)[p]; + if (MathIsFont(at(p))) { + f = at(p); break; } } - (*array)[pos++] = f; + at(pos++) = f; } array->move(pos2, pos - pos2); @@ -324,11 +333,11 @@ void MathedIter::insertInset(MathedInset split(shift); - (*array)[pos] = type; + at(pos) = type; array->raw_pointer_insert(p, pos + 1); pos += SizeInset; - (*array)[pos - 1] = type; - (*array)[array->last()] = '\0'; + at(pos - 1) = type; + at(array->last()) = '\0'; fcode(-1); #endif } @@ -343,20 +352,20 @@ bool MathedIter::Delete() byte const c = GetChar(); if (c >= ' ') { - if (MathIsFont((*array)[pos - 1]) && (*array)[pos + 1] < ' ') { + if (MathIsFont(at(pos - 1)) && at(pos + 1) < ' ') { shift = 2; pos--; int i = pos - 1; - for (; i > 0 && !MathIsFont((*array)[i]); --i) + for (; i > 0 && !MathIsFont(at(i)); --i) ; - if (i > 0 && MathIsFont((*array)[i])) - fcode((*array)[i]); + if (i > 0 && MathIsFont(at(i))) + fcode(at(i)); } else shift = 1; } else { - if (MathIsInset((*array)[pos])) + if (MathIsInset(at(pos))) shift = sizeof(char*) + 2; else if (c == LM_TC_TAB || c == LM_TC_CR) { ++shift; @@ -412,37 +421,37 @@ void MathedIter::adjustTabs() bool MathedIter::IsInset() const { - return MathIsInset((*array)[pos]); + return MathIsInset(at(pos)); } bool MathedIter::IsActive() const { - return MathIsActive((*array)[pos]); + return MathIsActive(at(pos)); } bool MathedIter::IsFont() const { - return MathIsFont((*array)[pos]); + return MathIsFont(at(pos)); } bool MathedIter::IsScript() const { - return MathIsScript((*array)[pos]); + return MathIsScript(at(pos)); } bool MathedIter::IsTab() const { - return ((*array)[pos] == LM_TC_TAB); + return (at(pos) == LM_TC_TAB); } bool MathedIter::IsCR() const { - return ((*array)[pos] == LM_TC_CR); + return (at(pos) == LM_TC_CR); } @@ -452,7 +461,7 @@ MathedIter::MathedIter(MathedArray * d) pos = 0; row = 0; col = 0; - fcode( (array && IsFont()) ? (*array)[0] : 0 ); + fcode( (array && IsFont()) ? at(0) : 0 ); } Index: math_iter.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_iter.h,v retrieving revision 1.29 diff -u -p -r1.29 math_iter.h --- math_iter.h 2001/03/06 10:24:45 1.29 +++ math_iter.h 2001/03/15 09:04:26 @@ -110,6 +110,10 @@ public: void setNumCols(int n) { ncols = n; } /// MathedArray * GetData() const; + /// + byte & at(int pos); + /// + byte at(int pos) const; protected: /// void split(int); Index: math_matrixinset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_matrixinset.C,v retrieving revision 1.16 diff -u -p -r1.16 math_matrixinset.C --- math_matrixinset.C 2001/03/10 09:01:23 1.16 +++ math_matrixinset.C 2001/03/15 09:04:26 @@ -19,7 +19,6 @@ MathMatrixInset::MathMatrixInset(int m, { flag = 15; if (n > 0) { - row_.data_ = new MathedRowSt(nc_ + 1); MathedXIter it(this); for (int j = 1; j < n; ++j) it.addRow(); @@ -29,7 +28,8 @@ MathMatrixInset::MathMatrixInset(int m, it.insert('T', LM_TC_TAB); } } else if (n < 0) { - row_.data_ = new MathedRowSt(nc_ + 1); + MathedXIter it(this); + it.addRow(); nr_ = 1; } } @@ -93,27 +93,19 @@ void MathMatrixInset::draw(Painter & pai void MathMatrixInset::Metrics() { - //if (row_.empty()) { -#warning This leaks row_.data but goes away soon - // lyxerr << " MIDA "; - MathedXIter it(this); - it.GoBegin(); - if (!it.crow_) { - it.crow_.st_ = new MathedRowSt(it.ncols + 1); // this leaks - } - MathedRowSt * mrow = it.crow_.st_; - while (it.OK()) { - if (it.IsCR()) { - if (it.col >= it.ncols) - it.ncols = it.col + 1; - MathedRowSt * r = new MathedRowSt(it.ncols + 1); // this leaks - it.crow_.st_->next_ = r; - it.crow_.st_ = r; - } - it.Next(); - } - row_.data_ = mrow; - //} + // Adjust row structure + MathedXIter it(this); + it.GoBegin(); + int nrows = 1; + while (it.OK()) { + if (it.IsCR()) { + ++nrows; + if (it.col >= it.ncols) + it.ncols = it.col + 1; + } + it.Next(); + } + row_.data_.resize(nrows); // Clean the arrays for (MathedRowContainer::iterator it = row_.begin(); it; ++it) Index: math_parser.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_parser.C,v retrieving revision 1.41 diff -u -p -r1.41 math_parser.C --- math_parser.C 2001/03/09 23:55:50 1.41 +++ math_parser.C 2001/03/15 09:04:26 @@ -604,7 +604,7 @@ void mathed_parse(MathedArray & array, u case LM_TK_NEWLINE: if (mt && (flags & FLAG_END)) { if (mt->Permit(LMPF_ALLOW_CR)) { - mt->getRowSt().insert_after(crow, MathedRowSt(mt->GetColumns() + 1)); + mt->getRowSt().insert(crow); ++crow; data.insert('K', LM_TC_CR); } else Index: math_rowst.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_rowst.h,v retrieving revision 1.10 diff -u -p -r1.10 math_rowst.h --- math_rowst.h 2001/03/12 13:58:11 1.10 +++ math_rowst.h 2001/03/15 09:04:26 @@ -17,10 +17,8 @@ public: typedef std::vector<int> Widths; /// - explicit - MathedRowStruct(int n) - : asc_(0), desc_(0), y_(0), widths_(n + 1, 0), - numbered_(true) + MathedRowStruct() + : asc_(0), desc_(0), y_(0), numbered_(true) {} /// string const & getLabel() const; @@ -64,25 +62,6 @@ protected: }; -class MathedRowContainer; - -class MathedRowSt : public MathedRowStruct { -public: - /// - explicit MathedRowSt(int n) - : MathedRowStruct(n), next_(0) - {} - explicit MathedRowSt(MathedRowStruct const & t) - : MathedRowStruct(t), next_(0) - {} -//private: - /// - MathedRowSt * next_; - /// - friend class MathedRowContainer; -}; - - // The idea is to change this MathedRowContainer to mimic the behaviour // of std::list<MathedRowStruct> in several small steps. In the end it // could be replaced by such a list and MathedRowSt can go as well. @@ -91,104 +70,51 @@ struct MathedRowContainer { /// struct iterator { /// - iterator() : st_(0) {} + iterator() : st_(0), pos_(0) {} /// - explicit iterator(MathedRowSt * st) : st_(st) {} + explicit iterator(MathedRowContainer * m) : st_(m), pos_(0) {} + /// "better" conversion to bool, static_cast doens't help? + operator void *() const + { return (void *)(st_ && pos_ < st_->data_.size()); } /// - explicit iterator(MathedRowContainer * m) : st_(m->data_) {} - /// "better" conversion to bool - operator void *() const { return st_; } + MathedRowStruct & operator*() { Assert(st_); return st_->data_[pos_]; } /// - MathedRowStruct & operator*() { Assert(st_); return *st_; } + MathedRowStruct * operator->() { return &st_->data_[pos_]; } /// - MathedRowStruct * operator->() { return st_; } + MathedRowStruct const * operator->() const { return &st_->data_[pos_]; +} /// - MathedRowStruct const * operator->() const { return st_; } + void operator++() { Assert(st_); ++pos_; } /// - void operator++() { Assert(st_); st_ = st_->next_; } + bool is_last() const { Assert(st_); return pos_ == st_->data_.size() - +1; } /// - bool is_last() const { Assert(st_); return st_->next_ == 0; } - /// - bool operator==(const iterator & it) const { return st_ == it.st_; } + bool operator==(const iterator & it) const + { return st_ == it.st_ && pos_ == it.pos_; } //private: + /// + MathedRowContainer * st_; /// - MathedRowSt * st_; + unsigned int pos_; }; /// - MathedRowContainer() : data_(0) {} - - /// - MathedRowContainer(MathedRowContainer const & c) : data_(0) { - if (!c.empty()) { - MathedRowSt * ro = 0; - MathedRowSt * mrow = c.data_; - - while (mrow) { - MathedRowSt * r = new MathedRowSt(*mrow); - if (!ro) - data_ = r; - else - ro->next_ = r; - mrow = mrow->next_; - ro = r; - } - } - } - - - ~MathedRowContainer() { - MathedRowSt * r = data_; - while (r) { - MathedRowSt * q = r->next_; - delete r; - r = q; - } - } - - /// iterator begin() { return iterator(this); } /// - bool empty() const { return data_ == 0; } + bool empty() const { return data_.size() == 0; } /// insert 'item' before 'iterator' - void insert(iterator const & it, MathedRowStruct const & item) { - MathedRowSt * r = new MathedRowSt(item); - if (data_ == it.st_) - data_ = r; - else { - MathedRowSt * pos = data_; - if (pos->next_ == it.st_) - pos->next_ = r; - } - r->next_ = it.st_; + void insert(iterator const & it) { + Assert(it.st_ == this); + data_.insert(data_.begin() + it.pos_, MathedRowStruct()); } - /// insert 'item' after 'iterator' - void insert_after(iterator & it, MathedRowStruct const & item) { - MathedRowSt * r = new MathedRowSt(item); - if (it) { - r->next_ = it.st_->next_; - it.st_->next_ = r; - } else { - it.st_ = r; - r->next_ = 0; - } - } - void erase(iterator & it) { - Assert(it.st_); - MathedRowSt * r = it.st_->next_; - if (r) { - it.st_->next_ = r->next_; - delete r; - } + Assert(it.st_ == this); + data_.erase(data_.begin() + it.pos_); } - /// - MathedRowSt * data_; + std::vector<MathedRowStruct> data_; private: // currently unimplemented just to make sure it's not used Index: math_xiter.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_xiter.C,v retrieving revision 1.18 diff -u -p -r1.18 math_xiter.C --- math_xiter.C 2001/03/10 09:01:23 1.18 +++ math_xiter.C 2001/03/15 09:04:26 @@ -156,7 +156,7 @@ void MathedXIter::Merge(MathedArray cons while (pos < pos2 && OK()) { if (IsCR()) { if (p_ && p_->Permit(LMPF_ALLOW_CR)) { - container().insert_after(crow_, MathedRowSt(ncols + 1)); + container().insert(crow_); ++crow_; } else { Delete(); @@ -369,7 +369,7 @@ void MathedXIter::addRow() } // Create new item for the structure - container().insert_after(crow_, MathedRowSt(ncols + 1)); + container().insert(crow_); // Fill missed tabs in current row while (col < ncols - 1) insert('T', LM_TC_TAB);