544 lines
21 KiB
C++
544 lines
21 KiB
C++
/*
|
|
* Interactive disassembler (IDA).
|
|
* Copyright (c) 1990-2021 Hex-Rays
|
|
* ALL RIGHTS RESERVED.
|
|
*
|
|
*/
|
|
|
|
#ifndef _CONFIG_HPP
|
|
#define _CONFIG_HPP
|
|
|
|
//-----------------------------------------------------------------------
|
|
/// \defgroup IDPOPT_T Option value types
|
|
/// Passed as 'value_type' parameter to ::set_options_t callbacks
|
|
//@{
|
|
#define IDPOPT_STR 1 ///< string constant (char *)
|
|
#define IDPOPT_NUM 2 ///< number (uval_t *)
|
|
#define IDPOPT_BIT 3 ///< bit, yes/no (int *)
|
|
#define IDPOPT_I64 5 ///< 64bit number (int64 *)
|
|
#define IDPOPT_CST 6 ///< lexer (lexer_t*)
|
|
///< Custom type, starting with a '{'
|
|
///< Values of this type should be handled by
|
|
///< ::set_options_t callbacks. E.g.,:
|
|
///< \code
|
|
///< ERROR_STRINGS =
|
|
///< {
|
|
///< {0, "Unknown error"},
|
|
///< {1, "Missing filename"},
|
|
///< {5, "Out-of-memory"}
|
|
///< }
|
|
///< \endcode
|
|
///< For values of this type, the data that will
|
|
///< be passed as the callback's 'value' parameter
|
|
///< is the lexer instance that is being used
|
|
///< to parse the configuration file.
|
|
///< You can use \ref parse_json() (see parsejson.hpp)
|
|
///< to parse JSON-format data
|
|
///< NB: the '{' is already consumed by the parser,
|
|
///< so you need to push it again if it's a part of the JSON object
|
|
//@}
|
|
|
|
/// \defgroup IDPOPT_RET Option result codes
|
|
/// Predefined return values for ::set_options_t callbacks
|
|
//@{
|
|
#define IDPOPT_OK NULL ///< ok
|
|
#define IDPOPT_BADKEY ((char*)1) ///< illegal keyword
|
|
#define IDPOPT_BADTYPE ((char*)2) ///< illegal type of value
|
|
#define IDPOPT_BADVALUE ((char*)3) ///< illegal value (bad range, for example)
|
|
//@}
|
|
|
|
|
|
/// Callback - called when a config directive is processed in IDA.
|
|
/// Also see read_config_file() and processor_t::set_idp_options
|
|
/// \param keyword keyword encountered in IDA.CFG/user config file.
|
|
/// if NULL, then an interactive dialog form should be displayed
|
|
/// \param value_type type of value of the keyword - one of \ref IDPOPT_T
|
|
/// \param value pointer to value
|
|
/// \param idb_loaded true if the ev_oldfile/ev_newfile events have been generated?
|
|
/// \return one of \ref IDPOPT_RET, otherwise a pointer to an error message
|
|
|
|
typedef const char *(idaapi set_options_t)(
|
|
const char *keyword,
|
|
int value_type,
|
|
const void *value,
|
|
bool idb_loaded);
|
|
|
|
/// \defgroup IDAOPT_PRIO Option priority
|
|
/// Specifies the priority of a configuration option. Since options may
|
|
/// be specified in different way, and applied in various orders, we need
|
|
/// option priorities.
|
|
/// Normally the default priority option does not overwrite the existing value
|
|
/// whereas the high priority one does.
|
|
/// High priority options may be stored in the database to be available
|
|
/// in the next session.
|
|
//@{
|
|
#define IDPOPT_PRI_DEFAULT 1 ///< default priority - taken from config file
|
|
#define IDPOPT_PRI_HIGH 2 ///< high priority - received from UI or a script function
|
|
//@}
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
/// Parse the value type for the value token 'value'.
|
|
/// This is mostly used for converting from values that a cfgopt_handler_t
|
|
/// receives, into data that callbacks
|
|
/// - processor_t::set_idp_options
|
|
/// - debugger_t::set_dbg_options
|
|
/// expect.
|
|
///
|
|
/// Plugins that wish to use options shouldn't rely on this,
|
|
/// and use the cfgopt_t utility instead.
|
|
///
|
|
/// \param out parsed data
|
|
/// \param lx the lexer in use
|
|
/// \param value the value token
|
|
/// \return true if guessing didn't lead to an error, false otherwise.
|
|
/// note that even if 'true' is returned, it doesn't mean the
|
|
/// type could be guessed: merely that no syntax error occurred.
|
|
class lexer_t;
|
|
struct token_t;
|
|
idaman bool ida_export parse_config_value(
|
|
idc_value_t *out,
|
|
lexer_t *lx,
|
|
const token_t &value);
|
|
|
|
//-------------------------------------------------------------------------
|
|
typedef const char *(idaapi cfgopt_handler_t)(
|
|
lexer_t *lx,
|
|
const token_t &keyword,
|
|
const token_t &value);
|
|
|
|
//-------------------------------------------------------------------------
|
|
typedef const char *(idaapi cfgopt_handler2_t)(
|
|
lexer_t *lx,
|
|
const token_t &keyword,
|
|
const token_t &value,
|
|
int64 param1,
|
|
int64 param2);
|
|
|
|
//-------------------------------------------------------------------------
|
|
typedef const char *(idaapi cfgopt_handler3_t)(
|
|
lexer_t *lx,
|
|
const token_t &keyword,
|
|
const token_t &value,
|
|
int64 param1,
|
|
int64 param2,
|
|
void *obj);
|
|
|
|
//-----------------------------------------------------------------------
|
|
/// used by cfgopt_t. You shouldn't have to deal with those directly.
|
|
#define IDPOPT_NUM_INT (0)
|
|
#define IDPOPT_NUM_CHAR (1 << 24)
|
|
#define IDPOPT_NUM_SHORT (2 << 24)
|
|
#define IDPOPT_NUM_RANGE (1 << 26)
|
|
#define IDPOPT_NUM_UNS (1 << 27)
|
|
|
|
#define IDPOPT_BIT_UINT 0
|
|
#define IDPOPT_BIT_UCHAR (1 << 24)
|
|
#define IDPOPT_BIT_USHORT (2 << 24)
|
|
#define IDPOPT_BIT_BOOL (3 << 24)
|
|
|
|
#define IDPOPT_STR_QSTRING (1 << 24)
|
|
#define IDPOPT_STR_LONG (1 << 25)
|
|
|
|
#define IDPOPT_I64_RANGES (1 << 24)
|
|
#define IDPOPT_I64_UNS (1 << 25)
|
|
|
|
#define IDPOPT_CST_PARAMS (1 << 24)
|
|
|
|
#define IDPOPT_MBROFF (1 << 18)
|
|
|
|
//-------------------------------------------------------------------------
|
|
struct cfgopt_t;
|
|
idaman const char *ida_export cfgopt_t__apply(
|
|
const cfgopt_t *_this,
|
|
int vtype,
|
|
const void *vdata);
|
|
idaman const char *ida_export cfgopt_t__apply2(
|
|
const cfgopt_t *_this,
|
|
int vtype,
|
|
const void *vdata,
|
|
void *obj);
|
|
|
|
//-------------------------------------------------------------------------
|
|
// cfgopt_t objects are suitable for being statically initialized, and
|
|
// passed to 'read_config_file'.
|
|
//
|
|
// E.g.,
|
|
// ---
|
|
// static const cfgopt_t g_opts[] =
|
|
// {
|
|
// cfgopt_t("AUTO_UNDEFINE", &auto_undefine, -1, 1),
|
|
// cfgopt_t("NOVICE", &novice, true),
|
|
// cfgopt_t("EDITOR", editor_buf, sizeof(editor_buf)),
|
|
// cfgopt_t("SCREEN_PALETTE", set_screen_palette), // specific handler for SCREEN_PALETTE
|
|
// };
|
|
//
|
|
// ...
|
|
//
|
|
// read_config_file("myfile", g_opts, qnumber(g_opts), other_handler)
|
|
// ---
|
|
//
|
|
// NOTES:
|
|
// * so-called 'long' strings (the default) can span on multiple lines,
|
|
// and are terminated by a ';'
|
|
struct cfgopt_t
|
|
{
|
|
const char *name;
|
|
union
|
|
{
|
|
void *ptr;
|
|
size_t mbroff; // offset of a structure member
|
|
cfgopt_handler_t *hnd; // to avoid reinterpret_cast and gcc's error:
|
|
cfgopt_handler2_t *hnd2; // "a reinterpret_cast is not a constant expression"
|
|
cfgopt_handler3_t *hnd3; //
|
|
};
|
|
int flags;
|
|
struct num_range_t
|
|
{
|
|
constexpr num_range_t(int64 _min, int64 _max) : minval(_min), maxval(_max) {}
|
|
int64 minval;
|
|
int64 maxval;
|
|
};
|
|
struct params_t
|
|
{
|
|
constexpr params_t(int64 _p1, int64 _p2) : p1(_p1), p2(_p2) {}
|
|
int64 p1;
|
|
int64 p2;
|
|
};
|
|
union
|
|
{
|
|
size_t buf_size;
|
|
num_range_t num_range;
|
|
uint32 bit_flags;
|
|
params_t params;
|
|
void *mbroff_obj;
|
|
};
|
|
|
|
// IDPOPT_STR
|
|
constexpr cfgopt_t(const char *_n, char *_p, size_t _sz, bool _long = true)
|
|
: name(_n), ptr(_p), flags(IDPOPT_STR | (_long ? IDPOPT_STR_LONG : 0)), buf_size(_sz)
|
|
{}
|
|
constexpr cfgopt_t(const char *_n, qstring *_p, bool _long = true)
|
|
: name(_n), ptr(_p), flags(IDPOPT_STR | IDPOPT_STR_QSTRING | (_long ? IDPOPT_STR_LONG : 0)), buf_size(0)
|
|
{}
|
|
|
|
// IDPOPT_NUM
|
|
constexpr cfgopt_t(const char *_n, int *_p)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM), buf_size(0) {}
|
|
constexpr cfgopt_t(const char *_n, uint *_p)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_UNS), buf_size(0) {}
|
|
constexpr cfgopt_t(const char *_n, char *_p)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_CHAR), buf_size(0) {}
|
|
constexpr cfgopt_t(const char *_n, uchar *_p)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_UNS | IDPOPT_NUM_CHAR), buf_size(0) {}
|
|
constexpr cfgopt_t(const char *_n, short *_p)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_SHORT), buf_size(0) {}
|
|
constexpr cfgopt_t(const char *_n, ushort *_p)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_UNS | IDPOPT_NUM_SHORT), buf_size(0) {}
|
|
// IDPOPT_NUM + ranges
|
|
constexpr cfgopt_t(const char *_n, int *_p, int _min, int _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_RANGE), num_range(_min, _max) {}
|
|
constexpr cfgopt_t(const char *_n, uint *_p, uint _min, uint _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_UNS | IDPOPT_NUM_RANGE), num_range(_min, _max) {}
|
|
constexpr cfgopt_t(const char *_n, char *_p, char _min, char _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_CHAR | IDPOPT_NUM_RANGE), num_range(_min, _max) {}
|
|
constexpr cfgopt_t(const char *_n, uchar *_p, uchar _min, uchar _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_UNS | IDPOPT_NUM_CHAR | IDPOPT_NUM_RANGE), num_range(_min, _max) {}
|
|
constexpr cfgopt_t(const char *_n, short *_p, short _min, short _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_RANGE | IDPOPT_NUM_SHORT), num_range(_min, _max) {}
|
|
constexpr cfgopt_t(const char *_n, ushort *_p, ushort _min, ushort _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_NUM | IDPOPT_NUM_UNS | IDPOPT_NUM_RANGE | IDPOPT_NUM_SHORT), num_range(_min, _max) {}
|
|
|
|
// IDPOPT_BIT
|
|
constexpr cfgopt_t(const char *_n, bool *_p, bool _flags) : name(_n), ptr(_p), flags(IDPOPT_BIT | IDPOPT_BIT_BOOL), bit_flags(_flags) {}
|
|
constexpr cfgopt_t(const char *_n, uchar *_p, uchar _flags) : name(_n), ptr(_p), flags(IDPOPT_BIT | IDPOPT_BIT_UCHAR), bit_flags(_flags) {}
|
|
constexpr cfgopt_t(const char *_n, ushort *_p, ushort _flags) : name(_n), ptr(_p), flags(IDPOPT_BIT | IDPOPT_BIT_USHORT), bit_flags(_flags) {}
|
|
constexpr cfgopt_t(const char *_n, uint32 *_p, uint32 _flags) : name(_n), ptr(_p), flags(IDPOPT_BIT), bit_flags(_flags) {}
|
|
|
|
// IDPOPT_I64
|
|
constexpr cfgopt_t(const char *_n, int64 *_p) : name(_n), ptr(_p), flags(IDPOPT_I64), buf_size(0) {}
|
|
constexpr cfgopt_t(const char *_n, uint64 *_p) : name(_n), ptr(_p), flags(IDPOPT_I64 | IDPOPT_NUM_UNS), buf_size(0) {}
|
|
// IDPOPT_I64 + ranges
|
|
constexpr cfgopt_t(const char *_n, int64 *_p, int64 _min, int64 _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_I64 | IDPOPT_I64_RANGES), num_range(_min, _max) {}
|
|
constexpr cfgopt_t(const char *_n, uint64 *_p, uint64 _min, uint64 _max)
|
|
: name(_n), ptr(_p), flags(IDPOPT_I64 | IDPOPT_I64_UNS | IDPOPT_I64_RANGES), num_range(int64(_min), int64(_max)) {}
|
|
|
|
// IDPOPT_CST
|
|
constexpr cfgopt_t(const char *_n, cfgopt_handler_t *_p)
|
|
: name(_n), hnd(_p), flags(IDPOPT_CST), buf_size(0) {}
|
|
// IDPOPT_CST + params
|
|
constexpr cfgopt_t(const char *_n, cfgopt_handler2_t *_p, int64 _p1=0, int64 _p2=0)
|
|
: name(_n), hnd2(_p), flags(IDPOPT_CST | IDPOPT_CST_PARAMS), params(_p1, _p2) {}
|
|
|
|
// configuration option based on the offset of a structure member
|
|
|
|
// IDPOPT_STR
|
|
template<class T>
|
|
constexpr cfgopt_t(const char *_n, qstring T:: *, size_t _mbroff, bool _long = true)
|
|
: name(_n),
|
|
mbroff(_mbroff),
|
|
flags(IDPOPT_MBROFF | IDPOPT_STR | IDPOPT_STR_QSTRING | (_long ? IDPOPT_STR_LONG : 0)),
|
|
buf_size(0)
|
|
{}
|
|
#define CFGOPT_QS(nm, cfgt, cfgm, _long) \
|
|
cfgopt_t(nm, &cfgt::cfgm, qoffsetof(cfgt, cfgm), _long)
|
|
|
|
#define CFGOPT_INNER_QS(nm, cfgt, cfgm, mt, mf, _long) \
|
|
cfgopt_t(nm, &mt::mf, qoffsetof(cfgt, cfgm) + qoffsetof(mt, mf), _long)
|
|
|
|
|
|
// IDPOPT_NUM
|
|
#define CTR_CFGOPT(ctrtype, ctrflags) \
|
|
template<class T> \
|
|
constexpr cfgopt_t(const char *_n, ctrtype T:: *, size_t _mbroff) \
|
|
: name(_n), \
|
|
mbroff(_mbroff), \
|
|
flags(IDPOPT_MBROFF|IDPOPT_NUM|ctrflags), \
|
|
buf_size(0) \
|
|
{}
|
|
CTR_CFGOPT(int, 0)
|
|
CTR_CFGOPT(uint, IDPOPT_NUM_UNS)
|
|
CTR_CFGOPT(char, IDPOPT_NUM_CHAR)
|
|
CTR_CFGOPT(uchar, IDPOPT_NUM_UNS|IDPOPT_NUM_CHAR)
|
|
CTR_CFGOPT(short, IDPOPT_NUM_SHORT)
|
|
CTR_CFGOPT(ushort, IDPOPT_NUM_SHORT|IDPOPT_NUM_UNS)
|
|
#undef CTR_CFGOPT
|
|
|
|
#define CFGOPT_N(nm, cfgt, cfgm) \
|
|
cfgopt_t(nm, &cfgt::cfgm, qoffsetof(cfgt, cfgm))
|
|
|
|
#define CFGOPT_INNER_N(nm, cfgt, cfgm, mt, mf) \
|
|
cfgopt_t(nm, &mt::mf, qoffsetof(cfgt, cfgm) + qoffsetof(mt, mf))
|
|
|
|
|
|
// IDPOPT_NUM + ranges
|
|
#define CTR_CFGOPT(ctrtype, ctrflags) \
|
|
template<class T> \
|
|
constexpr cfgopt_t(const char *_n, ctrtype T:: *, size_t _mbroff, int64 _min, int64 _max) \
|
|
: name(_n), \
|
|
mbroff(_mbroff), \
|
|
flags(IDPOPT_MBROFF|IDPOPT_NUM|IDPOPT_NUM_RANGE|ctrflags), \
|
|
num_range(_min, _max) \
|
|
{}
|
|
CTR_CFGOPT(int, 0)
|
|
CTR_CFGOPT(uint, IDPOPT_NUM_UNS)
|
|
CTR_CFGOPT(char, IDPOPT_NUM_CHAR)
|
|
CTR_CFGOPT(uchar, IDPOPT_NUM_UNS|IDPOPT_NUM_CHAR)
|
|
CTR_CFGOPT(short, IDPOPT_NUM_SHORT)
|
|
CTR_CFGOPT(ushort, IDPOPT_NUM_SHORT|IDPOPT_NUM_UNS)
|
|
#undef CTR_CFGOPT
|
|
|
|
#define CFGOPT_R(nm, cfgt, cfgm, min, max) \
|
|
cfgopt_t(nm, &cfgt::cfgm, qoffsetof(cfgt, cfgm), min, max)
|
|
|
|
#define CFGOPT_INNER_R(nm, cfgt, cfgm, mt, mf, min, max) \
|
|
cfgopt_t(nm, &mt::mf, qoffsetof(cfgt, cfgm) + qoffsetof(mt, mf), min, max)
|
|
|
|
|
|
// IDPOPT_BIT
|
|
#define CTR_CFGOPT(ctrtype, ctrflags) \
|
|
template<class T> \
|
|
constexpr cfgopt_t(const char *_n, ctrtype T:: *, size_t _mbroff, ctrtype _flags) \
|
|
: name(_n), \
|
|
mbroff(_mbroff), \
|
|
flags(IDPOPT_MBROFF|IDPOPT_BIT|ctrflags), \
|
|
bit_flags(_flags) \
|
|
{}
|
|
CTR_CFGOPT(bool, IDPOPT_BIT_BOOL);
|
|
CTR_CFGOPT(uchar, IDPOPT_BIT_UCHAR);
|
|
CTR_CFGOPT(ushort, IDPOPT_BIT_USHORT);
|
|
CTR_CFGOPT(uint32, 0);
|
|
#undef CTR_CFGOPT
|
|
#define CFGOPT_B(nm, cfgt, cfgm, _flags) \
|
|
cfgopt_t(nm, &cfgt::cfgm, qoffsetof(cfgt, cfgm), _flags)
|
|
|
|
#define CFGOPT_INNER_B(nm, cfgt, cfgm, mt, mf, _flags) \
|
|
cfgopt_t(nm, &mt::mf, qoffsetof(cfgt, cfgm) + qoffsetof(mt, mf), _flags)
|
|
|
|
|
|
// IDPOPT_I64
|
|
template<class T>
|
|
constexpr cfgopt_t(const char *_n, int64 T:: *, size_t _mbroff)
|
|
: name(_n),
|
|
mbroff(_mbroff),
|
|
flags(IDPOPT_MBROFF|IDPOPT_I64),
|
|
buf_size(0)
|
|
{}
|
|
template<class T>
|
|
constexpr cfgopt_t(const char *_n, uint64 T:: *, size_t _mbroff)
|
|
: name(_n),
|
|
mbroff(_mbroff),
|
|
flags(IDPOPT_MBROFF|IDPOPT_I64|IDPOPT_NUM_UNS),
|
|
buf_size(0)
|
|
{}
|
|
|
|
// IDPOPT_I64 + ranges
|
|
template<class T>
|
|
constexpr cfgopt_t(const char *_n, int64 T:: *, size_t _mbroff, int64 _min, int64 _max)
|
|
: name(_n),
|
|
mbroff(_mbroff),
|
|
flags(IDPOPT_MBROFF|IDPOPT_I64|IDPOPT_I64_RANGES),
|
|
num_range(_min, _max)
|
|
{}
|
|
template<class T>
|
|
constexpr cfgopt_t(const char *_n, uint64 T:: *, size_t _mbroff, uint64 _min, uint64 _max)
|
|
: name(_n),
|
|
mbroff(_mbroff),
|
|
flags(IDPOPT_MBROFF|IDPOPT_I64|IDPOPT_I64_UNS|IDPOPT_I64_RANGES),
|
|
num_range(int64(_min), int64(_max))
|
|
{}
|
|
|
|
// IDPOPT_CST + params
|
|
constexpr cfgopt_t(const char *_n, cfgopt_handler3_t *_p, int64 _p1=0, int64 _p2=0)
|
|
: name(_n), hnd3(_p), flags(IDPOPT_MBROFF|IDPOPT_CST), params(_p1, _p2) {}
|
|
|
|
int type() const { return flags & 0xf; }
|
|
int qualifier() const { return flags & 0xf000000; }
|
|
|
|
const char *apply(int vtype, const void *vdata, void *obj=nullptr) const
|
|
{
|
|
return cfgopt_t__apply2(this, vtype, vdata, obj);
|
|
}
|
|
};
|
|
|
|
/// Parse the input, and apply options.
|
|
///
|
|
/// \param input input file name, or string
|
|
/// \param is_file is input a string, or a file name
|
|
/// \param opts options destcriptions
|
|
/// \param nopts the number of entries present in the 'opts' array
|
|
/// \param defhdlr a handler to be called, if a directive couldn't be found in 'opts'
|
|
/// \param defines a list of preprocessor identifiers to define (so it is
|
|
/// possible to use #ifdef checks in the file.)
|
|
/// NB: the actual identifier defined by the parser will be
|
|
/// surrounded with double underscores (e.g., passing 'FOO'
|
|
/// will result in '__FOO__' being defined)
|
|
/// Additionally, the parser will also define a similar macro
|
|
/// with the current processor name (e.g., __ARM__)
|
|
/// \param ndefines the number of defines in the list
|
|
/// \param obj see cfgopt_t constructor based on the offset of a structure member
|
|
/// \return true if parsing finished without errors, false if there was a
|
|
/// syntax error, callback returned an error, or no file was found
|
|
/// at all.
|
|
|
|
idaman bool ida_export read_config(
|
|
const char *input,
|
|
bool is_file,
|
|
const cfgopt_t opts[],
|
|
size_t nopts,
|
|
cfgopt_handler_t *defhdlr = NULL,
|
|
const char *const *defines = NULL,
|
|
size_t ndefines = 0);
|
|
|
|
idaman bool ida_export read_config2(
|
|
const char *input,
|
|
bool is_file,
|
|
const cfgopt_t opts[],
|
|
size_t nopts,
|
|
cfgopt_handler_t *defhdlr = nullptr,
|
|
const char *const *defines = nullptr,
|
|
size_t ndefines = 0,
|
|
void *obj = nullptr);
|
|
|
|
inline bool read_config_file2(
|
|
const char *filename,
|
|
const cfgopt_t opts[],
|
|
size_t nopts,
|
|
cfgopt_handler_t *defhdlr = nullptr,
|
|
const char *const *defines = nullptr,
|
|
size_t ndefines = 0,
|
|
void *obj = nullptr)
|
|
{
|
|
return read_config2(filename, true, opts, nopts, defhdlr, defines, ndefines, obj);
|
|
}
|
|
|
|
/// Search for all IDA system files with the given name.
|
|
/// This function will search, in that order, for the following files:
|
|
/// -# %IDADIR%/cfg/<file>
|
|
/// -# for each directory 'ONEDIR' in %IDAUSR%: %ONEDIR%/cfg/<file>
|
|
///
|
|
/// For each directive in each of those files, the same processing as
|
|
/// that of read_config will be performed.
|
|
|
|
inline bool read_config_file(
|
|
const char *filename,
|
|
const cfgopt_t opts[],
|
|
size_t nopts,
|
|
cfgopt_handler_t *defhdlr = NULL,
|
|
const char *const *defines = NULL,
|
|
size_t ndefines = 0)
|
|
{
|
|
return read_config(filename, true, opts, nopts, defhdlr, defines, ndefines);
|
|
}
|
|
|
|
|
|
/// For each directive in 'string', the same processing as that of
|
|
/// read_config will be performed.
|
|
inline bool read_config_string(
|
|
const char *string,
|
|
const cfgopt_t opts[],
|
|
size_t nopts,
|
|
cfgopt_handler_t *defhdlr = NULL,
|
|
const char *const *defines = NULL,
|
|
size_t ndefines = 0)
|
|
{
|
|
return read_config(string, false, opts, nopts, defhdlr, defines, ndefines);
|
|
}
|
|
|
|
|
|
/// Process one or more config directive(s).
|
|
/// \param directive the directives to process
|
|
/// \param priority priority \ref IDPOPT_RET
|
|
/// In the case of errors this function displays a message and exits.
|
|
|
|
idaman void ida_export process_config_directive(
|
|
const char *directive,
|
|
int priority=IDPOPT_PRI_HIGH);
|
|
|
|
|
|
/// Register array of config options.
|
|
/// This function can be used by a plugin to register the config options.
|
|
/// After registering an option, it becomes usable by the
|
|
/// process_config_directive() function.
|
|
/// \param opts array of config options
|
|
/// \param nopts number of options to install. 0 means uninstall
|
|
/// \param cb callback that will be invoked upon changing a config option
|
|
/// \param obj see cfgopt_t constructor based on the offset of a structure member
|
|
/// \return success
|
|
|
|
typedef void idaapi config_changed_cb_t(const cfgopt_t &opt, int vtype, const void *vdata);
|
|
|
|
idaman bool ida_export register_cfgopts(
|
|
const cfgopt_t opts[],
|
|
size_t nopts,
|
|
config_changed_cb_t cb=nullptr,
|
|
void *obj=nullptr);
|
|
|
|
|
|
/// Get one of config parameters defined by CC_PARMS in ida.cfg.
|
|
/// All parameters for all compilers are stored in local map during last read
|
|
/// of ida.cfg - this function just returns previously stored parameter value for
|
|
/// given compiler (NULL if no such parameter)
|
|
idaman const char *ida_export cfg_get_cc_parm(comp_t compid, const char *name);
|
|
|
|
|
|
/// Get header path config parameter from ida.cfg.
|
|
/// Also see cfg_get_cc_parm()
|
|
|
|
inline const char *cfg_get_cc_header_path(comp_t compid)
|
|
{
|
|
return cfg_get_cc_parm(compid, "HEADER_PATH");
|
|
}
|
|
|
|
|
|
/// Get predefined macros config parameter from ida.cfg.
|
|
/// Also see cfg_get_cc_parm()
|
|
|
|
inline const char *cfg_get_cc_predefined_macros(comp_t compid)
|
|
{
|
|
return cfg_get_cc_parm(compid, "PREDEFINED_MACROS");
|
|
}
|
|
|
|
#endif // _CONFIG_HPP
|