mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Support for "else if" syntax
This commit is contained in:
parent
6b04eb793f
commit
79fd837145
7 changed files with 197 additions and 25 deletions
|
@ -11,6 +11,7 @@ src/decompile/cpp/Doxyfile||GHIDRA|||Most of this file is autogenerated by doxyg
|
||||||
src/decompile/cpp/Makefile||GHIDRA||||END|
|
src/decompile/cpp/Makefile||GHIDRA||||END|
|
||||||
src/decompile/datatests/convert.xml||GHIDRA||||END|
|
src/decompile/datatests/convert.xml||GHIDRA||||END|
|
||||||
src/decompile/datatests/deadvolatile.xml||GHIDRA||||END|
|
src/decompile/datatests/deadvolatile.xml||GHIDRA||||END|
|
||||||
|
src/decompile/datatests/elseif.xml||GHIDRA||||END|
|
||||||
src/decompile/datatests/floatprint.xml||GHIDRA||||END|
|
src/decompile/datatests/floatprint.xml||GHIDRA||||END|
|
||||||
src/decompile/datatests/forloop1.xml||GHIDRA||||END|
|
src/decompile/datatests/forloop1.xml||GHIDRA||||END|
|
||||||
src/decompile/datatests/forloop_loaditer.xml||GHIDRA||||END|
|
src/decompile/datatests/forloop_loaditer.xml||GHIDRA||||END|
|
||||||
|
|
|
@ -71,6 +71,7 @@ void EmitXml::endBlock(int4 id) {
|
||||||
|
|
||||||
/// Tell the emitter that a new line is desired at the current indent level
|
/// Tell the emitter that a new line is desired at the current indent level
|
||||||
void EmitXml::tagLine(void) {
|
void EmitXml::tagLine(void) {
|
||||||
|
emitPending();
|
||||||
*s << "<break " << highlight[(int4)no_color] << " indent=\"0x" << hex <<
|
*s << "<break " << highlight[(int4)no_color] << " indent=\"0x" << hex <<
|
||||||
indentlevel << "\"/>";
|
indentlevel << "\"/>";
|
||||||
}
|
}
|
||||||
|
@ -79,6 +80,7 @@ void EmitXml::tagLine(void) {
|
||||||
/// is overridden only for the line, then it returns to its previous value.
|
/// is overridden only for the line, then it returns to its previous value.
|
||||||
/// \param indent is the desired indent level for the new line
|
/// \param indent is the desired indent level for the new line
|
||||||
void EmitXml::tagLine(int4 indent) {
|
void EmitXml::tagLine(int4 indent) {
|
||||||
|
emitPending();
|
||||||
*s << "<break " << highlight[(int4)no_color] << " indent=\"0x" << hex <<
|
*s << "<break " << highlight[(int4)no_color] << " indent=\"0x" << hex <<
|
||||||
indent << "\"/>";
|
indent << "\"/>";
|
||||||
}
|
}
|
||||||
|
@ -923,6 +925,7 @@ void EmitPrettyPrint::endBlock(int4 id)
|
||||||
void EmitPrettyPrint::tagLine(void)
|
void EmitPrettyPrint::tagLine(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
emitPending();
|
||||||
checkbreak();
|
checkbreak();
|
||||||
TokenSplit &tok( tokqueue.push() );
|
TokenSplit &tok( tokqueue.push() );
|
||||||
tok.tagLine();
|
tok.tagLine();
|
||||||
|
@ -932,6 +935,7 @@ void EmitPrettyPrint::tagLine(void)
|
||||||
void EmitPrettyPrint::tagLine(int4 indent)
|
void EmitPrettyPrint::tagLine(int4 indent)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
emitPending();
|
||||||
checkbreak();
|
checkbreak();
|
||||||
TokenSplit &tok( tokqueue.push() );
|
TokenSplit &tok( tokqueue.push() );
|
||||||
tok.tagLine(indent);
|
tok.tagLine(indent);
|
||||||
|
|
|
@ -26,6 +26,7 @@ class PcodeOp;
|
||||||
class FlowBlock;
|
class FlowBlock;
|
||||||
class Funcdata;
|
class Funcdata;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
|
class PendPrint;
|
||||||
|
|
||||||
/// \brief Base class (and interface) for pretty printing and XML markup of tokens
|
/// \brief Base class (and interface) for pretty printing and XML markup of tokens
|
||||||
///
|
///
|
||||||
|
@ -80,9 +81,11 @@ protected:
|
||||||
int4 indentlevel; ///< Current indent level (in fixed width characters)
|
int4 indentlevel; ///< Current indent level (in fixed width characters)
|
||||||
int4 parenlevel; ///< Current depth of parentheses
|
int4 parenlevel; ///< Current depth of parentheses
|
||||||
int4 indentincrement; ///< Change in indentlevel per level of nesting
|
int4 indentincrement; ///< Change in indentlevel per level of nesting
|
||||||
|
PendPrint *pendPrint; ///< Pending print callback
|
||||||
void resetDefaultsInternal(void) { indentincrement = 2; } ///< Set options to default values for EmitXml
|
void resetDefaultsInternal(void) { indentincrement = 2; } ///< Set options to default values for EmitXml
|
||||||
|
void emitPending(void); ///< Emit any pending print commands
|
||||||
public:
|
public:
|
||||||
EmitXml(void) { s = (ostream *)0; indentlevel=0; parenlevel=0; resetDefaultsInternal(); } ///< Constructor
|
EmitXml(void) { s = (ostream *)0; indentlevel=0; parenlevel=0; pendPrint=(PendPrint *)0; resetDefaultsInternal(); } ///< Constructor
|
||||||
|
|
||||||
/// \brief Possible types of syntax highlighting
|
/// \brief Possible types of syntax highlighting
|
||||||
enum syntax_highlight {
|
enum syntax_highlight {
|
||||||
|
@ -136,7 +139,7 @@ public:
|
||||||
/// Inform the emitter that a printing group is ending.
|
/// Inform the emitter that a printing group is ending.
|
||||||
/// \param id is the id associated with the group (as returned by openGroup)
|
/// \param id is the id associated with the group (as returned by openGroup)
|
||||||
virtual void closeGroup(int4 id) {}
|
virtual void closeGroup(int4 id) {}
|
||||||
virtual void clear(void) { parenlevel = 0; indentlevel=0; } ///< Reset the emitter to its initial state
|
virtual void clear(void) { parenlevel = 0; indentlevel=0; pendPrint=(PendPrint *)0; } ///< Reset the emitter to its initial state
|
||||||
virtual void setOutputStream(ostream *t) { s = t; } ///< Set the output stream for the emitter
|
virtual void setOutputStream(ostream *t) { s = t; } ///< Set the output stream for the emitter
|
||||||
virtual ostream *getOutputStream(void) const { return s; } ///< Get the current output stream
|
virtual ostream *getOutputStream(void) const { return s; } ///< Get the current output stream
|
||||||
virtual void spaces(int4 num,int4 bump=0);
|
virtual void spaces(int4 num,int4 bump=0);
|
||||||
|
@ -214,6 +217,24 @@ public:
|
||||||
///
|
///
|
||||||
/// \param val is the desired number of characters to indent
|
/// \param val is the desired number of characters to indent
|
||||||
void setIndentIncrement(int4 val) { indentincrement = val; }
|
void setIndentIncrement(int4 val) { indentincrement = val; }
|
||||||
|
|
||||||
|
/// \brief Set a pending print callback
|
||||||
|
///
|
||||||
|
/// The callback will be issued prior to the the next call to tagLine() unless
|
||||||
|
/// a the method cancelPendingPrint() is called first.
|
||||||
|
/// \param pend is the callback to be issued
|
||||||
|
void setPendingPrint(PendPrint *pend) { pendPrint = pend; }
|
||||||
|
|
||||||
|
/// \brief Cancel any pending print callback
|
||||||
|
///
|
||||||
|
/// If there is any print callback pending, cancel it
|
||||||
|
void cancelPendingPrint(void) { pendPrint = (PendPrint *)0; }
|
||||||
|
|
||||||
|
/// \brief Check if the given print callback is still pending
|
||||||
|
///
|
||||||
|
/// \param pend is the given print callback to check
|
||||||
|
/// \return \b true if the specific print callback is pending
|
||||||
|
bool hasPendingPrint(PendPrint *pend) const { return (pendPrint == pend); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A trivial emitter that outputs syntax straight to the stream
|
/// \brief A trivial emitter that outputs syntax straight to the stream
|
||||||
|
@ -779,4 +800,25 @@ public:
|
||||||
void setXML(bool val); ///< Toggle whether the low-level emitter emits XML markup or not
|
void setXML(bool val); ///< Toggle whether the low-level emitter emits XML markup or not
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Helper class for sending cancelable print commands to an ExitXml
|
||||||
|
///
|
||||||
|
/// The PendPrint is issued as a placeholder for commands to the emitter using its
|
||||||
|
/// setPendingPrint() method. The callback() method is overridden to tailor the exact
|
||||||
|
/// sequence of print commands. The print commands will be executed prior to the next
|
||||||
|
/// tagLine() call to the emitter, unless the PendPrint is cancelled.
|
||||||
|
class PendPrint {
|
||||||
|
public:
|
||||||
|
virtual ~PendPrint(void) {} ///< Destructor
|
||||||
|
virtual void callback(EmitXml *emit)=0; ///< Callback that executes the actual print commands
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void EmitXml::emitPending(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (pendPrint != (PendPrint *)0) {
|
||||||
|
pendPrint->callback(this);
|
||||||
|
pendPrint = (PendPrint *)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2596,17 +2596,28 @@ void PrintC::emitBlockCondition(const BlockCondition *bl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PendingBrace::callback(EmitXml *emit)
|
||||||
|
|
||||||
|
{
|
||||||
|
emit->print("{");
|
||||||
|
indentId = emit->startIndent();
|
||||||
|
}
|
||||||
|
|
||||||
void PrintC::emitBlockIf(const BlockIf *bl)
|
void PrintC::emitBlockIf(const BlockIf *bl)
|
||||||
|
|
||||||
{
|
{
|
||||||
const PcodeOp *op;
|
const PcodeOp *op;
|
||||||
|
PendingBrace pendingBrace;
|
||||||
|
|
||||||
|
if (isSet(pending_brace))
|
||||||
|
emit->setPendingPrint(&pendingBrace);
|
||||||
|
|
||||||
// if block never prints final branch
|
// if block never prints final branch
|
||||||
// so no_branch and only_branch don't matter
|
// so no_branch and only_branch don't matter
|
||||||
// and shouldn't be passed automatically to
|
// and shouldn't be passed automatically to
|
||||||
// the subblocks
|
// the subblocks
|
||||||
pushMod();
|
pushMod();
|
||||||
unsetMod(no_branch|only_branch);
|
unsetMod(no_branch|only_branch|pending_brace);
|
||||||
|
|
||||||
pushMod();
|
pushMod();
|
||||||
setMod(no_branch);
|
setMod(no_branch);
|
||||||
|
@ -2614,7 +2625,11 @@ void PrintC::emitBlockIf(const BlockIf *bl)
|
||||||
condBlock->emit(this);
|
condBlock->emit(this);
|
||||||
popMod();
|
popMod();
|
||||||
emitCommentBlockTree(condBlock);
|
emitCommentBlockTree(condBlock);
|
||||||
emit->tagLine();
|
if (emit->hasPendingPrint(&pendingBrace)) // If we issued a brace but it did not emit
|
||||||
|
emit->cancelPendingPrint(); // Cancel the brace in order to have "else if" syntax
|
||||||
|
else
|
||||||
|
emit->tagLine(); // Otherwise start the "if" on a new line
|
||||||
|
|
||||||
op = condBlock->lastOp();
|
op = condBlock->lastOp();
|
||||||
emit->tagOp("if",EmitXml::keyword_color,op);
|
emit->tagOp("if",EmitXml::keyword_color,op);
|
||||||
emit->spaces(1);
|
emit->spaces(1);
|
||||||
|
@ -2625,34 +2640,48 @@ void PrintC::emitBlockIf(const BlockIf *bl)
|
||||||
if (bl->getGotoTarget() != (FlowBlock *)0) {
|
if (bl->getGotoTarget() != (FlowBlock *)0) {
|
||||||
emit->spaces(1);
|
emit->spaces(1);
|
||||||
emitGotoStatement(condBlock,bl->getGotoTarget(),bl->getGotoType());
|
emitGotoStatement(condBlock,bl->getGotoTarget(),bl->getGotoType());
|
||||||
popMod();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
setMod(no_branch);
|
setMod(no_branch);
|
||||||
emit->spaces(1);
|
|
||||||
int4 id = emit->startIndent();
|
|
||||||
emit->print("{");
|
|
||||||
int4 id1 = emit->beginBlock(bl->getBlock(1));
|
|
||||||
bl->getBlock(1)->emit(this);
|
|
||||||
emit->endBlock(id1);
|
|
||||||
emit->stopIndent(id);
|
|
||||||
emit->tagLine();
|
|
||||||
emit->print("}");
|
|
||||||
if (bl->getSize()==3) {
|
|
||||||
emit->tagLine();
|
|
||||||
emit->print("else",EmitXml::keyword_color);
|
|
||||||
emit->spaces(1);
|
emit->spaces(1);
|
||||||
int4 id = emit->startIndent();
|
int4 id = emit->startIndent();
|
||||||
emit->print("{");
|
emit->print("{");
|
||||||
int4 id2 = emit->beginBlock(bl->getBlock(2));
|
int4 id1 = emit->beginBlock(bl->getBlock(1));
|
||||||
bl->getBlock(2)->emit(this);
|
bl->getBlock(1)->emit(this);
|
||||||
emit->endBlock(id2);
|
emit->endBlock(id1);
|
||||||
emit->stopIndent(id);
|
emit->stopIndent(id);
|
||||||
emit->tagLine();
|
emit->tagLine();
|
||||||
emit->print("}");
|
emit->print("}");
|
||||||
|
if (bl->getSize() == 3) {
|
||||||
|
emit->tagLine();
|
||||||
|
emit->print("else",EmitXml::keyword_color);
|
||||||
|
emit->spaces(1);
|
||||||
|
FlowBlock *elseBlock = bl->getBlock(2);
|
||||||
|
if (elseBlock->getType() == FlowBlock::t_if) {
|
||||||
|
// Attempt to merge the "else" and "if" syntax
|
||||||
|
setMod(pending_brace);
|
||||||
|
int4 id2 = emit->beginBlock(elseBlock);
|
||||||
|
elseBlock->emit(this);
|
||||||
|
emit->endBlock(id2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int4 id = emit->startIndent();
|
||||||
|
emit->print("{");
|
||||||
|
int4 id2 = emit->beginBlock(elseBlock);
|
||||||
|
elseBlock->emit(this);
|
||||||
|
emit->endBlock(id2);
|
||||||
|
emit->stopIndent(id);
|
||||||
|
emit->tagLine();
|
||||||
|
emit->print("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
popMod();
|
popMod();
|
||||||
|
if (pendingBrace.getIndentId() >= 0) {
|
||||||
|
emit->stopIndent(pendingBrace.getIndentId());
|
||||||
|
emit->tagLine();
|
||||||
|
emit->print("}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print the loop using the keyword \e for, followed by a semicolon separated
|
/// Print the loop using the keyword \e for, followed by a semicolon separated
|
||||||
|
|
|
@ -301,4 +301,16 @@ public:
|
||||||
virtual void opPopcountOp(const PcodeOp *op) { opFunc(op); }
|
virtual void opPopcountOp(const PcodeOp *op) { opFunc(op); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Set of print commands for displaying an open brace '{' and setting a new indent level
|
||||||
|
///
|
||||||
|
/// These are the print commands sent to the emitter prior to printing and \e else block.
|
||||||
|
/// The open brace can be canceled if the block decides it wants to use "else if" syntax.
|
||||||
|
class PendingBrace : public PendPrint {
|
||||||
|
int4 indentId; ///< Id associated with the new indent level
|
||||||
|
public:
|
||||||
|
PendingBrace(void) { indentId = -1; } ///< Constructor
|
||||||
|
int4 getIndentId(void) const { return indentId; } ///< If commands have been issued, returns the new indent level id.
|
||||||
|
virtual void callback(EmitXml *emit);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -149,7 +149,8 @@ public:
|
||||||
falsebranch = 0x800, ///< Print the false branch (for flat)
|
falsebranch = 0x800, ///< Print the false branch (for flat)
|
||||||
nofallthru = 0x1000, ///< Fall-thru no longer exists
|
nofallthru = 0x1000, ///< Fall-thru no longer exists
|
||||||
negatetoken = 0x2000, ///< Print the token representing the negation of current token
|
negatetoken = 0x2000, ///< Print the token representing the negation of current token
|
||||||
hide_thisparam = 0x4000 ///< Do not print the 'this' parameter in argument lists
|
hide_thisparam = 0x4000, ///< Do not print the 'this' parameter in argument lists
|
||||||
|
pending_brace = 0x8000 ///< The current block may need to surround itself with additional braces
|
||||||
};
|
};
|
||||||
/// \brief Possible types of Atom
|
/// \brief Possible types of Atom
|
||||||
enum tagtype {
|
enum tagtype {
|
||||||
|
@ -282,7 +283,6 @@ protected:
|
||||||
int4 getPending(void) const { return pending; } ///< Get the number of pending nodes yet to be put on the RPN stack
|
int4 getPending(void) const { return pending; } ///< Get the number of pending nodes yet to be put on the RPN stack
|
||||||
void resetDefaultsInternal(void); ///< Reset options to default for PrintLanguage
|
void resetDefaultsInternal(void); ///< Reset options to default for PrintLanguage
|
||||||
|
|
||||||
|
|
||||||
/// \brief Print a single unicode character as a \e character \e constant for the high-level language
|
/// \brief Print a single unicode character as a \e character \e constant for the high-level language
|
||||||
///
|
///
|
||||||
/// For most languages, this prints the character surrounded by single quotes.
|
/// For most languages, this prints the character surrounded by single quotes.
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<decompilertest>
|
||||||
|
<binaryimage arch="x86:LE:64:default:gcc">
|
||||||
|
<!--
|
||||||
|
Contrived example testing various forms of nested if/else structures,
|
||||||
|
where the some should collapse to "else if" syntax and others should not.
|
||||||
|
-->
|
||||||
|
<bytechunk space="ram" offset="0x1006ca" readonly="true">
|
||||||
|
554889e54883
|
||||||
|
ec10897dfc8975f8837dfc0a75188b45
|
||||||
|
f889c6488d3d3a030000b800000000e8
|
||||||
|
9cfeffffeb17837dfc017511488d3d2a
|
||||||
|
030000b800000000e883feffff837df8
|
||||||
|
01751b8b45fc89c6488d3d05030000b8
|
||||||
|
00000000e867feffffe9bb000000837d
|
||||||
|
f80b751e8b45fc83c06489c6488d3de1
|
||||||
|
020000b800000000e843feffffe99700
|
||||||
|
0000837df815751b8b45fc6bc06489c6
|
||||||
|
488d3dbd020000b800000000e81ffeff
|
||||||
|
ffeb76837df81f751d8b55fc8b45f801
|
||||||
|
d089c6488d3d9a020000b800000000e8
|
||||||
|
fcfdffffeb53837df8f9751b8b45fc2b
|
||||||
|
45f889c6488d3d79020000b800000000
|
||||||
|
e8dbfdffffeb32837df800751b8b45fc
|
||||||
|
83e80189c6488d3d58020000b8000000
|
||||||
|
00e8bafdffffeb11488d3d53020000b8
|
||||||
|
00000000e8a7fdffff8b45fc3b45f875
|
||||||
|
1b8b45fc83e80289c6488d3d24020000
|
||||||
|
b800000000e886fdffffeb28837dfc25
|
||||||
|
7511488d3d1f020000b800000000e86d
|
||||||
|
fdffff488d3d18020000b800000000e8
|
||||||
|
5cfdffff8b45fc3b45f87d1b8b45fc83
|
||||||
|
e80389c6488d3dd9010000b800000000
|
||||||
|
e83bfdffffeb1e8b55fc8b45f801d083
|
||||||
|
f80a7511488d3ddd010000b800000000
|
||||||
|
e81bfdffff817df8c8000000751b8b45
|
||||||
|
fc83c06789c6488d3d97010000b80000
|
||||||
|
0000e8f9fcffffeb23817df8c9000000
|
||||||
|
751a817dfc2b0100007f11488d3d7b01
|
||||||
|
0000b800000000e8d4fcffff837df81b
|
||||||
|
751b8b45fc83c01b89c6488d3d530100
|
||||||
|
00b800000000e8b5fcffffeb5d837df8
|
||||||
|
1d7557eb2e488d3d64010000e88ffcff
|
||||||
|
ff837dfc64751b8b45f883c06f89c648
|
||||||
|
8d3d4e010000b800000000e880fcffff
|
||||||
|
eb1890837dfc677511488d3d3c010000
|
||||||
|
b800000000e866fcffff488d3d310100
|
||||||
|
00e84afcffff8345fc018b45fc3b45f8
|
||||||
|
7ca390c9c3
|
||||||
|
</bytechunk>
|
||||||
|
<bytechunk space="ram" offset="0x100a24" readonly="true">
|
||||||
|
426f64792025640a00456c73650046
|
||||||
|
696e616c004e6f7420717569746500
|
||||||
|
457874726100436f6d6d656e740054
|
||||||
|
6f7000426f6479202564004c616265
|
||||||
|
6c00426f74746f6d00
|
||||||
|
</bytechunk>
|
||||||
|
</binaryimage>
|
||||||
|
<script>
|
||||||
|
<com>map fun r0x1006ca testElseIf</com>
|
||||||
|
<com>map fun r0x100590 printf</com>
|
||||||
|
<com>parse line extern void testElseIf(int4 a,int4 b);</com>
|
||||||
|
<com>parse line extern void printf(char *,...);</com>
|
||||||
|
<com>map label mylabel r0x100913</com>
|
||||||
|
<com>lo fu testElseIf</com>
|
||||||
|
<com>comment instr r0x10085a Comment</com>
|
||||||
|
<com>decompile</com>
|
||||||
|
<com>print C</com>
|
||||||
|
<com>quit</com>
|
||||||
|
</script>
|
||||||
|
<stringmatch name="Else-if #1" min="1" max="1">else if \(a == 1\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #2" min="1" max="1">else if \(b == 0xb\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #3" min="1" max="1">else if \(b == 0x15\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #4" min="1" max="1">else if \(b == 0x1f\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #5" min="1" max="1">else if \(b == -7\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #6" min="1" max="1">else if \(b == 0\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #7" min="0" max="0">else if \(a == 0x25\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #8" min="1" max="1">if \(a == 0x25\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #9" min="0" max="0">else if \(b \+ a == 10\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #10" min="1" max="1">if \(b \+ a == 10\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #11" min="1" max="1">else if \(b == 0x1d\) goto</stringmatch>
|
||||||
|
<stringmatch name="Else-if #12" min="0" max="0">else if \(.* == 0x67\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #13" min="1" max="1">if \(.* == 0x67\)</stringmatch>
|
||||||
|
<stringmatch name="Else-if #14" min="1" max="1">else if \(\(b == 0xc9\) && \(a < 300\)\)</stringmatch>
|
||||||
|
</decompilertest>
|
Loading…
Add table
Add a link
Reference in a new issue