From: Guillaume Munch Date: Mon, 14 Dec 2015 01:54:27 +0000 (+0000) Subject: Sanitize InsetMathHull and add a check for mutability in LFUN_MATH_MUTATE X-Git-Tag: 2.3.0alpha1~1668 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=935588f2de4703471c1dc9bac6ec0707bf3d4d8f;p=features.git Sanitize InsetMathHull and add a check for mutability in LFUN_MATH_MUTATE Remove in particular all comparisons < and >= involving HullType. Add a guard to make sure that mutate() only operates on types it has been designed for. Then I figured I could use this new knowledge to give feedback when math-mutate is not implemented via getStatus(). (To test this, insert a regexp in Advanced Search & Replace and try to change it into a standard equation via the contextual menu.) --- diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h index bd72863c3a..deb6915e9a 100644 --- a/src/mathed/InsetMath.h +++ b/src/mathed/InsetMath.h @@ -34,7 +34,8 @@ enum HullType { hullFlAlign, hullMultline, hullGather, - hullRegexp + hullRegexp, + hullUnknown }; HullType hullType(docstring const & name); diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp index 1ff65b2c6d..3d120a5da8 100644 --- a/src/mathed/InsetMathGrid.cpp +++ b/src/mathed/InsetMathGrid.cpp @@ -1850,17 +1850,32 @@ char InsetMathGrid::colAlign(HullType type, col_type col) case hullFlAlign: return "rl"[col & 1]; - default: + case hullUnknown: + case hullNone: + case hullSimple: + case hullEquation: + case hullRegexp: return 'c'; } + // avoid warning + return 'c'; } //static int InsetMathGrid::colSpace(HullType type, col_type col) { - int alignInterSpace; + int alignInterSpace = 0; switch (type) { + case hullUnknown: + case hullNone: + case hullSimple: + case hullEquation: + case hullMultline: + case hullGather: + case hullRegexp: + return 0; + case hullEqnArray: return 5; @@ -1877,8 +1892,6 @@ int InsetMathGrid::colSpace(HullType type, col_type col) case hullFlAlign: alignInterSpace = 60; break; - default: - return 0; } return (col % 2) ? alignInterSpace : 0; } diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index be10783b7a..e684d237f5 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -79,17 +79,25 @@ namespace { int getCols(HullType type) { switch (type) { - case hullEqnArray: - return 3; - case hullAlign: - case hullFlAlign: - case hullAlignAt: - case hullXAlignAt: - case hullXXAlignAt: - return 2; - default: - return 1; + case hullEqnArray: + return 3; + case hullAlign: + case hullFlAlign: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + return 2; + case hullUnknown: + case hullNone: + case hullSimple: + case hullEquation: + case hullMultline: + case hullGather: + case hullRegexp: + return 1; } + // avoid warning + return 0; } @@ -128,29 +136,30 @@ HullType hullType(docstring const & s) if (s == "flalign") return hullFlAlign; if (s == "regexp") return hullRegexp; lyxerr << "unknown hull type '" << to_utf8(s) << "'" << endl; - return HullType(-1); + return hullUnknown; } docstring hullName(HullType type) { switch (type) { - case hullNone: return from_ascii("none"); - case hullSimple: return from_ascii("simple"); - case hullEquation: return from_ascii("equation"); - case hullEqnArray: return from_ascii("eqnarray"); - case hullAlign: return from_ascii("align"); - case hullAlignAt: return from_ascii("alignat"); - case hullXAlignAt: return from_ascii("xalignat"); - case hullXXAlignAt: return from_ascii("xxalignat"); - case hullMultline: return from_ascii("multline"); - case hullGather: return from_ascii("gather"); - case hullFlAlign: return from_ascii("flalign"); - case hullRegexp: return from_ascii("regexp"); - default: - lyxerr << "unknown hull type '" << type << "'" << endl; - return from_ascii("none"); + case hullNone: return from_ascii("none"); + case hullSimple: return from_ascii("simple"); + case hullEquation: return from_ascii("equation"); + case hullEqnArray: return from_ascii("eqnarray"); + case hullAlign: return from_ascii("align"); + case hullAlignAt: return from_ascii("alignat"); + case hullXAlignAt: return from_ascii("xalignat"); + case hullXXAlignAt: return from_ascii("xxalignat"); + case hullMultline: return from_ascii("multline"); + case hullGather: return from_ascii("gather"); + case hullFlAlign: return from_ascii("flalign"); + case hullRegexp: return from_ascii("regexp"); + case hullUnknown: + lyxerr << "unknown hull type" << endl; + break; } + return from_ascii("none"); } static InsetLabel * dummy_pointer = 0; @@ -326,9 +335,26 @@ Inset * InsetMathHull::editXY(Cursor & cur, int x, int y) InsetMath::mode_type InsetMathHull::currentMode() const { - if (type_ == hullNone) + switch (type_) { + case hullNone: return UNDECIDED_MODE; + // definitely math mode ... + case hullUnknown: + case hullSimple: + case hullEquation: + case hullMultline: + case hullGather: + case hullEqnArray: + case hullAlign: + case hullFlAlign: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + case hullRegexp: + return MATH_MODE; + } + // avoid warning return MATH_MODE; } @@ -401,33 +427,27 @@ int InsetMathHull::defaultColSpace(col_type col) docstring InsetMathHull::standardFont() const { - docstring font_name; switch (type_) { case hullRegexp: - font_name = from_ascii("texttt"); - break; + return from_ascii("texttt"); case hullNone: - font_name = from_ascii("lyxnochange"); - break; + return from_ascii("lyxnochange"); default: - font_name = from_ascii("mathnormal"); + return from_ascii("mathnormal"); } - return font_name; } ColorCode InsetMathHull::standardColor() const { - ColorCode color; switch (type_) { case hullRegexp: case hullNone: - color = Color_foreground; - break; + return Color_foreground; + default: - color = Color_math; + return Color_math; } - return color; } @@ -850,20 +870,22 @@ bool InsetMathHull::numbered(row_type row) const bool InsetMathHull::ams() const { switch (type_) { - case hullAlign: - case hullFlAlign: - case hullMultline: - case hullGather: - case hullAlignAt: - case hullXAlignAt: - case hullXXAlignAt: - return true; - case hullNone: - case hullSimple: - case hullEquation: - case hullEqnArray: - case hullRegexp: - break; + case hullAlign: + case hullFlAlign: + case hullMultline: + case hullGather: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + return true; + case hullUnknown: + case hullRegexp: + return false; + case hullNone: + case hullSimple: + case hullEquation: + case hullEqnArray: + break; } for (size_t row = 0; row < numbered_.size(); ++row) if (numbered_[row] == NOTAG) @@ -874,21 +896,46 @@ bool InsetMathHull::ams() const Inset::DisplayType InsetMathHull::display() const { - if (type_ == hullSimple || type_ == hullNone || type_ == hullRegexp) + switch (type_) { + case hullUnknown: + case hullSimple: + case hullNone: + case hullRegexp: return Inline; + case hullEqnArray: + case hullAlign: + case hullFlAlign: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + case hullEquation: + case hullMultline: + case hullGather: + return AlignCenter; + } + // avoid warning return AlignCenter; } bool InsetMathHull::numberedType() const { - if (type_ == hullNone) - return false; - if (type_ == hullSimple) - return false; - if (type_ == hullXXAlignAt) - return false; - if (type_ == hullRegexp) + switch (type_) { + case hullUnknown: + case hullNone: + case hullSimple: + case hullXXAlignAt: + case hullRegexp: return false; + case hullEqnArray: + case hullAlign: + case hullFlAlign: + case hullAlignAt: + case hullXAlignAt: + case hullEquation: + case hullMultline: + case hullGather: + break; + } for (row_type row = 0; row < nrows(); ++row) if (numbered(row)) return true; @@ -987,7 +1034,7 @@ void InsetMathHull::header_write(WriteStream & os) const os << "\\regexp{"; break; - default: + case hullUnknown: os << "\n"; os.startOuterRow(); os << "\\begin{unknown" << star(n) << "}\n"; @@ -1041,7 +1088,7 @@ void InsetMathHull::footer_write(WriteStream & os) const os << "\\endregexp{}}"; break; - default: + case hullUnknown: os << "\n"; os.startOuterRow(); os << "\\end{unknown" << star(n) << "}\n"; @@ -1066,6 +1113,7 @@ bool InsetMathHull::isTable() const case hullSimple: case hullEquation: case hullRegexp: + case hullUnknown: break; } return false; @@ -1273,10 +1321,46 @@ void InsetMathHull::setType(HullType type) } +bool InsetMathHull::isMutable(HullType type) +{ + switch (type) { + case hullNone: + case hullSimple: + case hullEquation: + case hullEqnArray: + case hullAlign: + case hullFlAlign: + case hullAlignAt: + case hullXAlignAt: + case hullXXAlignAt: + case hullMultline: + case hullGather: + return true; + case hullUnknown: + case hullRegexp: + return false; + } + // avoid warning + return false; +} + + void InsetMathHull::mutate(HullType newtype) { //lyxerr << "mutating from '" << type_ << "' to '" << newtype << "'" << endl; + if (newtype == type_) + return; + + // This guards the algorithm below it, which is designed with certain types + // in mind. + if (!isMutable(newtype) || !isMutable(type_)) { + lyxerr << "mutation from '" << to_utf8(hullName(type_)) + << "' to '" << to_utf8(hullName(newtype)) + << "' not implemented" << endl; + return; + } + // we try to move along the chain // none <-> simple <-> equation <-> eqnarray -> *align* -> multline, gather -+ // ^ | @@ -1285,22 +1369,14 @@ void InsetMathHull::mutate(HullType newtype) // directly supported because it handles labels and numbering for // "down mutation". - if (newtype == type_) { - // done - } - - else if (newtype < hullNone) { - // unknown type - dump(); - } - - else if (type_ == hullNone) { + switch (type_) { + case hullNone: setType(hullSimple); numbered(0, false); mutate(newtype); - } + break; - else if (type_ == hullSimple) { + case hullSimple: if (newtype == hullNone) { setType(hullNone); numbered(0, false); @@ -1309,95 +1385,138 @@ void InsetMathHull::mutate(HullType newtype) numbered(0, label_[0] ? true : false); mutate(newtype); } - } + break; - else if (type_ == hullEquation) { - if (newtype < type_) { + case hullEquation: + switch (newtype) { + case hullNone: + case hullSimple: setType(hullSimple); numbered(0, false); mutate(newtype); - } else if (newtype == hullEqnArray) { + break; + case hullEqnArray: // split it "nicely" on the first relop splitTo3Cols(); setType(hullEqnArray); - } else if (newtype == hullMultline || newtype == hullGather) { + break; + case hullMultline: + case hullGather: setType(newtype); - } else { + break; + default: + // *align* // split it "nicely" splitTo2Cols(); setType(hullAlign); mutate(newtype); + break; } - } + break; - else if (type_ == hullEqnArray) { - if (newtype < type_) { + case hullEqnArray: + switch (newtype) { + case hullNone: + case hullSimple: + case hullEquation: glueall(newtype); mutate(newtype); - } else { // align & Co. + break; + default: + // align & Co. changeCols(2); setType(hullAlign); mutate(newtype); + break; } - } + break; - else if (type_ == hullAlign || type_ == hullAlignAt || - type_ == hullXAlignAt || type_ == hullFlAlign) { - if (newtype < hullAlign) { + case hullAlign: + case hullAlignAt: + case hullXAlignAt: + case hullFlAlign: + switch (newtype) { + case hullNone: + case hullSimple: + case hullEquation: + case hullEqnArray: changeCols(3); setType(hullEqnArray); mutate(newtype); - } else if (newtype == hullGather || newtype == hullMultline) { + break; + case hullGather: + case hullMultline: changeCols(1); setType(newtype); - } else if (newtype == hullXXAlignAt) { + break; + case hullXXAlignAt: for (row_type row = 0; row < nrows(); ++row) numbered(row, false); setType(newtype); - } else { + break; + default: setType(newtype); + break; } - } + break; - else if (type_ == hullXXAlignAt) { + case hullXXAlignAt: for (row_type row = 0; row < nrows(); ++row) numbered(row, false); - if (newtype < hullAlign) { + switch (newtype) { + case hullNone: + case hullSimple: + case hullEquation: + case hullEqnArray: changeCols(3); setType(hullEqnArray); mutate(newtype); - } else if (newtype == hullGather || newtype == hullMultline) { + break; + case hullGather: + case hullMultline: changeCols(1); setType(newtype); - } else { + break; + default: setType(newtype); + break; } - } + break; - else if (type_ == hullMultline || type_ == hullGather) { - if (newtype == hullGather || newtype == hullMultline) + case hullMultline: + case hullGather: + switch (newtype) { + case hullGather: + case hullMultline: setType(newtype); - else if (newtype == hullAlign || newtype == hullFlAlign || - newtype == hullAlignAt || newtype == hullXAlignAt) { + break; + case hullAlign: + case hullFlAlign: + case hullAlignAt: + case hullXAlignAt: splitTo2Cols(); setType(newtype); - } else if (newtype == hullXXAlignAt) { + break; + case hullXXAlignAt: splitTo2Cols(); for (row_type row = 0; row < nrows(); ++row) numbered(row, false); setType(newtype); - } else { + break; + default: + // first we mutate to EqnArray splitTo3Cols(); setType(hullEqnArray); mutate(newtype); + break; } - } + break; - else { - lyxerr << "mutation from '" << to_utf8(hullName(type_)) - << "' to '" << to_utf8(hullName(newtype)) - << "' not implemented" << endl; - } + default: + // we passed the guard so we should not be here + LASSERT("Mutation not implemented, but should have been.", return); + break; + }// switch } @@ -1475,7 +1594,12 @@ void InsetMathHull::doExtern(Cursor & cur, FuncRequest & func) } // only inline, display or eqnarray math is allowed - if (getType() > hullEqnArray) { + switch (getType()) { + case hullSimple: + case hullEquation: + case hullEqnArray: + break; + default: frontend::Alert::warning(_("Bad math environment"), _("Computation cannot be performed for AMS " "math environments.\nChange the math " @@ -1772,9 +1896,9 @@ bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_MATH_MUTATE: { HullType const ht = hullType(cmd.argument()); status.setOnOff(type_ == ht); - status.setEnabled(true); + status.setEnabled(isMutable(ht) && isMutable(type_)); - if (ht != hullSimple) { + if (ht != hullSimple && status.enabled()) { Cursor tmpcur = cur; while (!tmpcur.empty()) { InsetCode code = tmpcur.inset().lyxCode(); diff --git a/src/mathed/InsetMathHull.h b/src/mathed/InsetMathHull.h index 6578fd3e87..b79b515ac2 100644 --- a/src/mathed/InsetMathHull.h +++ b/src/mathed/InsetMathHull.h @@ -105,6 +105,8 @@ public: /// get type HullType getType() const; + /// is mutation implemented for this type? + static bool isMutable(HullType type); /// change type void mutate(HullType newtype);