Files
sigmaker-ida/idasdk75/include/ida_highlighter.hpp
2021-06-05 21:10:25 +03:00

147 lines
5.3 KiB
C++

#ifndef IDA_HIGHLIGHTER
#define IDA_HIGHLIGHTER
#include <expr.hpp>
idaman void ida_export code_highlight_block(void *context, highlighter_cbs_t *highlighter_cbs, const qstring &text);
// returns the length of text to colorize
// negative values may have special meaning in the future.
typedef ssize_t idaapi external_colorizer_t(syntax_highlight_style *color, const char *str);
typedef qvector<external_colorizer_t *> external_colorizers_t;
// returns true if identifier is colorized
typedef bool idaapi external_ident_colorizer_t(syntax_highlight_style *color, const qstring &ident);
typedef qvector<external_ident_colorizer_t *> external_ident_colorizers_t;
#define MLTCMTMASK 0xF
#define PREPROC_FLAG 0x10
// Common implementation of syntax_highlighter_t used in different parts of IDA
//-V:ida_syntax_highlighter_t:730 not all members of a class are initialized inside the constructor
struct ida_syntax_highlighter_t : syntax_highlighter_t
{
protected:
// keys of keywords_t point to memory from keyword_strings.
// once allocated, this buffer won't be moved in the memory.
qstrvec_t keyword_memory;
// helper class so that keywords_t gets sorted by string contents, not pointer values.
struct plain_char_ptr_t
{
const char *ptr;
plain_char_ptr_t(const char *p = NULL) : ptr(p) {}
bool operator <(const plain_char_ptr_t &r) const
{
return strcmp(ptr, r.ptr) < 0;
}
bool operator ==(const plain_char_ptr_t &r) const
{
return strcmp(ptr, r.ptr) == 0;
}
};
struct multicmt_t
{
qstring open_multicmt;
qstring close_multicmt;
multicmt_t() {}
multicmt_t(const char *_open_multicmt, const char *_close_multicmt) :
open_multicmt(_open_multicmt),
close_multicmt(_close_multicmt)
{}
};
// typedef std::map<plain_char_ptr_t, syntax_highlight_style> keywords_t;
struct keywords_style_t
{
qvector<plain_char_ptr_t> keywords;
syntax_highlight_style style;
};
typedef qvector<keywords_style_t> keywords_t;
//typedef qvector<plain_char_ptr_t> keywords_t;
typedef qvector<multicmt_t> multicmtvec_t;
keywords_t keywords;
qstring open_cmt; // string that opens a regular line comment
multicmtvec_t multicmts;
char literal_closer; // either close_strconst or close_chrconst for the current literal
// color mappings
syntax_highlight_style text_color = HF_DEFAULT;
syntax_highlight_style comment_color = HF_COMMENT;
syntax_highlight_style string_color = HF_STRING;
syntax_highlight_style preprocessor_color = HF_PREPROC;
external_colorizers_t external_colorizers;
external_ident_colorizers_t external_ident_colorizers;
// work variables
const char *input; // pointer to the start of the input buffer
const char *pending; // pointer in the input buffer
syntax_highlight_style style = HF_DEFAULT; // current highlighting style
bool pending_nonspaces_present(const char *end)
{
for ( const char *p = pending; p != end; ++p )
if ( !qisspace(*p) )
return true;
return false;
}
const char *parse_literal_const(highlighter_cbs_t *highlighter_cbs, const char *ptr, char literal_closer);
void flush_output(highlighter_cbs_t *highlighter_cbs, const char *ptr, syntax_highlight_style style);
void handle_cmt(highlighter_cbs_t *highlighter_cbs, int mcmt_idx, const char **ptr);
void handle_preproc(highlighter_cbs_t *highlighter_cbs, const char **ptr);
public:
// if any of the following features is not needed, just zero them out:
char open_strconst; // character that opens a string constant
char close_strconst; // character that closes a string constant
char open_chrconst; // character that closes a character constant
char close_chrconst; // character that opens a character constant
char escape_char; // backslash
char preprocessor_char; // #
ida_syntax_highlighter_t() : syntax_highlighter_t(&code_highlight_block) {}
void highlight_block_ex(highlighter_cbs_t *highlighter_cbs, const qstring &text);
void add_external_colorizer(external_colorizer_t *th) { external_colorizers.push_back(th); }
void add_external_ident_colorizer(external_ident_colorizer_t *th) { external_ident_colorizers.push_back(th); }
void set_open_cmt(const char *begin) { open_cmt = begin; }
void add_multi_line_comment(const char *begin, const char *end)
{
multicmt_t &mcmt = multicmts.push_back();
mcmt.open_multicmt = begin;
mcmt.close_multicmt = end;
}
void add_keywords(const char *kwstr, syntax_highlight_style _style)
{
char *ctx;
// in order not to allocate every keyword separately, we allocate the whole
// kwstr string at once and will just store pointers to it in the map.
qstring &mem = keyword_memory.push_back();
mem = kwstr;
keywords_style_t *pair_p = NULL;
for ( int i = 0; i < keywords.size(); i++ )
{
if ( keywords[i].style == _style )
{
pair_p = &keywords[i];
break;
}
}
if ( pair_p == NULL )
{
keywords_style_t &pair = keywords.push_back();
pair_p = &pair;
pair_p->style = _style;
}
for ( char *kw = qstrtok(mem.begin(), "|", &ctx); kw != NULL; kw = qstrtok(NULL, "|", &ctx) )
pair_p->keywords.push_back(kw);
}
};
#endif //IDA_HIGHLIGHTER