mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
New resetDefaults support
This commit is contained in:
parent
791f16101e
commit
d9bd93c36b
12 changed files with 147 additions and 50 deletions
|
@ -955,13 +955,26 @@ ActionDatabase::~ActionDatabase(void)
|
|||
delete (*iter).second;
|
||||
}
|
||||
|
||||
/// This provides the database with the single Action from which all other
|
||||
/// \e root Actions are derived. The Action has a reserved name "universal"
|
||||
/// \param act is the universal Action
|
||||
void ActionDatabase::registerUniversal(Action *act)
|
||||
/// Clear out (possibly altered) root Actions. Reset the default groups.
|
||||
/// Set the default root action "decompile"
|
||||
void ActionDatabase::resetDefaults(void)
|
||||
|
||||
{
|
||||
registerAction(universalname,act);
|
||||
Action *universalAction = (Action *)0;
|
||||
map<string,Action *>::iterator iter;
|
||||
iter = actionmap.find(universalname);
|
||||
if (iter != actionmap.end())
|
||||
universalAction = (*iter).second;
|
||||
for(iter = actionmap.begin();iter!=actionmap.end();++iter) {
|
||||
Action *curAction = (*iter).second;
|
||||
if (curAction != universalAction)
|
||||
delete curAction; // Clear out any old (modified) root actions
|
||||
}
|
||||
actionmap.clear();
|
||||
registerAction(universalname, universalAction);
|
||||
|
||||
buildDefaultGroups();
|
||||
setCurrent("decompile"); // The default root action
|
||||
}
|
||||
|
||||
const ActionGroupList &ActionDatabase::getGroup(const string &grp) const
|
||||
|
@ -1019,13 +1032,15 @@ Action *ActionDatabase::toggleAction(const string &grp, const string &basegrp,bo
|
|||
/// \param argv is a list of static char pointers, which must end with a NULL pointer, or a zero length string.
|
||||
void ActionDatabase::setGroup(const string &grp,const char **argv)
|
||||
|
||||
{ ActionGroupList &curgrp( groupmap[ grp ] );
|
||||
{
|
||||
ActionGroupList &curgrp( groupmap[ grp ] );
|
||||
curgrp.list.clear(); // Clear out any old members
|
||||
for(int4 i=0;;++i) {
|
||||
if (argv[i] == (char *)0) break;
|
||||
if (argv[i][0] == '\0') break;
|
||||
curgrp.list.insert( argv[i] );
|
||||
}
|
||||
isDefaultGroups = false;
|
||||
}
|
||||
|
||||
/// Copy an existing \e root Action by copying its grouplist, giving it a new name.
|
||||
|
@ -1038,6 +1053,7 @@ void ActionDatabase::cloneGroup(const string &oldname,const string &newname)
|
|||
{
|
||||
const ActionGroupList &curgrp(getGroup(oldname)); // Should already exist
|
||||
groupmap[ newname ] = curgrp; // Copy the group
|
||||
isDefaultGroups = false;
|
||||
}
|
||||
|
||||
/// Add a group to the grouplist for a particular \e root Action.
|
||||
|
@ -1046,7 +1062,9 @@ void ActionDatabase::cloneGroup(const string &oldname,const string &newname)
|
|||
/// \param basegroup is the group to add
|
||||
/// \return \b true for a new addition, \b false is the group was already present
|
||||
bool ActionDatabase::addToGroup(const string &grp, const string &basegroup)
|
||||
|
||||
{
|
||||
isDefaultGroups = false;
|
||||
ActionGroupList &curgrp( groupmap[ grp ] );
|
||||
return curgrp.list.insert( basegroup ).second;
|
||||
}
|
||||
|
@ -1057,7 +1075,9 @@ bool ActionDatabase::addToGroup(const string &grp, const string &basegroup)
|
|||
/// \param basegrp is the group to remove
|
||||
/// \return \b true if the group existed and was removed
|
||||
bool ActionDatabase::removeFromGroup(const string &grp, const string &basegrp)
|
||||
|
||||
{
|
||||
isDefaultGroups = false;
|
||||
ActionGroupList &curgrp( groupmap[ grp ] );
|
||||
return (curgrp.list.erase(basegrp) > 0);
|
||||
}
|
||||
|
|
|
@ -296,14 +296,16 @@ class ActionDatabase {
|
|||
string currentactname; ///< The name associated with the current root Action
|
||||
map<string,ActionGroupList> groupmap; ///< Map from root Action name to the grouplist it uses
|
||||
map<string,Action *> actionmap; ///< Map from name to root Action
|
||||
bool isDefaultGroups; ///< \b true if only the default groups are set
|
||||
static const char universalname[]; ///< The name of the \e universal root Action
|
||||
void registerAction(const string &nm,Action *act); ///< Register a \e root Action
|
||||
void buildDefaultGroups(void); ///< Set up descriptions of preconfigured root Actions
|
||||
Action *getAction(const string &nm) const; ///< Look up a \e root Action by name
|
||||
Action *deriveAction(const string &baseaction,const string &grp); ///< Derive a \e root Action
|
||||
public:
|
||||
ActionDatabase(void) { currentact = (Action *)0; } ///< Constructor
|
||||
ActionDatabase(void) { currentact = (Action *)0; isDefaultGroups = false; } ///< Constructor
|
||||
~ActionDatabase(void); ///< Destructor
|
||||
void registerUniversal(Action *act); ///< Register the \e universal root Action
|
||||
void resetDefaults(void); ///< (Re)set the default configuration
|
||||
Action *getCurrent(void) const { return currentact; } ///< Get the current \e root Action
|
||||
const string &getCurrentName(void) const { return currentactname; } ///< Get the name of the current \e root Action
|
||||
const ActionGroupList &getGroup(const string &grp) const; ///< Get a specific grouplist by name
|
||||
|
@ -314,6 +316,7 @@ public:
|
|||
void cloneGroup(const string &oldname,const string &newname); ///< Clone a \e root Action
|
||||
bool addToGroup(const string &grp,const string &basegroup); ///< Add a group to a \e root Action
|
||||
bool removeFromGroup(const string &grp,const string &basegroup); ///< Remove a group from a \e root Action
|
||||
void universalAction(Architecture *glb); ///< Build the universal action
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -86,17 +86,10 @@ Architecture::Architecture(void)
|
|||
|
||||
{
|
||||
// endian = -1;
|
||||
trim_recurse_max = 5; // Reasonable default value
|
||||
max_implied_ref = 2; // 2 is best, in specific cases a higher number might be good
|
||||
max_term_duplication = 2; // 2 and 3 (4) are pretty reasonable
|
||||
max_basetype_size = 10; // Needs to be 8 or bigger
|
||||
resetDefaultsInternal();
|
||||
min_funcsymbol_size = 1;
|
||||
aggressive_ext_trim = false;
|
||||
readonlypropagate = false;
|
||||
infer_pointers = true;
|
||||
funcptr_align = 0;
|
||||
flowoptions = 0;
|
||||
alias_block_level = 2; // Block structs and arrays by default
|
||||
defaultfp = (ProtoModel *)0;
|
||||
defaultReturnAddr.space = (AddrSpace *)0;
|
||||
evalfp_current = (ProtoModel *)0;
|
||||
|
@ -508,8 +501,8 @@ void Architecture::buildAction(DocumentStorage &store)
|
|||
|
||||
{
|
||||
parseExtraRules(store); // Look for any additional rules
|
||||
universal_action(this);
|
||||
allacts.setCurrent("decompile");
|
||||
allacts.universalAction(this);
|
||||
allacts.resetDefaults();
|
||||
}
|
||||
|
||||
/// This builds the database which holds the status registers setings and other
|
||||
|
@ -1253,6 +1246,30 @@ void Architecture::init(DocumentStorage &store)
|
|||
fillinReadOnlyFromLoader();
|
||||
}
|
||||
|
||||
void Architecture::resetDefaultsInternal(void)
|
||||
|
||||
{
|
||||
trim_recurse_max = 5;
|
||||
max_implied_ref = 2; // 2 is best, in specific cases a higher number might be good
|
||||
max_term_duplication = 2; // 2 and 3 (4) are reasonable
|
||||
max_basetype_size = 10; // Needs to be 8 or bigger
|
||||
flowoptions = 0;
|
||||
infer_pointers = true;
|
||||
readonlypropagate = false;
|
||||
alias_block_level = 2; // Block structs and arrays by default
|
||||
}
|
||||
|
||||
/// Reset options that can be modified by the OptionDatabase. This includes
|
||||
/// options specific to this class and options under PrintLanguage and ActionDatabase
|
||||
void Architecture::resetDefaults(void)
|
||||
|
||||
{
|
||||
resetDefaultsInternal();
|
||||
allacts.resetDefaults();
|
||||
for(int4 i=0;i<printlist.size();++i)
|
||||
printlist[i]->resetDefaults();
|
||||
}
|
||||
|
||||
Address SegmentedResolver::resolve(uintb val,int4 sz,const Address &point,uintb &fullEncoding)
|
||||
|
||||
{
|
||||
|
|
|
@ -164,6 +164,8 @@ public:
|
|||
#endif
|
||||
Architecture(void); ///< Construct an uninitialized Architecture
|
||||
void init(DocumentStorage &store); ///< Load the image and configure architecture
|
||||
void resetDefaultsInternal(void); ///< Reset default values for options specific to Architecture
|
||||
void resetDefaults(void); ///< Reset defaults values for options owned by \b this
|
||||
ProtoModel *getModel(const string &nm) const; ///< Get a specific PrototypeModel
|
||||
bool hasModel(const string &nm) const; ///< Does this Architecture have a specific PrototypeModel
|
||||
bool highPtrPossible(const Address &loc,int4 size) const; ///< Are pointers possible to the given location?
|
||||
|
|
|
@ -4703,11 +4703,12 @@ void TermOrder::sortTerms(void)
|
|||
sort(sorter.begin(),sorter.end(),additiveCompare);
|
||||
}
|
||||
|
||||
/// Build the default \e root Actions: decompile, jumptable, normalize, paramid, register, firstpass
|
||||
/// \param allacts is the database that will hold the \e root Actions
|
||||
void build_defaultactions(ActionDatabase &allacts)
|
||||
/// (Re)build the default \e root Actions: decompile, jumptable, normalize, paramid, register, firstpass
|
||||
void ActionDatabase::buildDefaultGroups(void)
|
||||
|
||||
{
|
||||
if (isDefaultGroups) return;
|
||||
groupmap.clear();
|
||||
const char *members[] = { "base", "protorecovery", "protorecovery_a", "deindirect", "localrecovery",
|
||||
"deadcode", "typerecovery", "stackptrflow",
|
||||
"blockrecovery", "stackvars", "deadcontrolflow", "switchnorm",
|
||||
|
@ -4716,36 +4717,37 @@ void build_defaultactions(ActionDatabase &allacts)
|
|||
"segment", "returnsplit", "nodejoin", "doubleload", "doubleprecis",
|
||||
"unreachable", "subvar", "floatprecision",
|
||||
"conditionalexe", "" };
|
||||
allacts.setGroup("decompile",members);
|
||||
setGroup("decompile",members);
|
||||
|
||||
const char *jumptab[] = { "base", "noproto", "localrecovery", "deadcode", "stackptrflow",
|
||||
"stackvars", "analysis", "segment", "subvar", "conditionalexe", "" };
|
||||
allacts.setGroup("jumptable",jumptab);
|
||||
setGroup("jumptable",jumptab);
|
||||
|
||||
const char *normali[] = { "base", "protorecovery", "protorecovery_b", "deindirect", "localrecovery",
|
||||
"deadcode", "stackptrflow", "normalanalysis",
|
||||
"stackvars", "deadcontrolflow", "analysis", "fixateproto", "nodejoin",
|
||||
"unreachable", "subvar", "floatprecision", "normalizebranches",
|
||||
"conditionalexe", "" };
|
||||
allacts.setGroup("normalize",normali);
|
||||
setGroup("normalize",normali);
|
||||
|
||||
const char *paramid[] = { "base", "protorecovery", "protorecovery_b", "deindirect", "localrecovery",
|
||||
"deadcode", "typerecovery", "stackptrflow", "siganalysis",
|
||||
"stackvars", "deadcontrolflow", "analysis", "fixateproto",
|
||||
"unreachable", "subvar", "floatprecision",
|
||||
"conditionalexe", "" };
|
||||
allacts.setGroup("paramid",paramid);
|
||||
setGroup("paramid",paramid);
|
||||
|
||||
const char *regmemb[] = { "base", "analysis", "subvar", "" };
|
||||
allacts.setGroup("register",regmemb);
|
||||
setGroup("register",regmemb);
|
||||
|
||||
const char *firstmem[] = { "base", "" };
|
||||
allacts.setGroup("firstpass",firstmem);
|
||||
setGroup("firstpass",firstmem);
|
||||
isDefaultGroups = true;
|
||||
}
|
||||
|
||||
/// Construct the \b universal Action that contains all possible components
|
||||
/// \param conf is the Architecture that will use the Action
|
||||
void universal_action(Architecture *conf)
|
||||
void ActionDatabase::universalAction(Architecture *conf)
|
||||
|
||||
{
|
||||
vector<Rule *>::iterator iter;
|
||||
|
@ -4757,9 +4759,8 @@ void universal_action(Architecture *conf)
|
|||
ActionGroup *actstackstall;
|
||||
AddrSpace *stackspace = conf->getStackSpace();
|
||||
|
||||
build_defaultactions(conf->allacts);
|
||||
act = new ActionRestartGroup(Action::rule_onceperfunc,"universal",1);
|
||||
conf->allacts.registerUniversal(act);
|
||||
registerAction(universalname,act);
|
||||
|
||||
act->addAction( new ActionStart("base"));
|
||||
act->addAction( new ActionConstbase("base"));
|
||||
|
|
|
@ -433,6 +433,7 @@ void SetOptions::rawAction(void)
|
|||
{
|
||||
res = false;
|
||||
|
||||
ghidra->resetDefaults();
|
||||
ghidra->options->restoreXml(doc->getRoot());
|
||||
delete doc;
|
||||
doc = (Document *)0;
|
||||
|
|
|
@ -344,6 +344,12 @@ void EmitXml::spaces(int4 num,int4 bump)
|
|||
}
|
||||
}
|
||||
|
||||
void EmitXml::resetDefaults(void)
|
||||
|
||||
{
|
||||
resetDefaultsInternal();
|
||||
}
|
||||
|
||||
int4 TokenSplit::countbase = 0;
|
||||
|
||||
/// Emit markup or content corresponding to \b this token on a low-level emitter.
|
||||
|
@ -536,15 +542,15 @@ void TokenSplit::printDebug(ostream &s) const
|
|||
}
|
||||
#endif
|
||||
|
||||
EmitPrettyPrint::EmitPrettyPrint(int4 mls)
|
||||
: EmitXml(), scanqueue( 3*mls ), tokqueue( 3*mls )
|
||||
EmitPrettyPrint::EmitPrettyPrint(void)
|
||||
: EmitXml(), scanqueue( 3*100 ), tokqueue( 3*100 )
|
||||
|
||||
{
|
||||
lowlevel = new EmitNoXml(); // Do not emit xml by default
|
||||
maxlinesize = mls;
|
||||
spaceremain = maxlinesize;
|
||||
needbreak = false;
|
||||
commentmode = false;
|
||||
resetDefaultsPrettyPrint();
|
||||
}
|
||||
|
||||
EmitPrettyPrint::~EmitPrettyPrint(void)
|
||||
|
@ -1213,3 +1219,11 @@ void EmitPrettyPrint::setMaxLineSize(int4 val)
|
|||
spaceremain = maxlinesize;
|
||||
clear();
|
||||
}
|
||||
|
||||
void EmitPrettyPrint::resetDefaults(void)
|
||||
|
||||
{
|
||||
lowlevel->resetDefaults();
|
||||
resetDefaultsInternal();
|
||||
resetDefaultsPrettyPrint();
|
||||
}
|
||||
|
|
|
@ -80,8 +80,9 @@ protected:
|
|||
int4 indentlevel; ///< Current indent level (in fixed width characters)
|
||||
int4 parenlevel; ///< Current depth of parentheses
|
||||
int4 indentincrement; ///< Change in indentlevel per level of nesting
|
||||
void resetDefaultsInternal(void) { indentincrement = 2; } ///< Set options to default values for EmitXml
|
||||
public:
|
||||
EmitXml(void) { s = (ostream *)0; indentlevel=0; parenlevel=0; indentincrement=2; } ///< Constructor
|
||||
EmitXml(void) { s = (ostream *)0; indentlevel=0; parenlevel=0; resetDefaultsInternal(); } ///< Constructor
|
||||
|
||||
/// \brief Possible types of syntax highlighting
|
||||
enum syntax_highlight {
|
||||
|
@ -196,6 +197,9 @@ public:
|
|||
/// \return \b true if \b this produces an XML markup of its emitted source code
|
||||
virtual bool emitsXml(void) const { return true; }
|
||||
|
||||
/// \brief (Re)set the default emitting options
|
||||
virtual void resetDefaults(void);
|
||||
|
||||
/// \brief Get the current parentheses depth
|
||||
///
|
||||
/// \return the current number of open parenthetical groups
|
||||
|
@ -649,9 +653,11 @@ template<typename _type>
|
|||
void circularqueue<_type>::setMax(int4 sz)
|
||||
|
||||
{
|
||||
delete [] cache;
|
||||
max = sz;
|
||||
cache = new _type [ sz ];
|
||||
if (max != sz) {
|
||||
delete [] cache;
|
||||
max = sz;
|
||||
cache = new _type [ sz ];
|
||||
}
|
||||
left = 1; // This operation empties queue
|
||||
right = 0;
|
||||
}
|
||||
|
@ -721,8 +727,9 @@ class EmitPrettyPrint : public EmitXml {
|
|||
void print(const TokenSplit &tok); ///< Output the given token to the low-level emitter
|
||||
void advanceleft(void); ///< Emit tokens that have been fully committed
|
||||
void scan(void); ///< Process a new token
|
||||
void resetDefaultsPrettyPrint(void) { setMaxLineSize(100); }
|
||||
public:
|
||||
EmitPrettyPrint(int4 mls); ///< Construct with an initial maximum line size
|
||||
EmitPrettyPrint(void); ///< Construct with an initial maximum line size
|
||||
virtual ~EmitPrettyPrint(void);
|
||||
virtual int4 beginDocument(void);
|
||||
virtual void endDocument(int4 id);
|
||||
|
@ -768,6 +775,7 @@ public:
|
|||
virtual int4 getMaxLineSize(void) const { return maxlinesize; }
|
||||
virtual void setCommentFill(const string &fill) { commentfill = fill; }
|
||||
virtual bool emitsXml(void) const { return lowlevel->emitsXml(); }
|
||||
virtual void resetDefaults(void);
|
||||
void setXML(bool val); ///< Toggle whether the low-level emitter emits XML markup or not
|
||||
};
|
||||
|
||||
|
|
|
@ -94,12 +94,6 @@ PrintLanguage *PrintCCapability::buildLanguage(Architecture *glb)
|
|||
PrintC::PrintC(Architecture *g,const string &nm) : PrintLanguage(g,nm)
|
||||
|
||||
{
|
||||
option_NULL = false;
|
||||
option_inplace_ops = false;
|
||||
option_convention = true;
|
||||
option_nocasts = false;
|
||||
option_unplaced = false;
|
||||
option_hide_exts = true;
|
||||
nullToken = "NULL";
|
||||
|
||||
// Set the flip tokens
|
||||
|
@ -111,7 +105,7 @@ PrintC::PrintC(Architecture *g,const string &nm) : PrintLanguage(g,nm)
|
|||
not_equal.negate = &equal;
|
||||
|
||||
castStrategy = new CastStrategyC();
|
||||
setCStyleComments();
|
||||
resetDefaultsPrintC();
|
||||
}
|
||||
|
||||
/// Push nested components of a data-type declaration onto a stack, so we can access it bottom up
|
||||
|
@ -1282,6 +1276,18 @@ bool PrintC::printCharacterConstant(ostream &s,const Address &addr,int4 charsize
|
|||
return res;
|
||||
}
|
||||
|
||||
void PrintC::resetDefaultsPrintC(void)
|
||||
|
||||
{
|
||||
option_convention = true;
|
||||
option_hide_exts = true;
|
||||
option_inplace_ops = false;
|
||||
option_nocasts = false;
|
||||
option_NULL = false;
|
||||
option_unplaced = false;
|
||||
setCStyleComments();
|
||||
}
|
||||
|
||||
/// \brief Push a single character constant to the RPN stack
|
||||
///
|
||||
/// For C, a character constant is usually emitted as the character in single quotes.
|
||||
|
@ -1931,6 +1937,13 @@ void PrintC::emitGotoStatement(const FlowBlock *bl,const FlowBlock *exp_bl,
|
|||
emit->endStatement(id);
|
||||
}
|
||||
|
||||
void PrintC::resetDefaults(void)
|
||||
|
||||
{
|
||||
PrintLanguage::resetDefaults();
|
||||
resetDefaultsPrintC();
|
||||
}
|
||||
|
||||
void PrintC::adjustTypeOperators(void)
|
||||
|
||||
{
|
||||
|
|
|
@ -159,6 +159,7 @@ protected:
|
|||
void opHiddenFunc(const PcodeOp *op); ///< Push the given p-code op as a hidden token
|
||||
static bool hasCharTerminator(uint1 *buffer,int4 size,int4 charsize);
|
||||
bool printCharacterConstant(ostream &s,const Address &addr,int4 charsize) const;
|
||||
void resetDefaultsPrintC(void); ///< Set default values for options specific to PrintC
|
||||
virtual void pushConstant(uintb val,const Datatype *ct,
|
||||
const Varnode *vn,const PcodeOp *op);
|
||||
virtual bool pushEquate(uintb val,int4 sz,const EquateSymbol *sym,
|
||||
|
@ -200,6 +201,7 @@ public:
|
|||
void setDisplayUnplaced(bool val) { option_unplaced = val; } ///< Toggle whether \e unplaced comments are displayed in the header
|
||||
void setHideImpliedExts(bool val) { option_hide_exts = val; } ///< Toggle whether implied extensions are hidden
|
||||
virtual ~PrintC(void) {}
|
||||
virtual void resetDefaults(void);
|
||||
virtual void adjustTypeOperators(void);
|
||||
virtual void setCommentStyle(const string &nm);
|
||||
virtual bool isCharacterConstant(const uint1 *buf,int4 size,int4 charsize) const;
|
||||
|
|
|
@ -61,13 +61,10 @@ PrintLanguage::PrintLanguage(Architecture *g,const string &nm)
|
|||
castStrategy = (CastStrategy *)0;
|
||||
name = nm;
|
||||
curscope = (Scope *)0;
|
||||
emit = new EmitPrettyPrint(100);
|
||||
emit = new EmitPrettyPrint();
|
||||
|
||||
mods = 0;
|
||||
pending = 0;
|
||||
line_commentindent = 20;
|
||||
instr_comment_type = Comment::user2 | Comment::warning;
|
||||
head_comment_type = Comment::header | Comment::warningheader;
|
||||
resetDefaultsInternal();
|
||||
}
|
||||
|
||||
PrintLanguage::~PrintLanguage(void)
|
||||
|
@ -692,6 +689,15 @@ void PrintLanguage::opUnary(const OpToken *tok,const PcodeOp *op)
|
|||
pushVnImplied(op->getIn(0),op,mods);
|
||||
}
|
||||
|
||||
void PrintLanguage::resetDefaultsInternal(void)
|
||||
|
||||
{
|
||||
mods = 0;
|
||||
head_comment_type = Comment::header | Comment::warningheader;
|
||||
line_commentindent = 20;
|
||||
instr_comment_type = Comment::user2 | Comment::warning;
|
||||
}
|
||||
|
||||
/// The comment will get emitted as a single line using the high-level language's
|
||||
/// delimiters with the given indent level
|
||||
/// \param indent is the number of characters to indent
|
||||
|
@ -767,6 +773,13 @@ void PrintLanguage::setFlat(bool val)
|
|||
mods &= ~flat;
|
||||
}
|
||||
|
||||
void PrintLanguage::resetDefaults(void)
|
||||
|
||||
{
|
||||
emit->resetDefaults();
|
||||
resetDefaultsInternal();
|
||||
}
|
||||
|
||||
void PrintLanguage::clear(void)
|
||||
|
||||
{
|
||||
|
|
|
@ -275,6 +275,8 @@ protected:
|
|||
void opBinary(const OpToken *tok,const PcodeOp *op); ///< Push a binary operator onto the RPN stack
|
||||
void opUnary(const OpToken *tok,const PcodeOp *op); ///< Push a unary operator onto 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
|
||||
|
||||
|
||||
/// \brief Print a single unicode character as a \e character \e constant for the high-level language
|
||||
///
|
||||
|
@ -421,6 +423,7 @@ public:
|
|||
void setFlat(bool val); ///< Set whether nesting code structure should be emitted
|
||||
|
||||
virtual void adjustTypeOperators(void)=0; ///< Set basic data-type information for p-code operators
|
||||
virtual void resetDefaults(void); ///< Set printing options to their default value
|
||||
virtual void clear(void); ///< Clear the RPN stack and the low-level emitter
|
||||
virtual void setIntegerFormat(const string &nm); ///< Set the default integer format
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue