From 56f7524c4fd0fc14a509be7689f4820b31564dbc Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 23 Oct 2016 18:22:50 +0200 Subject: Deleted a level of data to reduce the memory fingerprint. --- ChangeLog | 74 ++ plugins/androhelpers/switch.c | 6 +- plugins/androhelpers/try_n_catch.c | 4 +- src/analysis/db/items/switcher.c | 26 +- src/analysis/disass/output.c | 14 +- src/analysis/routine.c | 14 +- src/analysis/types/basic.c | 2 +- src/analysis/types/cse.c | 4 +- src/analysis/types/encaps.c | 2 +- src/analysis/types/literal.c | 2 +- src/analysis/types/template.c | 6 +- src/analysis/variable.c | 4 +- src/arch/arm/v7/cregister.c | 2 +- src/arch/arm/v7/operands/coproc.c | 2 +- src/arch/arm/v7/operands/estate.c | 4 +- src/arch/arm/v7/operands/limitation.c | 18 +- src/arch/arm/v7/operands/maccess.c | 16 +- src/arch/arm/v7/operands/offset.c | 2 +- src/arch/arm/v7/operands/reglist.c | 8 +- src/arch/arm/v7/operands/rotation.c | 4 +- src/arch/arm/v7/operands/shift.c | 12 +- src/arch/arm/v7/register.c | 2 +- src/arch/dalvik/operands/args.c | 8 +- src/arch/dalvik/operands/pool.c | 36 +- src/arch/dalvik/register.c | 2 +- src/arch/instruction.c | 6 +- src/arch/operand.c | 5 +- src/arch/raw.c | 20 +- src/arch/target.c | 4 +- src/arch/undefined.c | 2 +- src/arch/x86/register.c | 2 +- src/decomp/expr/access.c | 2 +- src/decomp/expr/arithm.c | 2 +- src/decomp/expr/array.c | 4 +- src/decomp/expr/assign.c | 2 +- src/decomp/expr/call.c | 10 +- src/decomp/expr/dalvik/array.c | 4 +- src/decomp/expr/pseudo.c | 4 +- src/decomp/expr/return.c | 4 +- src/decomp/expr/text.c | 6 +- src/decomp/expression.c | 2 +- src/decomp/instr/ite.c | 4 +- src/decomp/instr/keyword.c | 4 +- src/decomp/instr/switch.c | 24 +- src/decomp/lang/asm.c | 28 +- src/decomp/lang/java.c | 74 +- src/format/dex/class.c | 2 +- src/glibext/Makefile.am | 3 +- src/glibext/gbinportion.c | 14 +- src/glibext/gbufferline.c | 806 +++----------------- src/glibext/gbufferline.h | 31 +- src/glibext/gbuffersegment.c | 1333 --------------------------------- src/glibext/gbuffersegment.h | 203 ----- src/glibext/gbufferview.c | 112 +-- src/glibext/gbufferview.h | 2 +- src/glibext/gcodebuffer.c | 8 +- src/glibext/linecolumn.c | 480 ++++++++++++ src/glibext/linecolumn.h | 93 +++ src/glibext/linesegment.c | 1155 ++++++++++++++++++++++++++++ src/glibext/linesegment.h | 196 +++++ src/gtkext/gtkbufferview.c | 3 + src/gui/core/core.c | 6 +- src/gui/dialogs/export.c | 2 +- 63 files changed, 2387 insertions(+), 2549 deletions(-) delete mode 100644 src/glibext/gbuffersegment.c delete mode 100644 src/glibext/gbuffersegment.h create mode 100644 src/glibext/linecolumn.c create mode 100644 src/glibext/linecolumn.h create mode 100644 src/glibext/linesegment.c create mode 100644 src/glibext/linesegment.h diff --git a/ChangeLog b/ChangeLog index 11da097..3a5e6e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,79 @@ 16-10-23 Cyrille Bagard + * plugins/androhelpers/switch.c: + * plugins/androhelpers/try_n_catch.c: + * src/analysis/db/items/switcher.c: + * src/analysis/disass/output.c: + * src/analysis/routine.c: + * src/analysis/types/basic.c: + * src/analysis/types/cse.c: + * src/analysis/types/encaps.c: + * src/analysis/types/literal.c: + * src/analysis/types/template.c: + * src/analysis/variable.c: + * src/arch/arm/v7/cregister.c: + * src/arch/arm/v7/operands/coproc.c: + * src/arch/arm/v7/operands/estate.c: + * src/arch/arm/v7/operands/limitation.c: + * src/arch/arm/v7/operands/maccess.c: + * src/arch/arm/v7/operands/offset.c: + * src/arch/arm/v7/operands/reglist.c: + * src/arch/arm/v7/operands/rotation.c: + * src/arch/arm/v7/operands/shift.c: + * src/arch/arm/v7/register.c: + * src/arch/dalvik/operands/args.c: + * src/arch/dalvik/operands/pool.c: + * src/arch/dalvik/register.c: + * src/arch/instruction.c: + * src/arch/operand.c: + * src/arch/raw.c: + * src/arch/target.c: + * src/arch/undefined.c: + * src/arch/x86/register.c: + * src/decomp/expr/access.c: + * src/decomp/expr/arithm.c: + * src/decomp/expr/array.c: + * src/decomp/expr/assign.c: + * src/decomp/expr/call.c: + * src/decomp/expr/dalvik/array.c: + * src/decomp/expression.c: + * src/decomp/expr/pseudo.c: + * src/decomp/expr/return.c: + * src/decomp/expr/text.c: + * src/decomp/instr/ite.c: + * src/decomp/instr/keyword.c: + * src/decomp/instr/switch.c: + * src/decomp/lang/asm.c: + * src/decomp/lang/java.c: + * src/format/dex/class.c: + * src/glibext/gbinportion.c: + Update code. + + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + * src/glibext/gbuffersegment.c: + * src/glibext/gbuffersegment.h: + * src/glibext/gbufferview.c: + * src/glibext/gbufferview.h: + * src/glibext/gcodebuffer.c: + Delete a level of data to reduce the memory fingerprint. + + * src/glibext/linecolumn.c: + * src/glibext/linecolumn.h: + New entries: delete a level of data to reduce the memory fingerprint. + + * src/glibext/linesegment.c: + * src/glibext/linesegment.h: + Renamed entries: delete a level of data to reduce the memory fingerprint. + + * src/glibext/Makefile.am: + * src/gtkext/gtkbufferview.c: + * src/gui/core/core.c: + * src/gui/dialogs/export.c: + Update code. + +16-10-23 Cyrille Bagard + * src/arch/immediate.c: * src/arch/target.c: Update code. diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c index 20b2119..2434897 100644 --- a/plugins/androhelpers/switch.c +++ b/plugins/androhelpers/switch.c @@ -286,7 +286,7 @@ static void mark_all_switch_cases(const GArchInstruction *instr, const dex_switc fulldesc = (char *)calloc(len + 1, sizeof(char)); len = snprintf(fulldesc, len + 1, _("; Case for value 0x%08x (%d)"), value, value); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, fulldesc, len, RTT_INDICATION); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, fulldesc, len, RTT_INDICATION, NULL); free(fulldesc); @@ -304,8 +304,8 @@ static void mark_all_switch_cases(const GArchInstruction *instr, const dex_switc g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); fulldesc = _("; Default case"); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, - fulldesc, strlen(fulldesc), RTT_INDICATION); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, + fulldesc, strlen(fulldesc), RTT_INDICATION, NULL); } diff --git a/plugins/androhelpers/try_n_catch.c b/plugins/androhelpers/try_n_catch.c index 0e2ae43..7e39327 100644 --- a/plugins/androhelpers/try_n_catch.c +++ b/plugins/androhelpers/try_n_catch.c @@ -204,13 +204,13 @@ static void mark_exception_handlers(const GLoadedBinary *binary, uleb128_t size, line = g_code_buffer_insert_at(buffer, handlers[i][j].addr, true); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_INDICATION); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_INDICATION, NULL); len = strlen(_("Handler for caught '%s'")) + strlen(handlers[i][j].desc); fulldesc = (char *)calloc(len + 1, sizeof(char)); snprintf(fulldesc, len + 1, _("Handler for caught '%s'"), handlers[i][j].desc); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, fulldesc, len, RTT_INDICATION); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, fulldesc, len, RTT_INDICATION, NULL); free(fulldesc); diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index a67040f..08a5a5f 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -502,7 +502,6 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO GArchOperand *op; /* Opérande à modifier */ GCodeBuffer *buffer; /* Tampon de lignes à traiter */ GBufferLine *line; /* Ligne de tampon à marquer */ - GBufferSegment *segment; /* Segment de texte à modifier*/ GImmOperand *operand; /* Opérande de valeur immédiate*/ char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */ size_t len; /* Taille de l'élément inséré */ @@ -541,29 +540,18 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO goto exit_gui; } - segment = g_buffer_line_find_segment_from_creator(line, G_OBJECT(op)); - result = (segment != NULL); + operand = G_IMM_OPERAND(op); - /* Applications globales finales */ + *old = g_imm_operand_get_display(operand); - if (result) - { - operand = G_IMM_OPERAND(op); - - *old = g_imm_operand_get_display(operand); - - if (new == IOD_COUNT) - new = g_imm_operand_get_default_display(operand); + if (new == IOD_COUNT) + new = g_imm_operand_get_default_display(operand); - g_imm_operand_set_display(operand, new); + g_imm_operand_set_display(operand, new); - len = g_imm_operand_to_string(operand, ASX_INTEL, value); + len = g_imm_operand_to_string(operand, ASX_INTEL, value); - g_buffer_segment_update_text(segment, value, len); - - g_object_unref(G_OBJECT(segment)); - - } + result = g_buffer_line_replace_text(line, G_OBJECT(op), value, len); g_object_unref(G_OBJECT(line)); diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index fb3f5ed..4fdc3c0 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -147,8 +147,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, - ROUTINE_OUTRO_MSG, strlen(ROUTINE_OUTRO_MSG), RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, + ROUTINE_OUTRO_MSG, strlen(ROUTINE_OUTRO_MSG), RTT_COMMENT, NULL); g_code_buffer_append_new_line(buffer, line); @@ -223,8 +223,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, - ROUTINE_INTRO_MSG, strlen(ROUTINE_INTRO_MSG), RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, + ROUTINE_INTRO_MSG, strlen(ROUTINE_INTRO_MSG), RTT_COMMENT, NULL); g_code_buffer_append_new_line(buffer, line); @@ -255,8 +255,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_LABEL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_LABEL, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL); g_code_buffer_append_new_line(buffer, line); @@ -311,7 +311,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA - g_buffer_line_insert_text(line, BLC_COMMENTS, prefixed, strlen(prefixed), RTT_COMMENT); + g_buffer_line_append_text(line, BLC_COMMENTS, prefixed, strlen(prefixed), RTT_COMMENT, NULL); free(prefixed); diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 7483bf0..ed91726 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -1033,7 +1033,7 @@ void g_binary_routine_output_info(const GBinRoutine *routine, GLangOutput *lang, g_data_type_output(routine->ret_type, lang, line, true, false); - g_buffer_line_insert_text(line, BLC_LAST_USED, " ", 1, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, " ", 1, RTT_COMMENT, NULL); /* Nom de la routine */ @@ -1045,22 +1045,22 @@ void g_binary_routine_output_info(const GBinRoutine *routine, GLangOutput *lang, len = 3; } - g_buffer_line_insert_text(line, BLC_LAST_USED, name, len, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, name, len, RTT_COMMENT, NULL); /* Arguments éventuels... */ - g_buffer_line_insert_text(line, BLC_LAST_USED, "(", 1, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, "(", 1, RTT_COMMENT, NULL); for (i = 0; i < routine->args_count; i++) { if (i > 0) - g_buffer_line_insert_text(line, BLC_LAST_USED, ", ", 2, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, ", ", 2, RTT_COMMENT, NULL); g_binary_variable_output(routine->args[i], lang, line, true, false); } - g_buffer_line_insert_text(line, BLC_LAST_USED, ")", 1, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, ")", 1, RTT_COMMENT, NULL); //g_lang_output_end_routine_prototype(lang, buffer, line); @@ -1092,7 +1092,7 @@ void g_binary_routine_print_code(const GBinRoutine *routine, GLangOutput *lang, line = g_lang_output_start_routine_prototype(lang, buffer, routine->ret_type); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); /* Nom de la routine */ @@ -1104,7 +1104,7 @@ void g_binary_routine_print_code(const GBinRoutine *routine, GLangOutput *lang, len = 3; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, name, len, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, name, len, RTT_COMMENT, NULL); diff --git a/src/analysis/types/basic.c b/src/analysis/types/basic.c index 0bf3ad4..dcd8634 100644 --- a/src/analysis/types/basic.c +++ b/src/analysis/types/basic.c @@ -319,7 +319,7 @@ static void g_basic_type_output(const GBasicType *type, GLangOutput *lang, GBuff text = g_basic_type_to_string(type); len = strlen(text); - g_buffer_line_insert_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW); + g_buffer_line_append_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW, NULL); free(text); diff --git a/src/analysis/types/cse.c b/src/analysis/types/cse.c index 4a0e4e5..2411cd1 100644 --- a/src/analysis/types/cse.c +++ b/src/analysis/types/cse.c @@ -172,7 +172,7 @@ char *g_class_enum_type_to_string(const GClassEnumType *type) void g_class_enum_type_output(const GClassEnumType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) { - g_buffer_line_insert_text(line, BLC_LAST_USED, type->name, strlen(type->name), - info ? RTT_COMMENT : RTT_RAW); + g_buffer_line_append_text(line, BLC_LAST_USED, type->name, strlen(type->name), + info ? RTT_COMMENT : RTT_RAW, NULL); } diff --git a/src/analysis/types/encaps.c b/src/analysis/types/encaps.c index dffc69d..7ca8885 100644 --- a/src/analysis/types/encaps.c +++ b/src/analysis/types/encaps.c @@ -276,7 +276,7 @@ static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) static void g_encapsulated_type_output(const GEncapsulatedType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) { - g_buffer_line_insert_text(line, BLC_LAST_USED, "!TODO!", 6, info ? RTT_COMMENT : RTT_RAW); + g_buffer_line_append_text(line, BLC_LAST_USED, "!TODO!", 6, info ? RTT_COMMENT : RTT_RAW, NULL); } diff --git a/src/analysis/types/literal.c b/src/analysis/types/literal.c index 7dbd5f0..5c3a3e8 100644 --- a/src/analysis/types/literal.c +++ b/src/analysis/types/literal.c @@ -234,7 +234,7 @@ static void g_literal_type_output(const GLiteralType *type, GLangOutput *lang, G text = g_literal_type_to_string(type); len = strlen(text); - g_buffer_line_insert_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW); + g_buffer_line_append_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW, NULL); free(text); diff --git a/src/analysis/types/template.c b/src/analysis/types/template.c index daeb454..974991a 100644 --- a/src/analysis/types/template.c +++ b/src/analysis/types/template.c @@ -240,18 +240,18 @@ static void g_template_type_output(const GTemplateType *type, GLangOutput *lang, g_class_enum_type_output(G_CLASS_ENUM_TYPE(type), lang, line, info, full); - g_buffer_line_insert_text(line, BLC_LAST_USED, "<", 1, info ? RTT_COMMENT : RTT_LTGT); + g_buffer_line_append_text(line, BLC_LAST_USED, "<", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); for (i = 0; i < type->models_count; i++) { if (i > 0) - g_buffer_line_insert_text(line, BLC_LAST_USED, ", ", 2, info ? RTT_COMMENT : RTT_SIGNS); + g_buffer_line_append_text(line, BLC_LAST_USED, ", ", 2, info ? RTT_COMMENT : RTT_SIGNS, NULL); g_data_type_output(type->models[i], lang, line, info, full); } - g_buffer_line_insert_text(line, BLC_LAST_USED, ">", 1, info ? RTT_COMMENT : RTT_LTGT); + g_buffer_line_append_text(line, BLC_LAST_USED, ">", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); } diff --git a/src/analysis/variable.c b/src/analysis/variable.c index d547281..e78c793 100644 --- a/src/analysis/variable.c +++ b/src/analysis/variable.c @@ -295,9 +295,9 @@ void g_binary_variable_output(const GBinVariable *var, GLangOutput *lang, GBuffe if (var->name != NULL) { if (!g_data_type_is_pointer(var->type, true)) - g_buffer_line_insert_text(line, BLC_LAST_USED, " ", 1, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, " ", 1, RTT_COMMENT, NULL); - g_buffer_line_insert_text(line, BLC_LAST_USED, var->name, strlen(var->name), RTT_COMMENT); + g_buffer_line_append_text(line, BLC_LAST_USED, var->name, strlen(var->name), RTT_COMMENT, NULL); } diff --git a/src/arch/arm/v7/cregister.c b/src/arch/arm/v7/cregister.c index 62f3833..f247df4 100644 --- a/src/arch/arm/v7/cregister.c +++ b/src/arch/arm/v7/cregister.c @@ -207,6 +207,6 @@ static void g_armv7_cregister_print(const GArmV7CRegister *reg, GBufferLine *lin break; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER); + g_buffer_line_append_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL); } diff --git a/src/arch/arm/v7/operands/coproc.c b/src/arch/arm/v7/operands/coproc.c index c816b37..90f8874 100644 --- a/src/arch/arm/v7/operands/coproc.c +++ b/src/arch/arm/v7/operands/coproc.c @@ -197,7 +197,7 @@ static void g_armv7_coproc_operand_print(const GArmV7CoprocOperand *operand, GBu nlen = snprintf(name, sizeof(name), "p%hhu", operand->index); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, name, nlen, RTT_REGISTER); + g_buffer_line_append_text(line, BLC_ASSEMBLY, name, nlen, RTT_REGISTER, NULL); } diff --git a/src/arch/arm/v7/operands/estate.c b/src/arch/arm/v7/operands/estate.c index 214508a..6f66832 100644 --- a/src/arch/arm/v7/operands/estate.c +++ b/src/arch/arm/v7/operands/estate.c @@ -193,9 +193,9 @@ GArchOperand *g_armv7_endian_operand_new(bool big) static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line, AsmSyntax syntax) { if (operand->big) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL); else - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL); } diff --git a/src/arch/arm/v7/operands/limitation.c b/src/arch/arm/v7/operands/limitation.c index 4d1d661..5a5b567 100644 --- a/src/arch/arm/v7/operands/limitation.c +++ b/src/arch/arm/v7/operands/limitation.c @@ -199,39 +199,39 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *oper switch (operand->type) { case BLT_SY: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "SY", 2, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "SY", 2, RTT_KEY_WORD, NULL); break; case BLT_ST: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ST", 2, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "ST", 2, RTT_KEY_WORD, NULL); break; case BLT_ISH: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ISH", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "ISH", 3, RTT_KEY_WORD, NULL); break; case BLT_ISHST: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ISHST", 5, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "ISHST", 5, RTT_KEY_WORD, NULL); break; case BLT_NSH: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "NSH", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "NSH", 3, RTT_KEY_WORD, NULL); break; case BLT_NSHST: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "NSHST", 5, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "NSHST", 5, RTT_KEY_WORD, NULL); break; case BLT_OSH: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "OSH", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "OSH", 3, RTT_KEY_WORD, NULL); break; case BLT_OSHST: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "OSHST", 5, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "OSHST", 5, RTT_KEY_WORD, NULL); break; default: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "(reserved)", 10, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "(reserved)", 10, RTT_KEY_WORD, NULL); break; } diff --git a/src/arch/arm/v7/operands/maccess.c b/src/arch/arm/v7/operands/maccess.c index 8eb5b57..10c8328 100644 --- a/src/arch/arm/v7/operands/maccess.c +++ b/src/arch/arm/v7/operands/maccess.c @@ -213,17 +213,17 @@ GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offs static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, GBufferLine *line, AsmSyntax syntax) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "[", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "[", 1, RTT_HOOK, NULL); g_arch_operand_print(operand->base, line, syntax); if (!operand->not_post_indexed) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL); if (operand->offset != NULL) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); g_arch_operand_print(operand->offset, line, syntax); @@ -231,18 +231,18 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G if (operand->shift != NULL) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); g_arch_operand_print(operand->shift, line, syntax); } if (operand->not_post_indexed) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL); if (operand->write_back) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "!", 1, RTT_PUNCT); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); } diff --git a/src/arch/arm/v7/operands/offset.c b/src/arch/arm/v7/operands/offset.c index 9a9506a..03d69d8 100644 --- a/src/arch/arm/v7/operands/offset.c +++ b/src/arch/arm/v7/operands/offset.c @@ -198,7 +198,7 @@ GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value) static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBufferLine *line, AsmSyntax syntax) { if (!operand->positive) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "-", 1, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "-", 1, RTT_KEY_WORD, NULL); g_arch_operand_print(operand->value, line, syntax); diff --git a/src/arch/arm/v7/operands/reglist.c b/src/arch/arm/v7/operands/reglist.c index a54d148..7ad72d0 100644 --- a/src/arch/arm/v7/operands/reglist.c +++ b/src/arch/arm/v7/operands/reglist.c @@ -206,21 +206,21 @@ static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, G { size_t i; /* Boucle de parcours */ - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "{", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL); for (i = 0; i < operand->count; i++) { if (i > 0) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line, syntax); } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "}", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL); } diff --git a/src/arch/arm/v7/operands/rotation.c b/src/arch/arm/v7/operands/rotation.c index 1532270..22f53c3 100644 --- a/src/arch/arm/v7/operands/rotation.c +++ b/src/arch/arm/v7/operands/rotation.c @@ -194,9 +194,9 @@ GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value) static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *operand, GBufferLine *line, AsmSyntax syntax) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ror", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "ror", 3, RTT_KEY_WORD, NULL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); g_arch_operand_print(operand->value, line, syntax); diff --git a/src/arch/arm/v7/operands/shift.c b/src/arch/arm/v7/operands/shift.c index 7a90a70..9a9035c 100644 --- a/src/arch/arm/v7/operands/shift.c +++ b/src/arch/arm/v7/operands/shift.c @@ -199,23 +199,23 @@ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBuff switch (operand->shift_type) { case SRType_LSL: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "lsl", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "lsl", 3, RTT_KEY_WORD, NULL); break; case SRType_LSR: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "lsr", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "lsr", 3, RTT_KEY_WORD, NULL); break; case SRType_ASR: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "asr", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "asr", 3, RTT_KEY_WORD, NULL); break; case SRType_ROR: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ror", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "ror", 3, RTT_KEY_WORD, NULL); break; case SRType_RRX: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "rrx", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "rrx", 3, RTT_KEY_WORD, NULL); break; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); g_arch_operand_print(operand->shift_value, line, syntax); diff --git a/src/arch/arm/v7/register.c b/src/arch/arm/v7/register.c index 31073ee..7b91260 100644 --- a/src/arch/arm/v7/register.c +++ b/src/arch/arm/v7/register.c @@ -224,6 +224,6 @@ static void g_armv7_register_print(const GArmV7Register *reg, GBufferLine *line, break; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER); + g_buffer_line_append_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL); } diff --git a/src/arch/dalvik/operands/args.c b/src/arch/dalvik/operands/args.c index 2897698..c03d951 100644 --- a/src/arch/dalvik/operands/args.c +++ b/src/arch/dalvik/operands/args.c @@ -201,7 +201,7 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff { size_t i; /* Boucle de parcours */ - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "{", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL); if (operand->count > 0) { @@ -209,8 +209,8 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff for (i = 1; i < operand->count; i++) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); g_arch_operand_print(operand->args[i], line, syntax); @@ -218,7 +218,7 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "}", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL); } diff --git a/src/arch/dalvik/operands/pool.c b/src/arch/dalvik/operands/pool.c index 5f98a04..b84d655 100644 --- a/src/arch/dalvik/operands/pool.c +++ b/src/arch/dalvik/operands/pool.c @@ -243,7 +243,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff switch (operand->type) { case DPT_NONE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "????", 4, RTT_ERROR); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "????", 4, RTT_ERROR, NULL); break; case DPT_STRING: @@ -252,14 +252,14 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff if (string != NULL) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "\"", 1, RTT_STRING); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "\"", 1, RTT_STRING, NULL); len = strlen(string); if (len > 0) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, string, len, RTT_STRING); + g_buffer_line_append_text(line, BLC_ASSEMBLY, string, len, RTT_STRING, NULL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "\"", 1, RTT_STRING); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "\"", 1, RTT_STRING, NULL); } else @@ -268,7 +268,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = calloc(len, sizeof(char)); snprintf(tmp, len, _(""), operand->index); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR, NULL); free(tmp); @@ -285,9 +285,9 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = g_data_type_to_string(type); g_object_unref(G_OBJECT(type)); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK, NULL); } else @@ -296,7 +296,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = calloc(len, sizeof(char)); snprintf(tmp, len, _(""), operand->index); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR, NULL); } @@ -305,7 +305,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff break; case DPT_PROTO: - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "proto(/*TODO*/)", 5, RTT_SECTION); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "proto(/*TODO*/)", 5, RTT_SECTION, NULL); break; case DPT_FIELD: @@ -317,9 +317,9 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = g_binary_variable_to_string(field, false); g_object_unref(G_OBJECT(field)); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK, NULL); } else @@ -328,7 +328,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = calloc(len, sizeof(char)); snprintf(tmp, len, _(""), operand->index); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR, NULL); } @@ -350,9 +350,9 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = g_binary_routine_to_string(routine); g_object_unref(G_OBJECT(routine)); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK, NULL); } else @@ -361,7 +361,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff tmp = calloc(len, sizeof(char)); snprintf(tmp, len, _(""), operand->index); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR); + g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, len - 1, RTT_ERROR, NULL); } diff --git a/src/arch/dalvik/register.c b/src/arch/dalvik/register.c index 7c0b601..35e8f58 100644 --- a/src/arch/dalvik/register.c +++ b/src/arch/dalvik/register.c @@ -237,6 +237,6 @@ void g_dalvik_register_print(const GDalvikRegister *reg, GBufferLine *line, AsmS } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER); + g_buffer_line_append_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL); } diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 1bdb50e..8264f5b 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -1056,7 +1056,7 @@ static GBufferLine *_g_arch_instruction_print(GArchInstruction *instr, GCodeBuff key = g_arch_instruction_get_keyword(instr, syntax); klen = strlen(key); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); if (instr->operands_count > 0) { @@ -1064,8 +1064,8 @@ static GBufferLine *_g_arch_instruction_print(GArchInstruction *instr, GCodeBuff for (i = 1; i < instr->operands_count; i++) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); g_arch_operand_print(instr->operands[i], result, syntax); diff --git a/src/arch/operand.c b/src/arch/operand.c index 5b36e13..a84018f 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -212,10 +212,11 @@ void g_arch_operand_set_alt_text(GArchOperand *operand, const char *text, Render void g_arch_operand_print(const GArchOperand *operand, GBufferLine *line, AsmSyntax syntax) { if (operand->alt_text != NULL) - g_buffer_line_insert_text(line, BLC_ASSEMBLY, + g_buffer_line_append_text(line, BLC_ASSEMBLY, operand->alt_text, operand->alt_len, - operand->alt_tag); + operand->alt_tag, + NULL); else G_ARCH_OPERAND_GET_CLASS(operand)->print(operand, line, syntax); diff --git a/src/arch/raw.c b/src/arch/raw.c index 67d2507..356f809 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -456,10 +456,10 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer key = g_arch_instruction_get_keyword(base, syntax); klen = strlen(key); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); if (instr->is_padding) - g_buffer_line_insert_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL); else /*if (instr->is_string)*/ { @@ -483,15 +483,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer { if (!first) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } else first = false; string[iter++] = '"'; - g_buffer_line_insert_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING); + g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL); iter = 1; @@ -501,8 +501,8 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer if (!first) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } else first = false; @@ -521,15 +521,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer { if (!first) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } else first = false; string[iter++] = '"'; - g_buffer_line_insert_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING); + g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL); } diff --git a/src/arch/target.c b/src/arch/target.c index 0517062..7ad9e62 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -219,7 +219,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l if (operand->symbol != NULL /* FIXME */ && g_binary_symbol_get_label(operand->symbol) != NULL /* FIXME */) { if (operand->diff > 0) - g_buffer_line_insert_text(line, BLC_MAIN, "<", 1, RTT_LTGT); + g_buffer_line_append_text(line, BLC_MAIN, "<", 1, RTT_LTGT, NULL); label = g_binary_symbol_get_label(operand->symbol); g_buffer_line_append_text(line, BLC_MAIN, label, strlen(label), RTT_LABEL, G_OBJECT(operand)); @@ -233,7 +233,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand)); - g_buffer_line_insert_text(line, BLC_MAIN, ">", 1, RTT_LTGT); + g_buffer_line_append_text(line, BLC_MAIN, ">", 1, RTT_LTGT, NULL); } diff --git a/src/arch/undefined.c b/src/arch/undefined.c index 9c944bc..e69a399 100644 --- a/src/arch/undefined.c +++ b/src/arch/undefined.c @@ -254,7 +254,7 @@ static GBufferLine *g_undef_instruction_print(GUndefInstruction *instr, GCodeBuf key = g_arch_instruction_get_keyword(base, syntax); klen = strlen(key); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL); return result; diff --git a/src/arch/x86/register.c b/src/arch/x86/register.c index 0e65e58..740ec3f 100644 --- a/src/arch/x86/register.c +++ b/src/arch/x86/register.c @@ -530,7 +530,7 @@ void g_x86_pool_operand_print(const GX86Register *reg, GBufferLine *line, AsmSyn } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER); + g_buffer_line_append_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL); } diff --git a/src/decomp/expr/access.c b/src/decomp/expr/access.c index 0af60c7..d7d354d 100644 --- a/src/decomp/expr/access.c +++ b/src/decomp/expr/access.c @@ -239,7 +239,7 @@ static GBufferLine *g_access_expression_print(const GAccessExpression *expr, GCo result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->owner), buffer, line, output); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ".", 3, RTT_PUNCT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ".", 3, RTT_PUNCT, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->target), buffer, result, output); diff --git a/src/decomp/expr/arithm.c b/src/decomp/expr/arithm.c index f14086d..7314dde 100644 --- a/src/decomp/expr/arithm.c +++ b/src/decomp/expr/arithm.c @@ -276,7 +276,7 @@ static GBufferLine *g_arithm_expression_print(const GArithmExpression *expr, GCo break; } - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, sign, 3, RTT_SIGNS); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, sign, 3, RTT_SIGNS, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->op2), buffer, result, output); diff --git a/src/decomp/expr/array.c b/src/decomp/expr/array.c index d335f61..5c18c11 100644 --- a/src/decomp/expr/array.c +++ b/src/decomp/expr/array.c @@ -239,12 +239,12 @@ static GBufferLine *g_array_access_print(const GArrayAccess *expr, GCodeBuffer * result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->array), buffer, line, output); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "[", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "[", 1, RTT_RAW, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->index), buffer, result, output); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "]", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "]", 1, RTT_RAW, NULL); return result; diff --git a/src/decomp/expr/assign.c b/src/decomp/expr/assign.c index 9a5b308..f4ab149 100644 --- a/src/decomp/expr/assign.c +++ b/src/decomp/expr/assign.c @@ -239,7 +239,7 @@ static GBufferLine *g_assign_expression_print(const GAssignExpression *expr, GCo result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->dest), buffer, line, output); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " = ", 3, RTT_SIGNS); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " = ", 3, RTT_SIGNS, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->src), buffer, result, output); diff --git a/src/decomp/expr/call.c b/src/decomp/expr/call.c index 8382b6d..7a09c37 100644 --- a/src/decomp/expr/call.c +++ b/src/decomp/expr/call.c @@ -238,9 +238,9 @@ static GBufferLine *g_routine_call_print(const GRoutineCall *call, GCodeBuffer * size_t i; /* Boucle de parcours */ name = g_binary_routine_get_name(call->routine); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW, NULL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "(", 1, RTT_PUNCT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "(", 1, RTT_PUNCT, NULL); if (call->count > 0) { @@ -248,8 +248,8 @@ static GBufferLine *g_routine_call_print(const GRoutineCall *call, GCodeBuffer * for (i = 1; i < call->count; i++) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ",", 1, RTT_PUNCT); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); g_dec_instruction_print(call->args[i], buffer, result, output); @@ -258,7 +258,7 @@ static GBufferLine *g_routine_call_print(const GRoutineCall *call, GCodeBuffer * } else result = line; - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_PUNCT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_PUNCT, NULL); return result; diff --git a/src/decomp/expr/dalvik/array.c b/src/decomp/expr/dalvik/array.c index 018952a..7806349 100644 --- a/src/decomp/expr/dalvik/array.c +++ b/src/decomp/expr/dalvik/array.c @@ -148,8 +148,8 @@ static void g_dalvik_alength_print(const GDalvikALength *expr, GCodeBuffer *buff g_dec_instruction_print(G_DEC_INSTRUCTION(expr->array), buffer, line, output); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, ".", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ".", 1, RTT_RAW, NULL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "length", 6, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "length", 6, RTT_RAW, NULL); } diff --git a/src/decomp/expr/pseudo.c b/src/decomp/expr/pseudo.c index 85a9e72..0ee83b9 100644 --- a/src/decomp/expr/pseudo.c +++ b/src/decomp/expr/pseudo.c @@ -179,13 +179,13 @@ static GBufferLine *g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuf if (reg->var != NULL) { name = g_binary_variable_to_string(reg->var, true); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW, NULL); free(name); } else { snprintf(label, 32, "%s%zu", reg->name, reg->index); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_RAW, NULL); } return line; diff --git a/src/decomp/expr/return.c b/src/decomp/expr/return.c index b61eb39..8758042 100644 --- a/src/decomp/expr/return.c +++ b/src/decomp/expr/return.c @@ -226,11 +226,11 @@ static GBufferLine *g_return_expression_print(const GReturnExpression *expr, GCo { GBufferLine *result; /* Ligne à retourner */ - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "return", 6, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "return", 6, RTT_KEY_WORD, NULL); if (expr->payload != NULL) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->payload), buffer, line, output); diff --git a/src/decomp/expr/text.c b/src/decomp/expr/text.c index 9991b85..d4d5f85 100644 --- a/src/decomp/expr/text.c +++ b/src/decomp/expr/text.c @@ -150,9 +150,9 @@ GDecInstruction *g_str_expression_new(const char *value) static GBufferLine *g_str_expression_print(const GStrExpression *expr, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "\"", 1, RTT_STRING); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, expr->value, expr->len, RTT_STRING); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "\"", 1, RTT_STRING); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "\"", 1, RTT_STRING, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, expr->value, expr->len, RTT_STRING, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "\"", 1, RTT_STRING, NULL); return line; diff --git a/src/decomp/expression.c b/src/decomp/expression.c index e8bdbd9..ff2c0da 100644 --- a/src/decomp/expression.c +++ b/src/decomp/expression.c @@ -98,7 +98,7 @@ static GBufferLine *g_dec_expression_neg_print(const GDecExpression *expr, GCode { GBufferLine *result; /* Ligne à retourner */ - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "!", 1, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "!", 1, RTT_KEY_WORD, NULL); result = expr->original_print(G_DEC_INSTRUCTION(expr), buffer, line, output); diff --git a/src/decomp/instr/ite.c b/src/decomp/instr/ite.c index eedd7b4..b6391d5 100644 --- a/src/decomp/instr/ite.c +++ b/src/decomp/instr/ite.c @@ -241,7 +241,7 @@ static GBufferLine *g_ite_instruction_print(const GITEInstruction *instr, GCodeB { GBufferLine *result; /* Ligne à retourner */ - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "if ", 3, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "if ", 3, RTT_KEY_WORD, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(instr->cond), buffer, line, output); @@ -250,7 +250,7 @@ static GBufferLine *g_ite_instruction_print(const GITEInstruction *instr, GCodeB if (instr->false_branch != NULL) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "else", 4, RTT_KEY_WORD); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "else", 4, RTT_KEY_WORD, NULL); result = g_dec_instruction_print(instr->false_branch, buffer, result, output); } diff --git a/src/decomp/instr/keyword.c b/src/decomp/instr/keyword.c index 3ed12fb..aec6897 100644 --- a/src/decomp/instr/keyword.c +++ b/src/decomp/instr/keyword.c @@ -148,11 +148,11 @@ static GBufferLine *g_keyword_instruction_print(const GKeywordInstruction *instr switch (instr->keyword) { case DKW_BREAK: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "break", 5, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "break", 5, RTT_KEY_WORD, NULL); break; case DKW_CONTINUE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "continue", 8, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "continue", 8, RTT_KEY_WORD, NULL); break; } diff --git a/src/decomp/instr/switch.c b/src/decomp/instr/switch.c index a01c28c..eb93bb2 100644 --- a/src/decomp/instr/switch.c +++ b/src/decomp/instr/switch.c @@ -246,17 +246,17 @@ static GBufferLine *g_switch_instruction_print(const GSwitchInstruction *instr, size_t i; /* Boucle de parcours #1 */ size_t j; /* Boucle de parcours #2 */ - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "switch", 9, RTT_KEY_WORD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "switch", 9, RTT_KEY_WORD, NULL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "(", 1, RTT_PUNCT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "(", 1, RTT_PUNCT, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(instr->value), buffer, line, output); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_PUNCT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_PUNCT, NULL); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK, NULL); g_code_buffer_inc_indentation(buffer); @@ -268,13 +268,13 @@ static GBufferLine *g_switch_instruction_print(const GSwitchInstruction *instr, { result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "case", 4, RTT_KEY_WORD); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "case", 4, RTT_KEY_WORD, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); result = g_dec_instruction_print(G_DEC_INSTRUCTION(instr->cases[i].values[j]) , buffer, result, output); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL); } @@ -288,8 +288,8 @@ static GBufferLine *g_switch_instruction_print(const GSwitchInstruction *instr, { result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "default", 7, RTT_KEY_WORD); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "default", 7, RTT_KEY_WORD, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL); result = g_dec_instruction_print(instr->def_case, buffer, result, output); @@ -301,7 +301,7 @@ static GBufferLine *g_switch_instruction_print(const GSwitchInstruction *instr, result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK, NULL); return result; diff --git a/src/decomp/lang/asm.c b/src/decomp/lang/asm.c index bafef2e..069d0c4 100644 --- a/src/decomp/lang/asm.c +++ b/src/decomp/lang/asm.c @@ -165,10 +165,10 @@ static GBufferLine *g_asm_output_write_comments(GAsmOutput *output, GCodeBuffer result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_COMMENTS, "; ", 2, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, "; ", 2, RTT_COMMENT, NULL); if (length > 0) - g_buffer_line_insert_text(result, BLC_COMMENTS, text, length, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, text, length, RTT_COMMENT, NULL); return result; @@ -191,34 +191,34 @@ static GBufferLine *g_asm_output_write_comments(GAsmOutput *output, GCodeBuffer static void g_asm_output_write_comp_sign(GAsmOutput *output, GBufferLine *line, CompSignType sign) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); switch (sign) { case CST_EQ: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "==", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "==", 2, RTT_SIGNS, NULL); break; case CST_NE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "!=", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "!=", 2, RTT_SIGNS, NULL); break; case CST_LT: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "<", 1, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "<", 1, RTT_SIGNS, NULL); break; case CST_GE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ">=", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ">=", 2, RTT_SIGNS, NULL); break; case CST_GT: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ">", 1, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ">", 1, RTT_SIGNS, NULL); break; case CST_LE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "<=", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "<=", 2, RTT_SIGNS, NULL); break; default: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "?", 1, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "?", 1, RTT_SIGNS, NULL); break; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); } @@ -242,7 +242,7 @@ static GBufferLine *g_asm_output_start_routine_info(const GAsmOutput *output, GC result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL); return result; @@ -270,7 +270,7 @@ static GBufferLine *g_asm_output_start_routine_prototype(GAsmOutput *output, GCo result = g_code_buffer_append_new_line_fixme(buffer); /* TODO */ - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "XXX", 3, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "XXX", 3, RTT_COMMENT, NULL); return result; @@ -293,6 +293,6 @@ static GBufferLine *g_asm_output_start_routine_prototype(GAsmOutput *output, GCo static void g_asm_output_end_routine_prototype(GAsmOutput *output, GCodeBuffer *buffer, GBufferLine *line) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ";", 1, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ";", 1, RTT_COMMENT, NULL); } diff --git a/src/decomp/lang/java.c b/src/decomp/lang/java.c index d3db691..f8954a8 100644 --- a/src/decomp/lang/java.c +++ b/src/decomp/lang/java.c @@ -204,7 +204,7 @@ static GBufferLine *g_java_output_start_comments(GJavaOutput *output, GCodeBuffe result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_COMMENTS, "/**", 3, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, "/**", 3, RTT_COMMENT, NULL); return result; @@ -232,10 +232,10 @@ static GBufferLine *g_java_output_continue_comments(GJavaOutput *output, GCodeBu result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_COMMENTS, " * ", 3, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, " * ", 3, RTT_COMMENT, NULL); if (length > 0) - g_buffer_line_insert_text(result, BLC_COMMENTS, text, length, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, text, length, RTT_COMMENT, NULL); return result; @@ -261,7 +261,7 @@ static GBufferLine *g_java_output_end_comments(GJavaOutput *output, GCodeBuffer result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_COMMENTS, " */", 3, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, " */", 3, RTT_COMMENT, NULL); return result; @@ -289,10 +289,10 @@ static GBufferLine *g_java_output_write_comments(GJavaOutput *output, GCodeBuffe result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_COMMENTS, "// ", 3, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, "// ", 3, RTT_COMMENT, NULL); if (length > 0) - g_buffer_line_insert_text(result, BLC_COMMENTS, text, length, RTT_COMMENT); + g_buffer_line_append_text(result, BLC_COMMENTS, text, length, RTT_COMMENT, NULL); return result; @@ -315,34 +315,34 @@ static GBufferLine *g_java_output_write_comments(GJavaOutput *output, GCodeBuffe static void g_java_output_write_comp_sign(GJavaOutput *output, GBufferLine *line, CompSignType sign) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); switch (sign) { case CST_EQ: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "==", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "==", 2, RTT_SIGNS, NULL); break; case CST_NE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "!=", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "!=", 2, RTT_SIGNS, NULL); break; case CST_LT: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "<", 1, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "<", 1, RTT_SIGNS, NULL); break; case CST_GE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ">=", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ">=", 2, RTT_SIGNS, NULL); break; case CST_GT: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ">", 1, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ">", 1, RTT_SIGNS, NULL); break; case CST_LE: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "<=", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "<=", 2, RTT_SIGNS, NULL); break; default: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "?", 1, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "?", 1, RTT_SIGNS, NULL); break; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); } @@ -363,22 +363,22 @@ static void g_java_output_write_comp_sign(GJavaOutput *output, GBufferLine *line static void g_java_output_write_cond_operator(GLangOutput *output, GBufferLine *line, CondOperatorType op) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); switch (op) { case COT_AND: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "&&", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "&&", 2, RTT_SIGNS, NULL); break; case COT_OR: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "||", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "||", 2, RTT_SIGNS, NULL); break; default: - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "??", 2, RTT_SIGNS); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "??", 2, RTT_SIGNS, NULL); break; } - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); } @@ -404,15 +404,15 @@ static GBufferLine *g_java_output_start_class(GJavaOutput *output, GCodeBuffer * result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "class", 5, RTT_KEY_WORD); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "class", 5, RTT_KEY_WORD, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); name = _g_data_type_to_string(type, true); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW, NULL); free(name); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK, NULL); result = g_code_buffer_append_new_line_fixme(buffer); @@ -444,7 +444,7 @@ static void g_java_output_end_class(GJavaOutput *output, GCodeBuffer *buffer) result = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK, NULL); result = g_code_buffer_append_new_line_fixme(buffer); @@ -474,7 +474,7 @@ static GBufferLine *g_java_output_start_routine_prototype(GJavaOutput *output, G result = g_code_buffer_append_new_line_fixme(buffer); /* TODO */ - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "XXX", 3, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "XXX", 3, RTT_RAW, NULL); return result; @@ -497,7 +497,7 @@ static GBufferLine *g_java_output_start_routine_prototype(GJavaOutput *output, G static void g_java_output_end_routine_prototype(GJavaOutput *output, GCodeBuffer *buffer, GBufferLine *line) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ";", 1, RTT_PUNCT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ";", 1, RTT_PUNCT, NULL); } @@ -519,8 +519,8 @@ static void g_java_output_end_routine_prototype(GJavaOutput *output, GCodeBuffer static void g_java_output_start_routine_body(GJavaOutput *output, GCodeBuffer *buffer, GBufferLine *line) { /* - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK, NULL); g_code_buffer_inc_indentation(buffer); */ @@ -548,7 +548,7 @@ static void g_java_output_end_routine_body(GJavaOutput *output, GCodeBuffer *buf line = g_code_buffer_append_new_line_fixme(buffer); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK, NULL); */ } @@ -574,8 +574,8 @@ static GBufferLine *g_java_output_start_code_block(GJavaOutput *output, GCodeBuf if (count > 1) { - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "{", 1, RTT_HOOK, NULL); } g_code_buffer_inc_indentation(buffer); @@ -612,8 +612,8 @@ static GBufferLine *g_java_output_end_code_block(GJavaOutput *output, GCodeBuffe if (count > 1) { - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK); - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "}", 1, RTT_HOOK, NULL); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW, NULL); } return result; @@ -643,9 +643,9 @@ static GBufferLine *g_java_output_encapsulate_condition(GLangOutput *output, GCo result = line; if (opening) - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "(", 1, RTT_HOOK); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "(", 1, RTT_HOOK, NULL); else - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_HOOK); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_HOOK, NULL); return result; diff --git a/src/format/dex/class.c b/src/format/dex/class.c index 454cc40..a507e39 100644 --- a/src/format/dex/class.c +++ b/src/format/dex/class.c @@ -534,7 +534,7 @@ GBufferLine *line, GLangOutput *output) type = get_type_from_dex_pool(format, class->definition.class_idx); - //g_buffer_line_insert_text(line, BLC_ASSEMBLY, "{", 3, RTT_SIGNS); + //g_buffer_line_append_text(line, BLC_ASSEMBLY, "{", 3, RTT_SIGNS, NULL); //printf("Output :: %s\n", _g_data_type_to_string(type, true)); diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index a88b7d9..aa7a9a3 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -10,11 +10,12 @@ libglibext_la_SOURCES = \ delayed.h delayed.c \ gbinportion.h gbinportion.c \ gbufferline.h gbufferline.c \ - gbuffersegment.h gbuffersegment.c \ gbufferview.h gbufferview.c \ gcodebuffer.h gcodebuffer.c \ gnhash.h gnhash.c \ gwidthtracker.h gwidthtracker.c \ + linecolumn.h linecolumn.c \ + linesegment.h linesegment.c \ proto.h \ signal.h signal.c diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index 454fc6b..4851a08 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -549,8 +549,8 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, - "; ======================================================", 56, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, + "; ======================================================", 56, RTT_COMMENT, NULL); g_code_buffer_append_new_line(buffer, line); @@ -560,7 +560,7 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL); g_code_buffer_append_new_line(buffer, line); @@ -571,9 +571,9 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT, NULL); snprintf(rights, sizeof(rights), " (%s%s%s%s)", _("rights: "), @@ -581,7 +581,7 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem portion->rights & PAC_WRITE ? "w" : "-", portion->rights & PAC_EXEC ? "x" : "-"); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT, NULL); g_code_buffer_append_new_line(buffer, line); @@ -591,7 +591,7 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem g_buffer_line_fill_mrange(line, msize, msize); g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL); g_code_buffer_append_new_line(buffer, line); diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index a33817b..d03dfaf 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -27,84 +27,18 @@ #include #include #include -#include /* Récupération du langage par défaut ; FIXME ? */ #include "chrysamarshal.h" +#include "linecolumn.h" #include "../common/extstr.h" #include "../gtkext/support.h" -/* ---------------------------- REGROUPEMENT PAR COLONNE ---------------------------- */ - - -/* Informations sur le contenu d'une colonne */ -typedef struct _buffer_line_column -{ - GBufferSegment **segments; - size_t count; - - int max_width; /* Largeur max. de l'espace */ - -} buffer_line_column; - - -/* Réinitialise une colonne de ligne. */ -static void reset_column(buffer_line_column *); - -/* Recalcule la largeur d'une colonne de segments. */ -static void refresh_column_width(buffer_line_column *); - -/* Fournit la quantité de pixels requise pour l'impression. */ -static gint get_column_width(const buffer_line_column *); - -/* Ajoute un fragment de texte à une colonne de ligne. */ -static void add_segment_to_column(buffer_line_column *, GBufferSegment *) __attribute__ ((deprecated)); - -/* Ajoute un fragment de texte à une colonne de ligne. */ -static size_t append_text_to_line_column(buffer_line_column *, const char *, size_t, RenderingTagType); - -/* Valide ou non la présence d'un segment dans une colonne. */ -static bool column_has_segment(const buffer_line_column *, const GBufferSegment *, size_t *); - -/* Indique l'indice du premier contenu de la colonne. */ -static bool get_column_first_content_index(const buffer_line_column *, size_t *); - -/* Indique l'indice du dernier contenu de la colonne. */ -static bool get_column_last_content_index(const buffer_line_column *, size_t *); - -#define get_first_segment(col) ((col)->count > 0 ? (col)->segments[0] : NULL) -#define get_last_segment(col) ((col)->count > 0 ? (col)->segments[(col)->count - 1] : NULL) - -/* Indique l'indice du contenu de colonne à une abscisse donnée. */ -static bool get_column_content_index_at(const buffer_line_column *, gint *, GdkScrollDirection, gint *, size_t *); - -/* Donne le segment d'une colonne présent à un indice donné. */ -static GBufferSegment *get_column_content_from_index(const buffer_line_column *, size_t); - -/* Fournit le segment voisin d'un autre segment identifié. */ -static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection); - -/* Imprime le contenu d'une colonne de ligne de texte. */ -static void draw_segments_of_column(buffer_line_column *, cairo_t *, gint, gint, const segcnt_list *); - -/* Exporte la ligne de texte représentée. */ -static void export_segments_of_column(buffer_line_column *, buffer_export_context *, BufferExportType, int); - - - /* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */ -/* Identification d'un contenu de colonne */ -typedef struct _col_coord_t -{ - BufferLineColumn column; /* Colonne concernée */ - size_t index; /* Indice d'insertion */ - -} col_coord_t; - /* Mémorisation des origines de texte */ typedef struct _content_origin { @@ -122,7 +56,7 @@ struct _GBufferLine mrange_t range; /* Couverture geographique */ BufferLineColumn main_column; /* Colonne principale */ - buffer_line_column columns[BLC_COUNT]; /* Répartition du texte */ + line_column columns[BLC_COUNT]; /* Répartition du texte */ BufferLineColumn merge_start; /* Début de la zone globale */ BufferLineColumn last_used; /* Dernière colonne utilisée */ @@ -153,7 +87,7 @@ struct _GBufferLineClass /* Signaux */ - void (* content_changed) (GBufferLine *, GBufferSegment *); + void (* content_changed) (GBufferLine *, line_segment *); void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags); @@ -172,465 +106,6 @@ static void g_buffer_line_dispose(GBufferLine *); /* Procède à la libération totale de la mémoire. */ static void g_buffer_line_finalize(GBufferLine *); -/* Réagit au changement de contenu d'un segment encapsulé. */ -static void on_line_segment_changed(GBufferSegment *, GBufferLine *); - -/* Fournit les coordonnées correspondant à une abscisse donnée. */ -static bool g_buffer_line_get_coord_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool, col_coord_t *); - - - -/* ---------------------------------------------------------------------------------- */ -/* REGROUPEMENT PAR COLONNE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne à mettre à jour. * -* * -* Description : Réinitialise une colonne de ligne. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void reset_column(buffer_line_column *column) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < column->count; i++) - g_object_unref(G_OBJECT(column->segments[i])); - - if (column->segments != NULL) - { - free(column->segments); - column->segments = NULL; - } - - column->count = 0; - - column->max_width = 0; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne à mettre à jour. * -* * -* Description : Recalcule la largeur d'une colonne de segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void refresh_column_width(buffer_line_column *column) -{ - size_t i; /* Boucle de parcours */ - - column->max_width = 0; - - for (i = 0; i < column->count; i++) - column->max_width += g_buffer_segment_get_width(column->segments[i]); - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne à consulter. * -* * -* Description : Fournit la quantité de pixels requise pour l'impression. * -* * -* Retour : Largeur requise par la colonne, en pixel. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static gint get_column_width(const buffer_line_column *column) -{ - return column->max_width; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne à venir compléter. * -* segment = fragment de texte à ajouter à la colonne. * -* * -* Description : Ajoute un fragment de texte à une colonne de ligne. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void add_segment_to_column(buffer_line_column *column, GBufferSegment *segment) -{ - - /* FIXME : à remplacer */ - - - column->segments = (GBufferSegment **)realloc(column->segments, ++column->count * sizeof(GBufferSegment *)); - - - column->segments[column->count - 1] = segment; - - - column->max_width += g_buffer_segment_get_width(segment); - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne à venir compléter. * -* text = texte à insérer dans l'existant. * -* length = taille du texte à traiter. * -* type = type de décorateur à utiliser. * -* * -* Description : Ajoute un fragment de texte à une colonne de ligne. * -* * -* Retour : Indice du point d'insertion. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t append_text_to_line_column(buffer_line_column *column, const char *text, size_t length, RenderingTagType type) -{ - size_t result; /* Indice à retourner */ - GBufferSegment *content; /* Contenu à représenter */ - - result = column->count; - - content = g_buffer_segment_new(type, text, length); - - column->segments = (GBufferSegment **)realloc(column->segments, ++column->count * sizeof(GBufferSegment *)); - - column->segments[result] = content; - - column->max_width += g_buffer_segment_get_width(content); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne à venir consulter. * -* segment = fragment de texte à trouver dans la colonne. * -* index = indice du segment retrouvé ou NULL. [OUT] * -* * -* Description : Valide ou non la présence d'un segment dans une colonne. * -* * -* Retour : Statut de présence du segment indiqué. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool column_has_segment(const buffer_line_column *column, const GBufferSegment *segment, size_t *index) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < column->count; i++) - if (column->segments[i] == segment) - { - if (index != NULL) *index = i; - break; - } - - return (i < column->count); - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à consulter. * -* index = indice du contenu enregistré à la position. [OUT] * -* * -* Description : Indique l'indice du premier contenu de la colonne. * -* * -* Retour : Validité de l'indice renseigné. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool get_column_first_content_index(const buffer_line_column *column, size_t *index) -{ - bool result; /* Bilan à retourner */ - - result = (column->count > 0); - - if (result) - *index = 0; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à consulter. * -* index = indice du contenu enregistré à la position. [OUT] * -* * -* Description : Indique l'indice du dernier contenu de la colonne. * -* * -* Retour : Validité de l'indice renseigné. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool get_column_last_content_index(const buffer_line_column *column, size_t *index) -{ - bool result; /* Bilan à retourner */ - - result = (column->count > 0); - - if (result) - *index = column->count - 1; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à consulter. * -* x = position de recherche, puis position locale. [OUT]* -* dir = direction d'un éventuel déplacement en cours. * -* consumed = distance pour arriver à la base du segment. [OUT] * -* index = indice du contenu enregistré à la position. [OUT] * -* * -* Description : Indique l'indice du contenu de colonne à une abscisse donnée.* -* * -* Retour : Validité de l'indice renseigné. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool get_column_content_index_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir, gint *consumed, size_t *index) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - gint width; /* Largeur à retirer */ - bool included; /* Appartenance à une largeur ?*/ - - result = false; - *consumed = 0; - - for (i = 0; i < column->count && !result; i++) - { - width = g_buffer_segment_get_width(column->segments[i]); - - /** - * Soit une limite entre deux segments A et B : - * - * - dans le cas d'un déplacement vers la gauche, on part de cette limite - * pour progresser à l'intérieur de A. Donc la limite fait partie de A. - * - * - dans le cas d'un déplacement vers la droite, on part de cette limite - * pour progresser à l'intérieur de B. Donc la limite ne fait pas partie de A. - */ - if (dir == GDK_SCROLL_LEFT) included = (width >= *x); - else included = (width > *x); - - if (included) - { - *index = i; - result = true; - } - - else if ((i + 1) == column->count) - { - *index = i; - result = true; - *x = width; - } - - else - { - *x -= width; - *consumed += width; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à consulter. * -* index = indice du contenu à fournir. * -* * -* Description : Donne le segment d'une colonne présent à un indice donné. * -* * -* Retour : Segment trouvé ou NULL si hors borne. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBufferSegment *get_column_content_from_index(const buffer_line_column *column, size_t index) -{ - GBufferSegment *result; /* Trouvaille à retourner */ - - assert(index < column->count); - - result = column->segments[index]; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à consulter. * -* target = segment dont un voisin est à retourner. * -* dir = orientation des recherches. * -* * -* Description : Fournit le segment voisin d'un autre segment identifié. * -* * -* Retour : Segment trouvé ou NULL si hors borne ou inconnu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir) -{ - GBufferSegment *result; /* Trouvaille à retourner */ - bool found; /* Le segment est bien présent */ - size_t i; /* Boucle de parcours */ - - result = NULL; - - found = column_has_segment(column, target, &i); - - if (found) - switch (dir) - { - case GDK_SCROLL_LEFT: - if (i > 0) - result = column->segments[i - 1]; - break; - - case GDK_SCROLL_RIGHT: - if ((i + 1) < column->count) - result = column->segments[i + 1]; - break; - - default: - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à manipuler. * -* cairo = contexte graphique à utiliser pour les pinceaux. * -* x_init = abscisse du point d'impression de départ. * -* y = ordonnée du point d'impression. * -* list = liste de contenus à mettre en évidence. * -* * -* Description : Imprime le contenu d'une colonne de ligne de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void draw_segments_of_column(buffer_line_column *column, cairo_t *cairo, gint x_init, gint y, const segcnt_list *list) -{ - gint x; /* Abscisse d'impression */ - size_t i; /* Boucle de parcours */ - - x = x_init; - - for (i = 0; i < column->count; i++) - g_buffer_segment_draw(column->segments[i], cairo, &x, y, list); - -} - - -/****************************************************************************** -* * -* Paramètres : column = colonne de ligne de texte à manipuler. * -* ctx = éléments à disposition pour l'exportation. * -* type = type d'exportation attendue. * -* span = fusion de colonnes au sein des cellules ? * -* * -* Description : Exporte la ligne de texte représentée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void export_segments_of_column(buffer_line_column *column, buffer_export_context *ctx, BufferExportType type, int span) -{ - size_t i; /* Boucle de parcours */ - - switch (type) - { - case BET_HTML: - switch (span) - { - case 0: - break; - case 1: - dprintf(ctx->fd, "\t\t"); - break; - default: - if (span > 0) dprintf(ctx->fd, "\t\t", span); - break; - } - break; - default: - break; - } - - for (i = 0; i < column->count; i++) - g_buffer_segment_export(column->segments[i], ctx, type); - - switch (type) - { - case BET_HTML: - if (span < 0 || span == 1) dprintf(ctx->fd, "\n"); - break; - default: - break; - } - -} - /* ---------------------------------------------------------------------------------- */ @@ -715,7 +190,7 @@ static void g_buffer_line_init(GBufferLine *line) BufferLineColumn i; /* Boucle de parcours */ for (i = 0; i < BLC_COUNT; i++) - reset_column(&line->columns[i]); + init_line_column(&line->columns[i]); line->merge_start = BLC_COUNT; line->last_used = BLC_COUNT; @@ -851,16 +326,16 @@ void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDa if (address[i] != '0') break; if (i == len) - g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_PHYS_ADDR_PAD); + g_buffer_line_append_text(line, BLC_PHYSICAL, address, len, RTT_PHYS_ADDR_PAD, NULL); else { - g_buffer_line_insert_text(line, BLC_PHYSICAL, address, 2, RTT_PHYS_ADDR); + g_buffer_line_append_text(line, BLC_PHYSICAL, address, 2, RTT_PHYS_ADDR, NULL); if (i > 2) - g_buffer_line_insert_text(line, BLC_PHYSICAL, &address[2], i - 2, RTT_PHYS_ADDR_PAD); + g_buffer_line_append_text(line, BLC_PHYSICAL, &address[2], i - 2, RTT_PHYS_ADDR_PAD, NULL); - g_buffer_line_insert_text(line, BLC_PHYSICAL, &address[i], len - i, RTT_PHYS_ADDR); + g_buffer_line_append_text(line, BLC_PHYSICAL, &address[i], len - i, RTT_PHYS_ADDR, NULL); } @@ -876,16 +351,16 @@ void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDa if (address[i] != '0') break; if (i == len) - g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_VIRT_ADDR_PAD); + g_buffer_line_append_text(line, BLC_VIRTUAL, address, len, RTT_VIRT_ADDR_PAD, NULL); else { - g_buffer_line_insert_text(line, BLC_VIRTUAL, address, 2, RTT_VIRT_ADDR); + g_buffer_line_append_text(line, BLC_VIRTUAL, address, 2, RTT_VIRT_ADDR, NULL); if (i > 2) - g_buffer_line_insert_text(line, BLC_VIRTUAL, &address[2], i - 2, RTT_VIRT_ADDR_PAD); + g_buffer_line_append_text(line, BLC_VIRTUAL, &address[2], i - 2, RTT_VIRT_ADDR_PAD, NULL); - g_buffer_line_insert_text(line, BLC_VIRTUAL, &address[i], len - i, RTT_VIRT_ADDR); + g_buffer_line_append_text(line, BLC_VIRTUAL, &address[i], len - i, RTT_VIRT_ADDR, NULL); } @@ -987,7 +462,7 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor /* Conclusion */ - g_buffer_line_insert_text(line, BLC_BINARY, bin_code, iter - bin_code, RTT_RAW_CODE); + g_buffer_line_append_text(line, BLC_BINARY, bin_code, iter - bin_code, RTT_RAW_CODE, NULL); if (bin_code != static_buffer) free(bin_code); @@ -1033,91 +508,12 @@ GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *line, Buffe /****************************************************************************** * * -* Paramètres : line = ligne à venir consulter. * -* creator = créateur à l'origine du segment recherché. * -* * -* Description : Fournit le segment créé par un objet particulier. * -* * -* Retour : Segment trouvé dans la ligne ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *line, GObject *creator) -{ - GBufferSegment *result; /* Trouvaille à retourner */ - size_t i; /* Boucle de parcours */ - const col_coord_t *coord; /* Emplacement du contenu visé */ - - result = NULL; - - for (i = 0; i < line->ocount; i++) - { - if (line->origins[i].creator == creator) - { - coord = &line->origins[i].coord; - - result = get_column_content_from_index(&line->columns[coord->column], coord->index); - - break; - - } - - } - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = segment de texte dont le contenu vient de changer. * -* line = ligne contenant ce segment. * -* * -* Description : Réagit au changement de contenu d'un segment encapsulé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void on_line_segment_changed(GBufferSegment *segment, GBufferLine *line) -{ - BufferLineColumn i; /* Boucle de parcours */ - buffer_line_column *column; - - /* Actualisation de la largeur de la colonne */ - - for (i = 0; i < BLC_COUNT; i++) - { - column = &line->columns[i]; - - if (column_has_segment(column, segment, NULL)) - { - refresh_column_width(column); - break; - } - - } - - g_signal_emit_by_name(line, "content-changed", segment); - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne à venir compléter. * -* column = colonne de la ligne visée par l'insertion. * -* text = texte à insérer dans l'existant. * -* length = taille du texte à traiter. * -* type = type de décorateur à utiliser. * +* Paramètres : line = ligne à venir compléter. * +* column = colonne de la ligne visée par l'insertion. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* type = type de décorateur à utiliser. * +* creator = instance GLib quelconque à associer. * * * * Description : Ajoute du texte à formater dans une ligne donnée. * * * @@ -1127,9 +523,10 @@ static void on_line_segment_changed(GBufferSegment *segment, GBufferLine *line) * * ******************************************************************************/ -GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type) +void g_buffer_line_append_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type, GObject *creator) { - GBufferSegment *result; /* Portion de texte à renvoyer */ + size_t index; /* Indice d'insertion */ + content_origin *origin; /* Définition d'une origine */ assert(length > 0); @@ -1141,13 +538,21 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co else line->last_used = column; - result = g_buffer_segment_new(type, text, length); + index = append_text_to_line_column(&line->columns[column], text, length, type); - add_segment_to_column(&line->columns[column], result); + if (creator != NULL) + { + line->origins = (content_origin *)realloc(line->origins, ++line->ocount * sizeof(content_origin)); - g_signal_connect(result, "content-changed", G_CALLBACK(on_line_segment_changed), line); + origin = &line->origins[line->ocount - 1]; - return result; + origin->coord.column = column; + origin->coord.index = index; + + origin->creator = creator; + g_object_ref(G_OBJECT(creator)); + + } } @@ -1155,51 +560,44 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co /****************************************************************************** * * * Paramètres : line = ligne à venir compléter. * -* column = colonne de la ligne visée par l'insertion. * +* creator = instance GLib quelconque identifiant un segment. * * text = texte à insérer dans l'existant. * * length = taille du texte à traiter. * -* type = type de décorateur à utiliser. * -* creator = instance GLib quelconque à associer. * * * -* Description : Ajoute du texte à formater dans une ligne donnée. * +* Description : Remplace du texte dans une ligne donnée. * * * -* Retour : Portion de texte mis en place, voire NULL. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -void g_buffer_line_append_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type, GObject *creator) +bool g_buffer_line_replace_text(GBufferLine *line, const GObject *creator, const char *text, size_t length) { - size_t index; /* Indice d'insertion */ - content_origin *origin; /* Définition d'une origine */ - - assert(length > 0); - - if (column == BLC_MAIN) - column = line->main_column; - - if (column == BLC_LAST_USED) - column = line->last_used; - else - line->last_used = column; + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + const col_coord_t *coord; /* Emplacement du contenu visé */ - index = append_text_to_line_column(&line->columns[column], text, length, type); + result = false; - if (creator != NULL) + for (i = 0; i < line->ocount && !result; i++) { - line->origins = (content_origin *)realloc(line->origins, ++line->ocount * sizeof(content_origin)); + if (line->origins[i].creator == creator) + { + coord = &line->origins[i].coord; - origin = &line->origins[line->ocount - 1]; + replace_text_in_line_column(&line->columns[coord->column], coord->index, text, length); - origin->coord.column = column; - origin->coord.index = index; + g_signal_emit_by_name(line, "content-changed", NULL); - origin->creator = creator; - g_object_ref(G_OBJECT(creator)); + result = true; + + } } + return result; + } @@ -1267,7 +665,7 @@ char *g_buffer_line_get_text(const GBufferLine *line, BufferLineColumn first, Bu for (j = 0; j < line->columns[i].count; j++) { - extra = g_buffer_segment_get_text(line->columns[i].segments[j], markup); + extra = get_line_segment_text(line->columns[i].segments[j], markup); if (result == NULL) result = extra; @@ -1307,7 +705,7 @@ void g_buffer_line_delete_text(GBufferLine *line, BufferLineColumn first, Buffer assert(first < end); for (i = first; i < end; i++) - reset_column(&line->columns[i]); + reset_line_column(&line->columns[i]); } @@ -1469,7 +867,7 @@ void g_buffer_line_export(GBufferLine *line, buffer_export_context *ctx, BufferE /** * Pour la signification des différentes valeurs assignées, - * se référer au code de export_segments_of_column(). + * se référer au code de export_line_column_segments(). * * En gros : * - 1 = rien de spécial. @@ -1490,7 +888,7 @@ void g_buffer_line_export(GBufferLine *line, buffer_export_context *ctx, BufferE else col_span = ((i + 1) == BLC_COUNT ? -1 : 0); - export_segments_of_column(&line->columns[i], ctx, type, col_span); + export_line_column_segments(&line->columns[i], ctx, type, col_span); } @@ -1591,6 +989,32 @@ gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn i } + + +/****************************************************************************** +* * +* Paramètres : line = ligne à venir consulter. * +* coord = coordonnées interne du segment à retrouver. * +* * +* Description : Fournit le segment présent à une position donnée. * +* * +* Retour : Segment trouvé ou NULL si hors borne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *line, const col_coord_t *coord) +{ + line_segment *result; /* Trouvaille à retourner */ + + result = get_line_column_content_from_index(&line->columns[coord->column], coord->index); + + return result; + +} + + /****************************************************************************** * * * Paramètres : line = ligne à venir consulter. * @@ -1610,7 +1034,7 @@ gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn i * * ******************************************************************************/ -static bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force, col_coord_t *coord) +bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force, col_coord_t *coord) { bool result; /* Bilan à retourner */ BufferLineColumn last; /* Dernière colonne remplie */ @@ -1687,7 +1111,7 @@ static bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width */ if (*offset < 0) *offset = 0; - result = get_column_content_index_at(&line->columns[i], offset, dir, &consumed, &coord->index); + result = get_line_column_content_index_at(&line->columns[i], offset, dir, &consumed, &coord->index); if (result) { @@ -1720,7 +1144,7 @@ static bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width else *base += get_column_width(&line->columns[i - 1]); - result = get_column_first_content_index(&line->columns[i], &coord->index); + result = get_line_column_first_content_index(&line->columns[i], &coord->index); if (result) coord->column = i; @@ -1747,7 +1171,7 @@ static bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width if (last != BLC_COUNT) { - result = get_column_last_content_index(&line->columns[last], &coord->index); + result = get_line_column_last_content_index(&line->columns[last], &coord->index); if (result) { @@ -1791,16 +1215,16 @@ static bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width * * ******************************************************************************/ -GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force) +const line_segment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force) { - GBufferSegment *result; /* Trouvaille à retourner */ + const line_segment *result; /* Trouvaille à retourner */ col_coord_t coord; /* Emplacement du contenu visé */ bool status; /* Bilan de la localisation */ status = g_buffer_line_get_coord_at(line, summary, display, base, offset, dir, force, &coord); if (status) - result = get_column_content_from_index(&line->columns[coord.column], coord.index); + result = g_buffer_line_get_segment_from_coord(line, &coord); return result; @@ -1861,43 +1285,40 @@ GObject *g_buffer_line_get_creator_at(const GBufferLine *line, const line_width_ /****************************************************************************** * * * Paramètres : line = ligne à venir consulter. * -* target = segment dont un voisin est à retourner. * +* coord = cordonnées à consulter puis renseigner. [OUT] * * summary = résumé des largeurs maximales. * * display = règles d'affichage des colonnes modulables. * * dir = orientation des recherches. * * offset = décalage pour amener à l'extrémité nouvelle. [OUT] * * * -* Description : Fournit le segment voisin d'un autre segment identifié. * +* Description : Fournit des coordonnées voisines selon une direction donnée. * * * -* Retour : Segment trouvé dans la ligne ou NULL. * +* Retour : true si des coordonnées valides ont été renseignées. * * * * Remarques : - * * * ******************************************************************************/ -GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBufferSegment *target, const line_width_summary *summary, const bool *display, GdkScrollDirection dir, gint *offset) +bool g_buffer_line_find_near_coord(const GBufferLine *line, col_coord_t *coord, const line_width_summary *summary, const bool *display, GdkScrollDirection dir, gint *offset) { - GBufferSegment *result; /* Trouvaille à retourner */ + bool result; /* Bilan à retourner */ BufferLineColumn i; /* Boucle de parcours #1 */ bool displayed; /* Confort de lecture */ BufferLineColumn k; /* Boucle de parcours #2 */ - result = NULL; + result = false; /* Recherche dans la colonne de départ */ - for (i = 0; i < BLC_COUNT; i++) - if (column_has_segment(&line->columns[i], target, NULL)) - break; + i = coord->column; - if (i == BLC_COUNT) return NULL; + if (i == BLC_COUNT) return false; - result = find_near_segment(&line->columns[i], target, dir); - if (result != NULL) return result; + result = find_near_segment(&line->columns[i], &coord->index, dir); /* Recherche dans la direction des colonnes voisines */ - if (result == NULL) + if (!result) switch (dir) { case GDK_SCROLL_LEFT: @@ -1906,12 +1327,18 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBuffer if (i == 0) break; /* On s'assure que la colonne précédente est visible et peuplée */ - for (; i > BLC_FIRST && result == NULL; i--) + for (; i > BLC_FIRST && !result; i--) { displayed = (i <= BLC_DISPLAY ? display[i - 1] : true); if (displayed) - result = get_last_segment(&line->columns[i - 1]); + { + result = get_line_column_first_content_index(&line->columns[i - 1], &coord->index); + + if (result) + coord->column = i - 1; + + } } @@ -1919,16 +1346,19 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBuffer case GDK_SCROLL_RIGHT: - /* Si on a atteint la dernière colonne sans trouver... */ - /*if (i == BLC_COUNT) break;*/ - /* On s'assure que la colonne suivante est visible et peuplée */ - for (; (i + 1) < BLC_COUNT && result == NULL; i++) + for (; (i + 1) < BLC_COUNT && !result; i++) { displayed = ((i + 1) < BLC_DISPLAY ? display[i + 1] : true); if (displayed) - result = get_first_segment(&line->columns[i + 1]); + { + result = get_line_column_first_content_index(&line->columns[i + 1], &coord->index); + + if (result) + coord->column = i + 1; + + } } @@ -1941,7 +1371,7 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBuffer /* Calcul de la position finale */ - if (result != NULL) + if (result) { *offset = 0; @@ -2033,7 +1463,7 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const line_width_summ { if (i < BLC_DISPLAY && !display[i]) continue; - draw_segments_of_column(&line->columns[i], cairo, x, y, list); + draw_line_column_segments(&line->columns[i], cairo, x, y, list); if (i < line->merge_start) { diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 9403d80..b5d70b2 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -29,7 +29,7 @@ #include -#include "gbuffersegment.h" +#include "linesegment.h" #include "../analysis/content.h" #include "../arch/archbase.h" #include "../arch/vmpa.h" @@ -117,15 +117,12 @@ void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, /* Recherche le premier créateur enregistré dans des segments. */ GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *, BufferLineColumn); -/* Fournit le segment créé par un objet particulier. */ -GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *, GObject *); - -/* Ajoute du texte à formater dans une ligne donnée. */ -GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType) __attribute__ ((deprecated)); - /* Ajoute du texte à formater dans une ligne donnée. */ void g_buffer_line_append_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType, GObject *); +/* Remplace du texte dans une ligne donnée. */ +bool g_buffer_line_replace_text(GBufferLine *, const GObject *, const char *, size_t); + /* Indique si du texte est présent dans une ligne de tampon. */ bool g_buffer_line_has_text(const GBufferLine *, BufferLineColumn, BufferLineColumn); @@ -177,6 +174,14 @@ typedef struct _line_width_summary } line_width_summary; +/* Identification d'un contenu de colonne */ +typedef struct _col_coord_t +{ + BufferLineColumn column; /* Colonne concernée */ + size_t index; /* Indice d'insertion */ + +} col_coord_t; + /* Fait remonter les largeurs requises par une ligne donnée. */ void g_buffer_line_collect_widths(GBufferLine *, line_width_summary *); @@ -184,14 +189,20 @@ void g_buffer_line_collect_widths(GBufferLine *, line_width_summary *); /* Fournit la largeur d'une colonne finalement appliquée. */ gint g_buffer_line_compute_max_width(const GBufferLine *, BufferLineColumn, const line_width_summary *); +/* Fournit le segment présent à une position donnée. */ +const line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *, const col_coord_t *); + +/* Fournit les coordonnées correspondant à une abscisse donnée. */ +bool g_buffer_line_get_coord_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool, col_coord_t *); + /* Donne le segment présent à une abscisse donnée. */ -GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool); +const line_segment *g_buffer_line_get_segment_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool); /* Donne le créateur présent à une abscisse donnée. */ GObject *g_buffer_line_get_creator_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool); -/* Fournit le segment voisin d'un autre segment identifié. */ -GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *, GBufferSegment *, const line_width_summary *, const bool *, GdkScrollDirection, gint *); +/* Fournit des coordonnées voisines selon une direction donnée. */ +bool g_buffer_line_find_near_coord(const GBufferLine *, col_coord_t *, const line_width_summary *, const bool *, GdkScrollDirection, gint *); /* Imprime la ligne de texte représentée. */ void g_buffer_line_draw(GBufferLine *, cairo_t *, const line_width_summary *, gint, gint, const bool *, const segcnt_list *); diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c deleted file mode 100644 index dfa8c41..0000000 --- a/src/glibext/gbuffersegment.c +++ /dev/null @@ -1,1333 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gbuffersegment.c - concentration d'un fragment de caractères aux propriétés communes - * - * Copyright (C) 2010-2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "gbuffersegment.h" - - -#include -#include -#include -#include -#include -#include - - -#include "../common/extstr.h" -#include "../common/fnv1a.h" -#include "../gtkext/gtkblockview.h" -#include "../gtkext/support.h" - - - -/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ - - -/* Propriétés de rendu */ - -typedef struct _rendering_color_t -{ - GdkRGBA color; /* Couleur de rendu */ - bool has_color; /* Définition en place ? */ - -} rendering_color_t; - -typedef struct _rendering_pattern_t -{ - rendering_color_t foreground; /* Couleur d'impression */ - rendering_color_t inverted; /* Couleur inversée pour sél. */ - - cairo_font_slant_t slant; /* Style d'impression */ - cairo_font_weight_t weight; /* Poids de la police */ - -} rendering_pattern_t; - -/* Contenu brut pour segment, potentiellement commun */ -typedef struct _seg_content -{ - unsigned int ref_count; /* Compteur de références */ - - rendering_pattern_t *pattern; /* Propriétés du rendu */ - - fnv64_t hash; /* Empreinte pour comparaisons */ - char text[0]; /* Texte brut conservé */ - -} seg_content; - - -/* Conservation de toutes les créations partagées */ -static GHashTable *_segcnt_htable; - - -/* Fournit l'empreinte d'un contenu pour segments. */ -static guint get_seg_content_hash(const seg_content *); - -/* Détermine si deux contenus pour segments sont identiques. */ -static bool is_seg_content_equal(const seg_content *, const seg_content *); - -/* Détermine si deux contenus pour segments sont identiques. */ -static seg_content *get_shared_content(const seg_content *); - -/* Abandonne un contenu pour segments. */ -static void release_shared_content(seg_content *); - - - -/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ - - -/* Nom des éléments CSS */ - -#define SEGMENT_NAME(s) "segment-" s - -static const char *_segment_names[RTT_COUNT] = { - - [RTT_RAW] = SEGMENT_NAME("raw"), - [RTT_COMMENT] = SEGMENT_NAME("comment"), - [RTT_INDICATION] = SEGMENT_NAME("indication"), - [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), - [RTT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"), - [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), - [RTT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"), - [RTT_RAW_CODE] = SEGMENT_NAME("raw-code"), - [RTT_LABEL] = SEGMENT_NAME("label"), - [RTT_INSTRUCTION] = SEGMENT_NAME("instruction"), - [RTT_IMMEDIATE] = SEGMENT_NAME("immediate"), - [RTT_REGISTER] = SEGMENT_NAME("register"), - [RTT_PUNCT] = SEGMENT_NAME("punct"), - [RTT_HOOK] = SEGMENT_NAME("hooks"), - [RTT_SIGNS] = SEGMENT_NAME("signs"), - [RTT_LTGT] = SEGMENT_NAME("ltgt"), - [RTT_SECTION] = SEGMENT_NAME("section"), - [RTT_SEGMENT] = SEGMENT_NAME("segment"), - [RTT_STRING] = SEGMENT_NAME("string"), - [RTT_VAR_NAME] = SEGMENT_NAME("var-name"), - [RTT_KEY_WORD] = SEGMENT_NAME("keyword"), - [RTT_ERROR] = SEGMENT_NAME("error"), - -}; - -/* Compléments à Cairo */ - -#define CAIRO_FONT_SLANT_COUNT 3 -#define CAIRO_FONT_WEIGHT_COUNT 2 - -#define CAIRO_FONTS_COUNT (CAIRO_FONT_SLANT_COUNT * CAIRO_FONT_WEIGHT_COUNT) -#define CAIRO_FONT_INDEX(s, w) ((s) + (w) * CAIRO_FONT_WEIGHT_COUNT) - -/* Fragment de caractères aux propriétés communes (instance) */ -struct _GBufferSegment -{ - GObject parent; /* A laisser en premier */ - - seg_content *content; /* Contenu, partagé ou non */ - -}; - -/* Fragment de caractères aux propriétés communes (classe) */ -struct _GBufferSegmentClass -{ - GObjectClass parent; /* A laisser en premier */ - - rendering_color_t selection_bg; /* Fond d'impression */ - - cairo_t *font_ctxts[CAIRO_FONTS_COUNT]; /* Contextes de police */ - double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */ - rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression */ - - /* Signaux */ - - void (* content_changed) (GBufferSegment *); - -}; - - -/* Procède à l'initialisation d'une classe de fragment de texte. */ -static void g_buffer_segment_class_init(GBufferSegmentClass *); - -/* Procède à l'initialisation d'un fragment de texte. */ -static void g_buffer_segment_init(GBufferSegment *); - -/* Supprime toutes les références externes. */ -static void g_buffer_segment_dispose(GBufferSegment *); - -/* Procède à la libération totale de la mémoire. */ -static void g_buffer_segment_finalize(GBufferSegment *); - -/* Met à jour le contenu d'un fragment de texte. */ -void g_buffer_segment_set_text(GBufferSegment *, rendering_pattern_t *, const char *, size_t); - - - -/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ - - -/* Liste identifiant un ensemble de segments */ -struct _segcnt_list -{ - fnv64_t *hashes; /* Empreinte pour comparaisons */ - size_t count; /* Nommbre de ces empreintes */ - -}; - - - -/* ---------------------------------------------------------------------------------- */ -/* ISOLATION DE CONTENUS PARTAGEABLES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Initialise la table mémorisant les contenus pour segments. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool init_segment_content_hash_table(void) -{ - _segcnt_htable = g_hash_table_new_full((GHashFunc)get_seg_content_hash, - (GEqualFunc)is_seg_content_equal, - free, NULL); - - return (_segcnt_htable != NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Organise la sortie de la table des contenus pour segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void exit_segment_content_hash_table(void) -{ - assert(g_hash_table_size(_segcnt_htable) == 0); - - g_hash_table_unref(_segcnt_htable); - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu pour segment à consulter. * -* * -* Description : Fournit l'empreinte d'un contenu pour segments. * -* * -* Retour : Empreinte de lu contenu représenté. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static guint get_seg_content_hash(const seg_content *content) -{ - return content->hash; - -} - - -/****************************************************************************** -* * -* Paramètres : content = premier contenu pour segment à analyser. * -* other = second contenu pour segment à analyser. * -* * -* Description : Détermine si deux contenus pour segments sont identiques. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool is_seg_content_equal(const seg_content *content, const seg_content *other) -{ - bool result; /* Résultat à retourner */ - - result = (content->pattern == other->pattern); - - result &= (cmp_fnv_64a(content->hash, other->hash) == 0); - - result &= (strcmp(content->text, other->text) == 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = premier contenu pour segment à analyser. * -* other = second contenu pour segment à analyser. * -* * -* Description : Détermine si deux contenus pour segments sont identiques. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static seg_content *get_shared_content(const seg_content *content) -{ - seg_content *result; /* Contenu partagé à renvoyer */ - gboolean found; /* Le contenu existe déjà ? */ - size_t allocated; /* Besoin complet en mémoire */ -#ifndef NDEBUG - gboolean created; /* Validation de mise en place */ -#endif - - /** - * On considère qu'il n'y a pas besoin de mutex ici, puisque toutes les - * opérations se réalisent à priori dans le seul thread principal pour l'affichage. - */ - - found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL); - - if (!found) - { - allocated = sizeof(seg_content) + strlen(content->text) + 1; - - result = (seg_content *)malloc(allocated); - - memcpy(result, content, allocated); - - result->ref_count = 1; - -#ifndef NDEBUG - created = g_hash_table_insert(_segcnt_htable, result, result); - assert(created); -#else - g_hash_table_insert(_segcnt_htable, result, result); -#endif - - } - - else - { - assert(result->ref_count < UINT_MAX); - - result->ref_count++; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu pour segments à délaisser. * -* * -* Description : Abandonne un contenu pour segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void release_shared_content(seg_content *content) -{ -#ifndef NDEBUG - gboolean deleted; /* Validation de suppression */ -#endif - - /** - * On considère qu'il n'y a pas besoin de mutex ici, puisque toutes les - * opérations se réalisent à priori dans le seul thread principal pour l'affichage. - */ - - if (--content->ref_count == 0) - { -#ifndef NDEBUG - deleted = g_hash_table_remove(_segcnt_htable, content); - assert(deleted); -#else - g_hash_table_remove(_segcnt_htable, content); -#endif - } - -} - - - - -/* ---------------------------------------------------------------------------------- */ -/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ -/* ---------------------------------------------------------------------------------- */ - - -/* Détermine le type du fragment de caractères aux propriétés communes. */ -G_DEFINE_TYPE(GBufferSegment, g_buffer_segment, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : class = classe de composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation d'une classe de fragment de texte.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_buffer_segment_class_init(GBufferSegmentClass *class) -{ - GObjectClass *object; /* Autre version de la classe */ - GtkStyleContext *context; /* Contexte pour les styles */ - GtkWidgetPath *path; /* Chemin d'accès aux thèmes */ - gchar *filename; /* Accès à une image 1x1 */ - cairo_font_slant_t s; /* Boucle de parcours #1 */ - cairo_font_weight_t w; /* Boucle de parcours #2 */ - cairo_t **cr; /* Contexte à créer */ - cairo_surface_t *surface; /* Surface pour dessin Cairo */ - cairo_text_extents_t extents; /* Couverture des caractères */ - RenderingTagType i; /* Boucle de parcours */ - - object = G_OBJECT_CLASS(class); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_segment_dispose; - object->finalize = (GObjectFinalizeFunc)g_buffer_segment_finalize; - - /* Création d'un contexte d'accès */ - - path = gtk_widget_path_new(); - gtk_widget_path_append_type(path, G_TYPE_OBJECT); - - context = gtk_style_context_new(); - gtk_style_context_set_path(context, path); - gtk_style_context_set_screen(context, gdk_screen_get_default()); - - /* Contextes pour les mesures initiales */ - - filename = find_pixmap_file("nil.png"); - if (filename == NULL) abort(); - - for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++) - for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++) - { - cr = &class->font_ctxts[CAIRO_FONT_INDEX(s, w)]; - - surface = cairo_image_surface_create_from_png(filename); - *cr = cairo_create(surface); - cairo_surface_destroy(surface); - - cairo_select_font_face(*cr, "mono", s, w); - cairo_set_font_size(*cr, 13); - - cairo_text_extents(*cr, "A", &extents); - class->x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance; - - } - - g_free(filename); - - /* Fond d'impression */ - - class->selection_bg.has_color = true; - class->selection_bg.color.red = 0.5; - class->selection_bg.color.green = 0.5; - class->selection_bg.color.blue = 0.5; - class->selection_bg.color.alpha = 1.0; - - /* Chargement des définitions utiles */ - - void define_rendering_pattern(GtkStyleContext *ctx, const char *name, rendering_pattern_t *pattern) - { - GdkRGBA *tmp_color; /* Description d'une couleur */ - PangoFontDescription *font_desc; /* Description d'une police */ - - gtk_style_context_save(ctx); - - gtk_style_context_add_class(context, name); - - gtk_style_context_get(ctx, GTK_STATE_NORMAL, GTK_STYLE_PROPERTY_COLOR, &tmp_color, NULL); - - pattern->foreground.has_color = true; - pattern->foreground.color = *tmp_color; - - pattern->inverted.has_color = true; - pattern->inverted.color.red = 1.0 - tmp_color->red; - pattern->inverted.color.green = 1.0 - tmp_color->green; - pattern->inverted.color.blue = 1.0 - tmp_color->blue; - pattern->inverted.color.alpha = tmp_color->alpha; - - gdk_rgba_free(tmp_color); - - gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL); - - switch (pango_font_description_get_style(font_desc)) - { - case PANGO_STYLE_NORMAL: - pattern->slant = CAIRO_FONT_SLANT_NORMAL; - break; - case PANGO_STYLE_ITALIC: - pattern->slant = CAIRO_FONT_SLANT_ITALIC; - break; - case PANGO_STYLE_OBLIQUE: - pattern->slant = CAIRO_FONT_SLANT_OBLIQUE; - break; - } - - switch (pango_font_description_get_weight(font_desc)) - { - case PANGO_WEIGHT_THIN: - case PANGO_WEIGHT_ULTRALIGHT: - case PANGO_WEIGHT_LIGHT: - case PANGO_WEIGHT_SEMILIGHT: - case PANGO_WEIGHT_BOOK: - case PANGO_WEIGHT_NORMAL: - case PANGO_WEIGHT_MEDIUM: - pattern->weight = CAIRO_FONT_WEIGHT_NORMAL; - break; - case PANGO_WEIGHT_SEMIBOLD: - case PANGO_WEIGHT_BOLD: - case PANGO_WEIGHT_ULTRABOLD: - case PANGO_WEIGHT_HEAVY: - case PANGO_WEIGHT_ULTRAHEAVY: - pattern->weight = CAIRO_FONT_WEIGHT_BOLD; - break; - } - - pango_font_description_free(font_desc); - - gtk_style_context_restore(context); - - } - - for (i = 0; i < RTT_COUNT; i++) - define_rendering_pattern(context, _segment_names[i], &class->patterns[i]); - - /* Nettoyages finaux... */ - - gtk_widget_path_free(path); - g_object_unref(context); - - /* Signaux */ - - g_signal_new("content-changed", - G_TYPE_BUFFER_SEGMENT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GBufferSegmentClass, content_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation d'un fragment de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_buffer_segment_init(GBufferSegment *segment) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : segment = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_buffer_segment_dispose(GBufferSegment *segment) -{ - release_shared_content(segment->content); - - G_OBJECT_CLASS(g_buffer_segment_parent_class)->dispose(G_OBJECT(segment)); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_buffer_segment_finalize(GBufferSegment *segment) -{ - G_OBJECT_CLASS(g_buffer_segment_parent_class)->finalize(G_OBJECT(segment)); - -} - - -/****************************************************************************** -* * -* Paramètres : type = propriétés de la zone de texte. * -* text = chaîne de caractères à traiter. * -* length = quantité de ces caractères. * -* * -* Description : Crée un nouveau fragment de texte avec des propriétés. * -* * -* Retour : Composant GTK créé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBufferSegment *g_buffer_segment_new(RenderingTagType type, const char *text, size_t length) -{ - GBufferSegment *result; /* Composant à retourner */ - GBufferSegmentClass *class; /* Stockage de styles préparés */ - - result = g_object_new(G_TYPE_BUFFER_SEGMENT, NULL); - - class = G_BUFFER_SEGMENT_GET_CLASS(result); - - g_buffer_segment_set_text(result, &class->patterns[type], text, length); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à mettre à jour. * -* pattern = paramètres d'impression du texte. * -* text = chaîne de caractères à traiter. * -* length = quantité de ces caractères. * -* * -* Description : Met à jour le contenu d'un fragment de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_segment_set_text(GBufferSegment *segment, rendering_pattern_t *pattern, const char *text, size_t length) -{ - char atmp[sizeof(seg_content) + 128]; /* Allocation static facile */ - seg_content *content; /* Contenu à mettre en place ? */ - - if (length < (sizeof(atmp) - sizeof(seg_content))) - content = (seg_content *)atmp; - else - content = (seg_content *)malloc(sizeof(seg_content) + length + 1); - - content->pattern = pattern; - - content->hash = fnv_64a_hash(text); - - memcpy(content->text, text, length); - content->text[length] = '\0'; - - segment->content = get_shared_content(content); - - if (content != (seg_content *)atmp) - free(content); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à mettre à jour. * -* text = chaîne de caractères à traiter. * -* length = quantité de ces caractères. * -* * -* Description : Met à jour le contenu d'un fragment de texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_segment_update_text(GBufferSegment *segment, const char *text, size_t length) -{ - rendering_pattern_t *pattern; /* Conservation des paramètres */ - - /* Destruction */ - - pattern = segment->content->pattern; - - release_shared_content(segment->content); - - /* Création */ - - g_buffer_segment_set_text(segment, pattern, text, length); - - g_signal_emit_by_name(segment, "content-changed"); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* ref = segment de référence servant à la comparaison. * -* * -* Description : Indique si les textes de deux segments sont identiques. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_buffer_segment_compare(const GBufferSegment *segment, const GBufferSegment *ref) -{ - bool result; /* Bilan à retourner */ - - result = is_seg_content_equal(segment->content, ref->content); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* markup = indique si le texte doit être décoré ou non. * -* * -* Description : Fournit le texte brut conservé dans le segment. * -* * -* Retour : Texte conservé en interne. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *g_buffer_segment_get_text(const GBufferSegment *segment, bool markup) -{ - char *result; /* Description à renvoyer */ - const seg_content *content; /* Accès au contenu */ - char color[7]; /* Couleur hexadécimale */ - char *valid; - - content = segment->content; - - /* Résolution du cas simple */ - if (!markup) - return strdup(content->text); - - result = strdup("pattern->foreground.color.red * 255), - (unsigned char)(content->pattern->foreground.color.green * 255), - (unsigned char)(content->pattern->foreground.color.blue * 255)); - - result = stradd(result, color); - - result = stradd(result, "\""); - - /* Style */ - - result = stradd(result, "style=\""); - - switch (content->pattern->slant) - { - case CAIRO_FONT_SLANT_NORMAL: - result = stradd(result, "normal"); - break; - - case CAIRO_FONT_SLANT_ITALIC: - result = stradd(result, "italic"); - break; - - case CAIRO_FONT_SLANT_OBLIQUE: - result = stradd(result, "oblique"); - break; - - } - - result = stradd(result, "\""); - - /* Epaisseur */ - - result = stradd(result, "weight=\""); - - switch (content->pattern->weight) - { - case CAIRO_FONT_WEIGHT_NORMAL: - result = stradd(result, "normal"); - break; - - case CAIRO_FONT_WEIGHT_BOLD: - result = stradd(result, "bold"); - break; - - } - - result = stradd(result, "\""); - - /* Conclusion */ - - result = stradd(result, ">"); - - valid = strdup(content->text); - valid = strrpl(valid, "<", "<"); - valid = strrpl(valid, "&", "&"); - - result = stradd(result, valid); - - free(valid); - - result = stradd(result, ""); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* * -* Description : Fournit la quantité de pixels requise pour l'impression. * -* * -* Retour : Largeur requise par la colonne, en pixel. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gint g_buffer_segment_get_width(const GBufferSegment *segment) -{ - gint result; /* Largeur à retourner */ - GBufferSegmentClass *class; /* Classe associée à l'instance*/ - const seg_content *content; /* Accès au contenu */ - cairo_font_slant_t slant; /* Style d'impression */ - cairo_font_weight_t weight; /* Poids de la police */ - - class = G_BUFFER_SEGMENT_GET_CLASS(segment); - - content = segment->content; - - slant = content->pattern->slant; - weight = content->pattern->weight; - - result = class->x_advances[CAIRO_FONT_INDEX(slant, weight)] * strlen(content->text); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à consulter. * -* x = position horizontale au niveau du segment. * -* * -* Description : Fournit la position idéale pour un marqueur. * -* * -* Retour : Position dans le segment donné. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gint g_buffer_segment_get_caret_position(const GBufferSegment *segment, gint x) -{ - gint result; /* Position à retourner */ - gint width; /* Largeur du segment */ - gint char_width; /* Largeur de police fixe */ - - width = g_buffer_segment_get_width(segment); - - if (x <= 0) - result = 0; - - else if (x >= width) - result = width; - - else - { - char_width = width / strlen(segment->content->text); - - result = (x / char_width) * char_width; - if ((x % char_width) > (char_width / 2)) - result += char_width; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à manipuler. * -* x = position du curseur à faire évoluer. [OUT] * -* ctrl = indique la demande d'un parcours rapide. * -* dir = direction du parcours. * -* * -* Description : Déplace le curseur au sein d'un segment de tampon. * -* * -* Retour : true si un déplacement a été effectué, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_buffer_segment_move_caret(const GBufferSegment *segment, gint *x, bool ctrl, GdkScrollDirection dir) -{ - bool result; /* Bilan d'opération à renvoyer*/ - gint width; /* Largeur du segment */ - gint char_width; /* Largeur de police fixe */ - - result = false; - - width = g_buffer_segment_get_width(segment); - char_width = width / strlen(segment->content->text); - - if (dir == GDK_SCROLL_LEFT) - { - printf(">>>>> left ::: x=%d width=%d char=%d\n", *x, width, char_width); - - if (*x > width) *x = width + char_width; - - if (*x == 0) goto gbsmc_done; - - if (ctrl) *x = 0; - else *x = MAX(0, *x - char_width); - - result = true; - - } - - else if (dir == GDK_SCROLL_RIGHT) - { - - printf(">>>>> right ::: x=%d width=%d char=%d\n", *x, width, char_width); - - if (*x == width) goto gbsmc_done; - - if (ctrl) *x = width; - else *x = MIN(width, *x + char_width); - - result = true; - - } - - gbsmc_done: - - printf(">>>>> result ::: %d\n", result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à manipuler. * -* cr = contexte graphique à utiliser pour les pinceaux. * -* x = abscisse du point d'impression (à maj). [OUT] * -* y = ordonnée du point d'impression. * -* list = liste de contenus à mettre en évidence. * -* * -* Description : Imprime le fragment de texte représenté. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_segment_draw(GBufferSegment *segment, cairo_t *cr, gint *x, gint y, const segcnt_list *list) -{ - bool selected; /* Marquer une sélection ? */ - gint width; /* Largeur du segment */ - GBufferSegmentClass *class; /* Accès aux infos globales */ - cairo_operator_t old; /* Sauvegarde avant changement */ - const seg_content *content; /* Accès au contenu */ - const rendering_color_t *used_fg; /* Couleur d'impression utile */ - - selected = selection_list_has_segment_content(list, segment); - - width = g_buffer_segment_get_width(segment); - - /* Fond du texte */ - if (selected) - { - class = G_BUFFER_SEGMENT_GET_CLASS(segment); - - cairo_set_source_rgba(cr, - class->selection_bg.color.red, - class->selection_bg.color.green, - class->selection_bg.color.blue, - class->selection_bg.color.alpha); - - cairo_rectangle(cr, *x, y, width, 17); - - old = cairo_get_operator(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); - cairo_fill(cr); - cairo_set_operator(cr, old); - - } - - /* Couleur d'impression */ - - content = segment->content; - - if (selected) - used_fg = &content->pattern->inverted; - else - used_fg = &content->pattern->foreground; - - if (used_fg->has_color) - cairo_set_source_rgba(cr, - used_fg->color.red, - used_fg->color.green, - used_fg->color.blue, - used_fg->color.alpha); - else - cairo_set_source_rgb(cr, 0, 0, 0); - - /* Impression du texte */ - - cairo_select_font_face(cr, "mono", content->pattern->slant, content->pattern->weight); - cairo_set_font_size(cr, 13); - - cairo_move_to(cr, *x, y + 17 - 3); /* 3 = font extents.descent */ - - cairo_show_text(cr, content->text); - - *x += width; - -} - - -/****************************************************************************** -* * -* Paramètres : ctx = éléments à disposition pour l'exportation. * -* type = type d'exportation attendue. * -* * -* Description : Exporte tous les styles utilisés par des segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_segment_export_style(buffer_export_context *ctx, BufferExportType type) -{ - GBufferSegment *dummy; /* Segment servant de sujet */ - GBufferSegmentClass *class; /* Classe des segments */ - size_t i; /* Boucle de parcours */ - const rendering_pattern_t *pattern; /* Modèle à transcrire */ - - dummy = g_object_new(G_TYPE_BUFFER_SEGMENT, NULL); - class = G_BUFFER_SEGMENT_GET_CLASS(dummy); - - for (i = 0; i < RTT_COUNT; i++) - { - pattern = &class->patterns[i]; - - switch (type) - { - case BET_HTML: - - dprintf(ctx->fd, ".%s {\n", _segment_names[i]); - - if (pattern->foreground.has_color) - dprintf(ctx->fd, "\tcolor: #%02hhx%02hhx%02hhx;\n", - (unsigned char)(pattern->foreground.color.red * 255), - (unsigned char)(pattern->foreground.color.green * 255), - (unsigned char)(pattern->foreground.color.blue * 255)); - - switch (pattern->slant) - { - case CAIRO_FONT_SLANT_ITALIC: - dprintf(ctx->fd, "\tfont-style: italic;\n"); - break; - case CAIRO_FONT_SLANT_OBLIQUE: - dprintf(ctx->fd, "\tfont-style: oblique;\n"); - break; - default: - dprintf(ctx->fd, "\tfont-style: normal;\n"); - break; - } - - switch (pattern->weight) - { - case CAIRO_FONT_WEIGHT_BOLD: - dprintf(ctx->fd, "\tfont-weight: bold;\n"); - break; - default: - dprintf(ctx->fd, "\tfont-weight: normal;\n"); - break; - } - - dprintf(ctx->fd, "}\n"); - - break; - - default: - break; - - } - - } - - g_object_unref(G_OBJECT(dummy)); - -} - - -/****************************************************************************** -* * -* Paramètres : segment = fragment de texte à manipuler. * -* ctx = éléments à disposition pour l'exportation. * -* type = type d'exportation attendue. * -* * -* Description : Exporte le fragment de texte représenté. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_segment_export(const GBufferSegment *segment, buffer_export_context *ctx, BufferExportType type) -{ - const seg_content *content; /* Accès au contenu */ - GBufferSegmentClass *class; /* Classe des segments */ - size_t index; /* Indice du modèle de rendu */ - - content = segment->content; - - switch (type) - { - case BET_HTML: - class = G_BUFFER_SEGMENT_GET_CLASS(segment); - index = (content->pattern - class->patterns); - dprintf(ctx->fd, "", _segment_names[index]); - break; - default: - break; - } - - dprintf(ctx->fd, "%s", content->text); - - switch (type) - { - case BET_HTML: - dprintf(ctx->fd, ""); - break; - default: - break; - } - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* GESTION OPTIMALE D'UNE LISTE DE CONTENUS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Initilise une liste de contenus de segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -segcnt_list *init_segment_content_list(void) -{ - segcnt_list *result; /* Structure à retourner */ - - result = (segcnt_list *)calloc(1, sizeof(segcnt_list)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à traiter. * -* * -* Description : Libère la mémoire occupée par une liste de contenus. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void exit_segment_content_list(segcnt_list *list) -{ - reset_segment_content_list(list); - - free(list); - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à manipuler. * -* * -* Description : Vide, si besoin est, une liste de contenus de segments. * -* * -* Retour : true si des éléments ont été purgés, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool reset_segment_content_list(segcnt_list *list) -{ - bool result; /* Bilan d'action à renvoyer */ - - result = (list->count > 0); - - if (list->hashes != NULL) - { - free(list->hashes); - list->hashes = NULL; - } - - list->count = 0; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à manipuler. * -* segment = fragment de texte à conservr. * -* * -* Description : Marque le contenu d'un segment comme remarquable. * -* * -* Retour : true si la liste a été complétée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_segment_content_to_selection_list(segcnt_list *list, const GBufferSegment *segment) -{ - bool result; /* Bilan à retourner */ - const seg_content *content; /* Accès au contenu */ - size_t i; /* Boucle de parcours */ - - static const char white_list[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - result = false; - - content = segment->content; - - for (i = 0; i < (sizeof(white_list) - 1) && !result; i++) - result = (strchr(content->text, white_list[i]) != NULL); - - if (result) - { - list->hashes = (fnv64_t *)realloc(list->hashes, ++list->count * sizeof(fnv64_t)); - - list->hashes[list->count - 1] = content->hash; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de références de contenus à consulter. * -* segment = fragment de texte à comparer. * -* * -* Description : Indique si le contenu d'un segment est notable ou non. * -* * -* Retour : true si le segment a un contenu présent dans la sélection. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool selection_list_has_segment_content(const segcnt_list *list, const GBufferSegment *segment) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - result = false; - - for (i = 0; i < list->count && !result; i++) - result = (cmp_fnv_64a(list->hashes[i], segment->content->hash) == 0); - - return result; - -} diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h deleted file mode 100644 index 01fb2ea..0000000 --- a/src/glibext/gbuffersegment.h +++ /dev/null @@ -1,203 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gbuffersegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes - * - * Copyright (C) 2010-2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _GLIBEXT_GBUFFERSEGMENT_H -#define _GLIBEXT_GBUFFERSEGMENT_H - - -#include -#include -#include -#include - - - -/* Liste identifiant un ensemble de segments */ -typedef struct _segcnt_list segcnt_list; - - - -/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ - - -/* Initialise la table mémorisant les contenus pour segments. */ -bool init_segment_content_hash_table(void); - -/* Organise la sortie de la table des contenus pour segments. */ -void exit_segment_content_hash_table(void); - - - -/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ - - -#define G_TYPE_BUFFER_SEGMENT (g_buffer_segment_get_type()) -#define G_BUFFER_SEGMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BUFFER_SEGMENT, GBufferSegment)) -#define G_BUFFER_SEGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BUFFER_SEGMENT, GBufferSegmentClass)) -#define G_IS_BUFFER_SEGMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BUFFER_SEGMENT)) -#define G_IS_BUFFER_SEGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BUFFER_SEGMENT)) -#define G_BUFFER_SEGMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BUFFER_SEGMENT, GBufferSegmentClass)) - - -/* Types de partie de rendu */ -typedef enum _RenderingTagType -{ - RTT_RAW, /* Contenu brut */ - - RTT_COMMENT, /* Commentaire */ - RTT_INDICATION, /* Aide à la lecture */ - - RTT_PHYS_ADDR_PAD, /* Position physique (début) */ - RTT_PHYS_ADDR, /* Position physique */ - RTT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */ - RTT_VIRT_ADDR, /* Adresse virtuelle */ - RTT_RAW_CODE, /* Code binaire brut */ - - RTT_LABEL, /* Etiquette sur une adresse */ - - RTT_INSTRUCTION, /* Code binaire brut */ - - RTT_IMMEDIATE, /* Valeur immédiate */ - - RTT_REGISTER, /* Registre */ - - RTT_PUNCT, /* Signes de ponctuation */ - RTT_HOOK, /* Crochets '[' et ']' */ - RTT_SIGNS, /* Signes '+', '-' et '*' */ - RTT_LTGT, /* Caractères '<' et '>' */ - - RTT_SECTION, /* Identifiant de section */ - RTT_SEGMENT, /* Indication de segment */ - RTT_STRING, /* Chaîne de caractères avec " */ - - RTT_VAR_NAME, /* Nom de variable */ - - RTT_KEY_WORD, /* Mot clef de langage */ - - RTT_ERROR, /* Erreur "interne" */ - - RTT_COUNT - -} RenderingTagType; - - -/* Fragment de caractères aux propriétés communes (instance) */ -typedef struct _GBufferSegment GBufferSegment; - -/* Fragment de caractères aux propriétés communes (classe) */ -typedef struct _GBufferSegmentClass GBufferSegmentClass; - - - -/* Détermine le type du fragment de caractères aux propriétés communes. */ -GType g_buffer_segment_get_type(void); - -/* Crée un nouveau fragment de texte avec des propriétés. */ -GBufferSegment *g_buffer_segment_new(RenderingTagType, const char *, size_t); - -/* Met à jour le contenu d'un fragment de texte. */ -void g_buffer_segment_update_text(GBufferSegment *, const char *, size_t); - -/* Indique si les textes de deux segments sont identiques. */ -bool g_buffer_segment_compare(const GBufferSegment *, const GBufferSegment *); - -/* Fournit le texte brut conservé dans le segment. */ -char *g_buffer_segment_get_text(const GBufferSegment *, bool); - -/* Fournit la quantité de pixels requise pour l'impression. */ -gint g_buffer_segment_get_width(const GBufferSegment *); - -/* Fournit la position idéale pour un marqueur. */ -gint g_buffer_segment_get_caret_position(const GBufferSegment *, gint); - -/* Déplace le curseur au sein d'un segment de tampon. */ -bool g_buffer_segment_move_caret(const GBufferSegment *, gint *, bool, GdkScrollDirection); - -/* Imprime le fragment de texte représenté. */ -void g_buffer_segment_draw(GBufferSegment *, cairo_t *, gint *, gint, const segcnt_list *); - -/* Types d'exportation */ -typedef enum _BufferExportType -{ - BET_TEXT, /* Exportation en texte brut */ - BET_HTML, /* Exportation en HTML */ - - BET_COUNT - -} BufferExportType; - -/* Elements sur lesquels une exportation peut s'appuyer */ -typedef struct _buffer_export_context -{ - union - { - int fd; /* Flux ouvert en écriture */ - - }; - - union - { - /* BET_TEXT */ - const char *sep; /* Séparation entre colonnes */ - - /* BET_HTML */ - struct - { - const char *font_name; /* Police d'impression */ - const char *bg_color; /* Fond du tableau HTML */ - - }; - - }; - -} buffer_export_context; - -/* Exporte tous les styles utilisés par des segments. */ -void g_buffer_segment_export_style(buffer_export_context *, BufferExportType); - -/* Exporte le fragment de texte représenté. */ -void g_buffer_segment_export(const GBufferSegment *, buffer_export_context *, BufferExportType); - - - -/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ - - -/* Initilise une liste de contenus de segments. */ -segcnt_list *init_segment_content_list(void); - -/* Libère la mémoire occupée par une liste de contenus. */ -void exit_segment_content_list(segcnt_list *); - -/* Vide, si besoin est, une liste de contenus de segments. */ -bool reset_segment_content_list(segcnt_list *); - -/* Marque le contenu d'un segment comme remarquable. */ -bool add_segment_content_to_selection_list(segcnt_list *, const GBufferSegment *); - -/* Indique si le contenu d'un segment est notable ou non. */ -bool selection_list_has_segment_content(const segcnt_list *, const GBufferSegment *); - - - -#endif /* _GLIBEXT_GBUFFERSEGMENT_H */ diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c index 2deeffe..9f17e24 100644 --- a/src/glibext/gbufferview.c +++ b/src/glibext/gbufferview.c @@ -84,7 +84,7 @@ static void g_buffer_view_finalize(GBufferView *); static void on_buffer_size_changed(const GCodeBuffer *, bool, size_t, size_t, GBufferView *); /* Réagit à un changement de contenu d'une ligne donnée. */ -static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, GBufferSegment *, GBufferView *); +static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, line_segment *, GBufferView *); /* Déplace le curseur au sein d'une vue de tampon. */ static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, GdkRectangle *, bool, GdkScrollDirection, const bool *); @@ -362,7 +362,7 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t * * ******************************************************************************/ -static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, GBufferSegment *segment, GBufferView *view) +static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_segment *segment, GBufferView *view) { const vmpa2t *addr; /* Localisation de ligne */ @@ -588,31 +588,22 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, con gint remaining; /* Copie de travail modifiable */ size_t index; /* Indice de ligne de tampon */ GBufferLine *line; /* Ligne à la position courante*/ - GBufferSegment *segment; /* Segment présent sur la place*/ + const line_segment *segment; /* Segment présent sur la place*/ GBufferViewClass *class; /* Classe pour les vues */ remaining = x; line = g_buffer_view_find_line_and_segment_at(view, &remaining, y, &index, display, &segment); + /* FIXME : unref() ! */ if (line == NULL) return NULL; if (segment == NULL) printf(" -- no segment\n"); if (segment == NULL) return NULL; - - - - printf("\n[BASE] orig = %d tronc = %d reste = %d dernier = %d largeur = %d\n", - x, x - remaining, remaining, g_buffer_segment_get_caret_position(segment, remaining), - g_buffer_segment_get_width(segment)); - - printf(" '%s'\n", g_buffer_segment_get_text(segment, false)); - - class = G_BUFFER_VIEW_GET_CLASS(view); - caret->x = /*view->left_text +*/ (x - remaining) + g_buffer_segment_get_caret_position(segment, remaining); + caret->x = /*view->left_text +*/ (x - remaining) + get_caret_position_from_line_segment(segment, remaining); caret->y = (index - view->first) * class->line_height; @@ -647,10 +638,7 @@ const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *l gint offset; /* Point de travail modifiable */ line_width_summary summary; /* Résumé concis des largeurs */ gint base; /* Position absolue de segment */ - GBufferSegment *segment; /* Segment visé par le pointeur*/ - - - + bool status; /* Bilan de la localisation */ class = G_BUFFER_VIEW_GET_CLASS(view); @@ -661,13 +649,13 @@ const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *l g_width_tracker_get_local_width_summary(view->tracker, index, &summary); - segment = g_buffer_line_get_segment_at(line, &summary, display, &base, &offset, GDK_SCROLL_LEFT, true); - if (segment == NULL) return NULL; + /* Traitement pour mise à jour de l'abscisse uniquement */ + status = g_buffer_line_get_coord_at(line, &summary, display, &base, &offset, + GDK_SCROLL_LEFT, true, (col_coord_t []) { { 0 } }); + if (!status) return NULL; caret->x = class->left_text + base + offset; - printf("caret Y : %zu -> %zu\n", view->first, index); - caret->y = (index - view->first) * class->line_height; caret->width = 2; @@ -702,9 +690,8 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line gint offset; /* Point de travail modifiable */ line_width_summary summary; /* Résumé concis des largeurs */ gint base; /* Position absolue de segment */ - GBufferSegment *segment; /* Segment visé par le pointeur*/ - - + col_coord_t coord; /* Coordonnées en interne */ + const line_segment *segment; /* Bribe de texte trouvée */ offset = caret->x; @@ -713,64 +700,29 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line g_width_tracker_get_local_width_summary(view->tracker, index, &summary); - segment = g_buffer_line_get_segment_at(line, &summary, display, &base, &offset, dir, false); - - if (segment == NULL) printf(" ===== NO SEG...\n"); - - if (segment == NULL) return false; - - - printf(" ====== FIRST SEG :: %p ('%s')\n", segment, g_buffer_segment_get_text(segment, false)); - - - + /* Déplacement au sein du segment courant ? */ + result = g_buffer_line_get_coord_at(line, &summary, display, &base, &offset, dir, false, &coord); + if (result) + { + segment = g_buffer_line_get_segment_from_coord(line, &coord); - //if (dir == GDK_SCROLL_LEFT || dir == GDK_SCROLL_RIGHT) - result = g_buffer_segment_move_caret(segment, &offset, ctrl, dir); - //else - //result = true; + result = move_caret_on_line_segment(segment, &offset, ctrl, dir); - printf(" ====== MOVE 1 ? %d\n", result); + } - /////////////////// + /* Tentative de déplacement chez le segment voisin ? */ if (!result) { base = 0; - segment = g_buffer_line_find_near_segment(line, segment, &summary, display, dir, &offset); - - - printf(" ====== NEAR SEG :: %p ('%s')\n", segment, segment ? g_buffer_segment_get_text(segment, false) : NULL); - - if (segment != NULL) - { - - result = true; - //result = g_buffer_segment_move_caret(segment, &offset, ctrl, dir); - - /* - if (result) - caret->x -= COL_MARGIN; - */ - - printf(" ====== MOVE 2 ? %d (offset=%d)\n", result, offset); - - - } - + result = g_buffer_line_find_near_coord(line, &coord, &summary, display, dir, &offset); } - - if (result) - printf(" ====== NEW CARET: %d -> %d\n", caret->x, G_BUFFER_VIEW_GET_CLASS(view)->left_text + base + offset); - else - printf(" ====== NO NEW CARET!\n"); - - + /* Mise à jour éventuelle */ if (result) caret->x = G_BUFFER_VIEW_GET_CLASS(view)->left_text + base + offset; @@ -804,7 +756,6 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b line_width_summary summary; /* Résumé concis des largeurs */ - bool computed; /* Récursivité pris en compte */ gint left_pos; /* Retour à la ligne */ gint right_pos; /* Position d'extrème droite */ BufferLineColumn i; /* Boucle de parcours */ @@ -833,8 +784,6 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b g_width_tracker_get_local_width_summary(view->tracker, index, &summary); - computed = false; - switch (dir) { case GDK_SCROLL_UP: @@ -933,17 +882,6 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line) } - /* - printf(" --- CARET --- moved = %d index = %d result = %p\n", - moved, index, result); - */ - - - /* - if (result && !computed) - result = g_buffer_view_compute_caret_full(view, caret->x, caret->y, caret, display, NULL); - */ - return result; } @@ -990,7 +928,7 @@ bool g_buffer_view_unhighlight_segments(GBufferView *view) bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const bool *display) { bool need_redraw; /* Besoin d'actualisation ? */ - GBufferSegment *segment; /* Segment sélectionnable */ + const line_segment *segment; /* Segment sélectionnable */ if (view->highlighted != NULL) need_redraw = g_buffer_view_unhighlight_segments(view); @@ -1199,6 +1137,8 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx) if (index <= view->last) result = g_code_buffer_find_line_by_index(view->buffer, index); + else + result = NULL; if (result != NULL && idx != NULL) *idx = index; @@ -1225,7 +1165,7 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx) * * ******************************************************************************/ -GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, GBufferSegment **segment) +GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, const line_segment **segment) { GBufferLine *result; /* Ligne trouvée à retourner */ size_t index; /* Indice de la ligne trouvée */ diff --git a/src/glibext/gbufferview.h b/src/glibext/gbufferview.h index d5bfd3d..6f7aff4 100644 --- a/src/glibext/gbufferview.h +++ b/src/glibext/gbufferview.h @@ -102,7 +102,7 @@ GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *, size_t ); GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); /* Fournit la ligne et son segment présents à une position. */ -GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *, gint *, gint, size_t *, const bool *, GBufferSegment **); +GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *, gint *, gint, size_t *, const bool *, const line_segment **); /* Fournit la ligne et son segment présents à une position. */ GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *, gint *, gint, size_t *, const bool *, GObject **); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 9961cbc..f73a6f9 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -136,7 +136,7 @@ struct _GCodeBufferClass /* Signaux */ - void (* line_changed) (GCodeBuffer *, GBufferLine *, GBufferSegment *); + void (* line_changed) (GCodeBuffer *, GBufferLine *, line_segment *); }; @@ -152,7 +152,7 @@ static void g_code_buffer_class_init(GCodeBufferClass *); static void g_code_buffer_init(GCodeBuffer *); /* Réagit à un changement de contenu d'une ligne donnée. */ -static void on_line_content_change(GBufferLine *, GBufferSegment *, GCodeBuffer *); +static void on_line_content_change(GBufferLine *, line_segment *, GCodeBuffer *); /* Réagit à un changement de propriété rattachée à une ligne. */ static void on_line_flag_flip(GBufferLine *, BufferLineFlags, BufferLineFlags, GCodeBuffer *); @@ -529,7 +529,7 @@ GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *buffer, const mrange_t result = g_buffer_line_new(range, buffer->main_column); for (i = 0; i < buffer->indent; i++) - g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW); + g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW, NULL); return result; @@ -550,7 +550,7 @@ GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *buffer, const mrange_t * * ******************************************************************************/ -static void on_line_content_change(GBufferLine *line, GBufferSegment *segment, GCodeBuffer *buffer) +static void on_line_content_change(GBufferLine *line, line_segment *segment, GCodeBuffer *buffer) { g_signal_emit_by_name(buffer, "line-changed", line, segment); diff --git a/src/glibext/linecolumn.c b/src/glibext/linecolumn.c new file mode 100644 index 0000000..22c1e44 --- /dev/null +++ b/src/glibext/linecolumn.c @@ -0,0 +1,480 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * linecolumn.h - prototypes pour le regroupement des segments de texte par colonnes + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "linecolumn.h" + + +#include +#include + + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à initialiser. * +* * +* Description : Initialise une colonne de ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_line_column(line_column *column) +{ + column->segments = NULL; + column->count = 0; + + column->max_width = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à mettre à jour. * +* * +* Description : Réinitialise une colonne de ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void reset_line_column(line_column *column) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < column->count; i++) + release_line_segment(column->segments[i]); + + if (column->segments != NULL) + { + free(column->segments); + column->segments = NULL; + } + + column->count = 0; + + column->max_width = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à mettre à jour. * +* * +* Description : Recalcule la largeur d'une colonne de segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void refresh_line_column_width(line_column *column) +{ + size_t i; /* Boucle de parcours */ + + column->max_width = 0; + + for (i = 0; i < column->count; i++) + column->max_width += get_line_segment_width(column->segments[i]); + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à consulter. * +* * +* Description : Fournit la quantité de pixels requise pour l'impression. * +* * +* Retour : Largeur requise par la colonne, en pixel. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint get_column_width(const line_column *column) +{ + return column->max_width; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à venir compléter. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* type = type de décorateur à utiliser. * +* * +* Description : Ajoute un fragment de texte à une colonne de ligne. * +* * +* Retour : Indice du point d'insertion. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t append_text_to_line_column(line_column *column, const char *text, size_t length, RenderingTagType type) +{ + size_t result; /* Indice à retourner */ + line_segment *segment; /* Contenu à représenter */ + + result = column->count; + + segment = get_new_line_segment(type, text, length); + + column->segments = (line_segment **)realloc(column->segments, ++column->count * sizeof(line_segment *)); + + column->segments[result] = segment; + + column->max_width += get_line_segment_width(segment); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à venir compléter. * +* index = indice du frament de texte à remplacer. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* * +* Description : Remplace un fragment de texte dans une colonne de ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void replace_text_in_line_column(line_column *column, size_t index, const char *text, size_t length) +{ + RenderingTagType type; /* Type de rendu à conserver */ + line_segment *segment; /* Contenu à représenter */ + + assert(index < column->count); + + /* Retrait */ + + segment = column->segments[index]; + + type = get_line_segment_type(segment); + + release_line_segment(segment); + + /* Ajout */ + + segment = get_new_line_segment(type, text, length); + + column->segments[index] = segment; + + refresh_line_column_width(column); + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à consulter. * +* index = indice du contenu enregistré à la position. [OUT] * +* * +* Description : Indique l'indice du premier contenu de la colonne. * +* * +* Retour : Validité de l'indice renseigné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool get_line_column_first_content_index(const line_column *column, size_t *index) +{ + bool result; /* Bilan à retourner */ + + result = (column->count > 0); + + if (result) + *index = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à consulter. * +* index = indice du contenu enregistré à la position. [OUT] * +* * +* Description : Indique l'indice du dernier contenu de la colonne. * +* * +* Retour : Validité de l'indice renseigné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool get_line_column_last_content_index(const line_column *column, size_t *index) +{ + bool result; /* Bilan à retourner */ + + result = (column->count > 0); + + if (result) + *index = column->count - 1; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à consulter. * +* index = indice à consulter puis renseigner. [OUT] * +* dir = orientation des recherches. * +* * +* Description : Fournit le segment voisin d'un autre segment identifié. * +* * +* Retour : Validité de l'indice renseigné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_near_segment(const line_column *column, size_t *index, GdkScrollDirection dir) +{ + bool result; /* Bilan à faire remonter */ + + result = false; + + switch (dir) + { + case GDK_SCROLL_LEFT: + if (*index > 0) + { + (*index)--; + result = true; + } + break; + + case GDK_SCROLL_RIGHT: + if ((*index + 1) < column->count) + { + (*index)++; + result = true; + } + break; + + default: + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à consulter. * +* x = position de recherche, puis position locale. [OUT]* +* dir = direction d'un éventuel déplacement en cours. * +* consumed = distance pour arriver à la base du segment. [OUT] * +* index = indice du contenu enregistré à la position. [OUT] * +* * +* Description : Indique l'indice du contenu de colonne à une abscisse donnée.* +* * +* Retour : Validité de l'indice renseigné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool get_line_column_content_index_at(const line_column *column, gint *x, GdkScrollDirection dir, gint *consumed, size_t *index) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + gint width; /* Largeur à retirer */ + bool included; /* Appartenance à une largeur ?*/ + + result = false; + *consumed = 0; + + for (i = 0; i < column->count && !result; i++) + { + width = get_line_segment_width(column->segments[i]); + + /** + * Soit une limite entre deux segments A et B : + * + * - dans le cas d'un déplacement vers la gauche, on part de cette limite + * pour progresser à l'intérieur de A. Donc la limite fait partie de A. + * + * - dans le cas d'un déplacement vers la droite, on part de cette limite + * pour progresser à l'intérieur de B. Donc la limite ne fait pas partie de A. + */ + if (dir == GDK_SCROLL_LEFT) included = (width >= *x); + else included = (width > *x); + + if (included) + { + *index = i; + result = true; + } + + else if ((i + 1) == column->count) + { + *index = i; + result = true; + *x = width; + } + + else + { + *x -= width; + *consumed += width; + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à consulter. * +* index = indice du contenu à fournir. * +* * +* Description : Donne le segment d'une colonne présent à un indice donné. * +* * +* Retour : Segment trouvé ou NULL si hors borne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +line_segment *get_line_column_content_from_index(const line_column *column, size_t index) +{ + line_segment *result; /* Trouvaille à retourner */ + + assert(index < column->count); + + result = column->segments[index]; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à manipuler. * +* cairo = contexte graphique à utiliser pour les pinceaux. * +* x_init = abscisse du point d'impression de départ. * +* y = ordonnée du point d'impression. * +* list = liste de contenus à mettre en évidence. * +* * +* Description : Imprime le contenu d'une colonne de ligne de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void draw_line_column_segments(const line_column *column, cairo_t *cairo, gint x_init, gint y, const segcnt_list *list) +{ + gint x; /* Abscisse d'impression */ + size_t i; /* Boucle de parcours */ + + x = x_init; + + for (i = 0; i < column->count; i++) + draw_line_segment(column->segments[i], cairo, &x, y, list); + +} + + +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne de texte à manipuler. * +* ctx = éléments à disposition pour l'exportation. * +* type = type d'exportation attendue. * +* span = fusion de colonnes au sein des cellules ? * +* * +* Description : Exporte la ligne de texte représentée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void export_line_column_segments(const line_column *column, buffer_export_context *ctx, BufferExportType type, int span) +{ + size_t i; /* Boucle de parcours */ + + switch (type) + { + case BET_HTML: + switch (span) + { + case 0: + break; + case 1: + dprintf(ctx->fd, "\t\t"); + break; + default: + if (span > 0) dprintf(ctx->fd, "\t\t", span); + break; + } + break; + default: + break; + } + + for (i = 0; i < column->count; i++) + export_line_segment(column->segments[i], ctx, type); + + switch (type) + { + case BET_HTML: + if (span < 0 || span == 1) dprintf(ctx->fd, "\n"); + break; + default: + break; + } + +} diff --git a/src/glibext/linecolumn.h b/src/glibext/linecolumn.h new file mode 100644 index 0000000..849c076 --- /dev/null +++ b/src/glibext/linecolumn.h @@ -0,0 +1,93 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * linecolumn.h - prototypes pour le regroupement des segments de texte par colonnes + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GLIBEXT_LINECOLUMN_H +#define _GLIBEXT_LINECOLUMN_H + + +#include +#include +#include + + +#include "linesegment.h" + + + +/* Informations sur le contenu d'une colonne */ +typedef struct _line_column line_column; + + +/* Informations sur le contenu d'une colonne */ +struct _line_column +{ + line_segment **segments; /* Liste des segments contenus */ + size_t count; /* Taille de cette liste */ + + int max_width; /* Largeur max. de l'espace */ + +}; + + +/* Initialise une colonne de ligne. */ +void init_line_column(line_column *); + +/* Réinitialise une colonne de ligne. */ +void reset_line_column(line_column *); + +/* Recalcule la largeur d'une colonne de segments. */ +void refresh_line_column_width(line_column *); + +/* Fournit la quantité de pixels requise pour l'impression. */ +gint get_column_width(const line_column *); + +/* Ajoute un fragment de texte à une colonne de ligne. */ +size_t append_text_to_line_column(line_column *, const char *, size_t, RenderingTagType); + +/* Remplace un fragment de texte dans une colonne de ligne. */ +void replace_text_in_line_column(line_column *, size_t, const char *, size_t); + +/* Indique l'indice du premier contenu de la colonne. */ +bool get_line_column_first_content_index(const line_column *, size_t *); + +/* Indique l'indice du dernier contenu de la colonne. */ +bool get_line_column_last_content_index(const line_column *, size_t *); + +/* Fournit le segment voisin d'un autre segment identifié. */ +bool find_near_segment(const line_column *, size_t *, GdkScrollDirection); + +/* Indique l'indice du contenu de colonne à une abscisse donnée. */ +bool get_line_column_content_index_at(const line_column *, gint *, GdkScrollDirection, gint *, size_t *); + +/* Donne le segment d'une colonne présent à un indice donné. */ +line_segment *get_line_column_content_from_index(const line_column *, size_t); + +/* Imprime le contenu d'une colonne de ligne de texte. */ +void draw_line_column_segments(const line_column *, cairo_t *, gint, gint, const segcnt_list *); + +/* Exporte la ligne de texte représentée. */ +void export_line_column_segments(const line_column *, buffer_export_context *, BufferExportType, int); + + + +#endif /* _GLIBEXT_LINECOLUMN_H */ diff --git a/src/glibext/linesegment.c b/src/glibext/linesegment.c new file mode 100644 index 0000000..e233b00 --- /dev/null +++ b/src/glibext/linesegment.c @@ -0,0 +1,1155 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * linesegment.c - concentration d'un fragment de caractères aux propriétés communes + * + * Copyright (C) 2010-2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "linesegment.h" + + +#include +#include +#include +#include +#include +#include + + +#include "../common/extstr.h" +#include "../common/fnv1a.h" +#include "../gtkext/support.h" + + + +/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ + + +/* Nom des éléments CSS */ + +#define SEGMENT_NAME(s) "segment-" s + +static const char *_segment_names[RTT_COUNT] = { + + [RTT_RAW] = SEGMENT_NAME("raw"), + [RTT_COMMENT] = SEGMENT_NAME("comment"), + [RTT_INDICATION] = SEGMENT_NAME("indication"), + [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), + [RTT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"), + [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), + [RTT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"), + [RTT_RAW_CODE] = SEGMENT_NAME("raw-code"), + [RTT_LABEL] = SEGMENT_NAME("label"), + [RTT_INSTRUCTION] = SEGMENT_NAME("instruction"), + [RTT_IMMEDIATE] = SEGMENT_NAME("immediate"), + [RTT_REGISTER] = SEGMENT_NAME("register"), + [RTT_PUNCT] = SEGMENT_NAME("punct"), + [RTT_HOOK] = SEGMENT_NAME("hooks"), + [RTT_SIGNS] = SEGMENT_NAME("signs"), + [RTT_LTGT] = SEGMENT_NAME("ltgt"), + [RTT_SECTION] = SEGMENT_NAME("section"), + [RTT_SEGMENT] = SEGMENT_NAME("segment"), + [RTT_STRING] = SEGMENT_NAME("string"), + [RTT_VAR_NAME] = SEGMENT_NAME("var-name"), + [RTT_KEY_WORD] = SEGMENT_NAME("keyword"), + [RTT_ERROR] = SEGMENT_NAME("error"), + +}; + +/* Compléments à Cairo */ + +#define CAIRO_FONT_SLANT_COUNT 3 +#define CAIRO_FONT_WEIGHT_COUNT 2 + +#define CAIRO_FONTS_COUNT (CAIRO_FONT_SLANT_COUNT * CAIRO_FONT_WEIGHT_COUNT) +#define CAIRO_FONT_INDEX(s, w) ((s) + (w) * CAIRO_FONT_WEIGHT_COUNT) + + +/* Propriétés de rendu */ + +typedef struct _rendering_color_t +{ + GdkRGBA color; /* Couleur de rendu */ + bool has_color; /* Définition en place ? */ + +} rendering_color_t; + +typedef struct _rendering_pattern_t +{ + rendering_color_t foreground; /* Couleur d'impression */ + rendering_color_t inverted; /* Couleur inversée pour sél. */ + + cairo_font_slant_t slant; /* Style d'impression */ + cairo_font_weight_t weight; /* Poids de la police */ + +} rendering_pattern_t; + +typedef struct _segment_rendering +{ + rendering_color_t selection_bg; /* Fond d'impression */ + + cairo_t *font_ctxts[CAIRO_FONTS_COUNT]; /* Contextes de police */ + double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */ + rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression */ + +} segment_rendering; + + +/* Configuration globale des rendus */ +static segment_rendering _seg_params; + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +struct _line_segment +{ + unsigned int ref_count; /* Compteur de références */ + + rendering_pattern_t *pattern; /* Propriétés du rendu */ + + fnv64_t hash; /* Empreinte pour comparaisons */ + char text[0]; /* Texte brut conservé */ + +}; + + +/* Conservation de toutes les créations partagées */ +static GHashTable *_segcnt_htable; + + +/* Fournit l'empreinte d'un contenu pour segments. */ +static guint get_line_segment_hash(const line_segment *); + +/* Détermine si deux contenus pour segments sont identiques. */ +static bool is_line_segment_equal(const line_segment *, const line_segment *); + +/* Détermine si deux contenus pour segments sont identiques. */ +static line_segment *get_shared_segment_content(const line_segment *); + +/* Abandonne un contenu pour segments. */ +static void release_shared_segment_content(line_segment *); + + + +/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ + + +/* Liste identifiant un ensemble de segments */ +struct _segcnt_list +{ + fnv64_t *hashes; /* Empreinte pour comparaisons */ + size_t count; /* Nommbre de ces empreintes */ + +}; + + + +/* ---------------------------------------------------------------------------------- */ +/* NATURE POUR UN FRAGMENT DE TEXTE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède à l'initialisation des paramètres de rendu de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_segment_rendering_parameters(void) +{ + GtkStyleContext *context; /* Contexte pour les styles */ + GtkWidgetPath *path; /* Chemin d'accès aux thèmes */ + gchar *filename; /* Accès à une image 1x1 */ + cairo_font_slant_t s; /* Boucle de parcours #1 */ + cairo_font_weight_t w; /* Boucle de parcours #2 */ + cairo_t **cr; /* Contexte à créer */ + cairo_surface_t *surface; /* Surface pour dessin Cairo */ + cairo_text_extents_t extents; /* Couverture des caractères */ + RenderingTagType i; /* Boucle de parcours */ + + /* Création d'un contexte d'accès */ + + path = gtk_widget_path_new(); + gtk_widget_path_append_type(path, G_TYPE_OBJECT); + + context = gtk_style_context_new(); + gtk_style_context_set_path(context, path); + gtk_style_context_set_screen(context, gdk_screen_get_default()); + + /* Contextes pour les mesures initiales */ + + filename = find_pixmap_file("nil.png"); + if (filename == NULL) abort(); + + for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++) + for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++) + { + cr = &_seg_params.font_ctxts[CAIRO_FONT_INDEX(s, w)]; + + surface = cairo_image_surface_create_from_png(filename); + *cr = cairo_create(surface); + cairo_surface_destroy(surface); + + cairo_select_font_face(*cr, "mono", s, w); + cairo_set_font_size(*cr, 13); + + cairo_text_extents(*cr, "A", &extents); + _seg_params.x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance; + + } + + g_free(filename); + + /* Fond d'impression */ + + _seg_params.selection_bg.has_color = true; + _seg_params.selection_bg.color.red = 0.5; + _seg_params.selection_bg.color.green = 0.5; + _seg_params.selection_bg.color.blue = 0.5; + _seg_params.selection_bg.color.alpha = 1.0; + + /* Chargement des définitions utiles */ + + void define_rendering_pattern(GtkStyleContext *ctx, const char *name, rendering_pattern_t *pattern) + { + GdkRGBA *tmp_color; /* Description d'une couleur */ + PangoFontDescription *font_desc; /* Description d'une police */ + + gtk_style_context_save(ctx); + + gtk_style_context_add_class(context, name); + + gtk_style_context_get(ctx, GTK_STATE_NORMAL, GTK_STYLE_PROPERTY_COLOR, &tmp_color, NULL); + + pattern->foreground.has_color = true; + pattern->foreground.color = *tmp_color; + + pattern->inverted.has_color = true; + pattern->inverted.color.red = 1.0 - tmp_color->red; + pattern->inverted.color.green = 1.0 - tmp_color->green; + pattern->inverted.color.blue = 1.0 - tmp_color->blue; + pattern->inverted.color.alpha = tmp_color->alpha; + + gdk_rgba_free(tmp_color); + + gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL); + + switch (pango_font_description_get_style(font_desc)) + { + case PANGO_STYLE_NORMAL: + pattern->slant = CAIRO_FONT_SLANT_NORMAL; + break; + case PANGO_STYLE_ITALIC: + pattern->slant = CAIRO_FONT_SLANT_ITALIC; + break; + case PANGO_STYLE_OBLIQUE: + pattern->slant = CAIRO_FONT_SLANT_OBLIQUE; + break; + } + + switch (pango_font_description_get_weight(font_desc)) + { + case PANGO_WEIGHT_THIN: + case PANGO_WEIGHT_ULTRALIGHT: + case PANGO_WEIGHT_LIGHT: + case PANGO_WEIGHT_SEMILIGHT: + case PANGO_WEIGHT_BOOK: + case PANGO_WEIGHT_NORMAL: + case PANGO_WEIGHT_MEDIUM: + pattern->weight = CAIRO_FONT_WEIGHT_NORMAL; + break; + case PANGO_WEIGHT_SEMIBOLD: + case PANGO_WEIGHT_BOLD: + case PANGO_WEIGHT_ULTRABOLD: + case PANGO_WEIGHT_HEAVY: + case PANGO_WEIGHT_ULTRAHEAVY: + pattern->weight = CAIRO_FONT_WEIGHT_BOLD; + break; + } + + pango_font_description_free(font_desc); + + gtk_style_context_restore(context); + + } + + for (i = 0; i < RTT_COUNT; i++) + define_rendering_pattern(context, _segment_names[i], &_seg_params.patterns[i]); + + /* Nettoyages finaux... */ + + gtk_widget_path_free(path); + g_object_unref(context); + + return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* ISOLATION DE CONTENUS PARTAGEABLES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Initialise la table mémorisant les contenus pour segments. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_segment_content_hash_table(void) +{ + _segcnt_htable = g_hash_table_new_full((GHashFunc)get_line_segment_hash, + (GEqualFunc)is_line_segment_equal, + free, NULL); + + return (_segcnt_htable != NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Organise la sortie de la table des contenus pour segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_segment_content_hash_table(void) +{ + assert(g_hash_table_size(_segcnt_htable) == 0); + + g_hash_table_unref(_segcnt_htable); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu pour segment à consulter. * +* * +* Description : Fournit l'empreinte d'un contenu pour segments. * +* * +* Retour : Empreinte de lu contenu représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint get_line_segment_hash(const line_segment *content) +{ + return content->hash; + +} + + +/****************************************************************************** +* * +* Paramètres : content = premier contenu pour segment à analyser. * +* other = second contenu pour segment à analyser. * +* * +* Description : Détermine si deux contenus pour segments sont identiques. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool is_line_segment_equal(const line_segment *content, const line_segment *other) +{ + bool result; /* Résultat à retourner */ + + result = (content->pattern == other->pattern); + + result &= (cmp_fnv_64a(content->hash, other->hash) == 0); + + result &= (strcmp(content->text, other->text) == 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = premier contenu pour segment à analyser. * +* other = second contenu pour segment à analyser. * +* * +* Description : Détermine si deux contenus pour segments sont identiques. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static line_segment *get_shared_segment_content(const line_segment *content) +{ + line_segment *result; /* Contenu partagé à renvoyer */ + gboolean found; /* Le contenu existe déjà ? */ + size_t allocated; /* Besoin complet en mémoire */ +#ifndef NDEBUG + gboolean created; /* Validation de mise en place */ +#endif + + /** + * On considère qu'il n'y a pas besoin de mutex ici, puisque toutes les + * opérations se réalisent à priori dans le seul thread principal pour l'affichage. + */ + + found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL); + + if (!found) + { + allocated = sizeof(line_segment) + strlen(content->text) + 1; + + result = (line_segment *)malloc(allocated); + + memcpy(result, content, allocated); + + result->ref_count = 1; + +#ifndef NDEBUG + created = g_hash_table_insert(_segcnt_htable, result, result); + assert(created); +#else + g_hash_table_insert(_segcnt_htable, result, result); +#endif + + } + + else + { + assert(result->ref_count < UINT_MAX); + + result->ref_count++; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu pour segments à délaisser. * +* * +* Description : Abandonne un contenu pour segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void release_shared_segment_content(line_segment *content) +{ +#ifndef NDEBUG + gboolean deleted; /* Validation de suppression */ +#endif + + /** + * On considère qu'il n'y a pas besoin de mutex ici, puisque toutes les + * opérations se réalisent à priori dans le seul thread principal pour l'affichage. + */ + + if (--content->ref_count == 0) + { +#ifndef NDEBUG + deleted = g_hash_table_remove(_segcnt_htable, content); + assert(deleted); +#else + g_hash_table_remove(_segcnt_htable, content); +#endif + } + +} + + + + +/* ---------------------------------------------------------------------------------- */ +/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : type = propriétés de la zone de texte. * +* text = chaîne de caractères à traiter. * +* length = quantité de ces caractères. * +* * +* Description : Crée un nouveau fragment de texte avec des propriétés. * +* * +* Retour : Elément créé ou recyclé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +line_segment *get_new_line_segment(RenderingTagType type, const char *text, size_t length) +{ + line_segment *result; /* Elément à retourner */ + char atmp[sizeof(line_segment) + 128]; /* Allocation static facile */ + line_segment *content; /* Contenu à mettre en place ? */ + + if (length < (sizeof(atmp) - sizeof(line_segment))) + content = (line_segment *)atmp; + else + content = (line_segment *)malloc(sizeof(line_segment) + length + 1); + + content->pattern = &_seg_params.patterns[type]; + + content->hash = fnv_64a_hash(text); + + memcpy(content->text, text, length); + content->text[length] = '\0'; + + result = get_shared_segment_content(content); + + if (content != (line_segment *)atmp) + free(content); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à libérer de la mémoire. * +* * +* Description : Retire une utilisation à un fragment de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void release_line_segment(line_segment *segment) +{ + release_shared_segment_content(segment); + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* * +* Description : Indique le type de rendu associé à un segment de ligne. * +* * +* Retour : Identifiant de type de rendu. * +* * +* Remarques : - * +* * +******************************************************************************/ + +RenderingTagType get_line_segment_type(const line_segment *segment) +{ + RenderingTagType result; /* Résultat à renvoyer */ + + result = (RenderingTagType)(segment->pattern - _seg_params.patterns); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* markup = indique si le texte doit être décoré ou non. * +* * +* Description : Fournit le texte brut conservé dans le segment. * +* * +* Retour : Texte conservé en interne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *get_line_segment_text(const line_segment *segment, bool markup) +{ + char *result; /* Description à renvoyer */ + char color[7]; /* Couleur hexadécimale */ + char *valid; + + /* Résolution du cas simple */ + if (!markup) + return strdup(segment->text); + + result = strdup("pattern->foreground.color.red * 255), + (unsigned char)(segment->pattern->foreground.color.green * 255), + (unsigned char)(segment->pattern->foreground.color.blue * 255)); + + result = stradd(result, color); + + result = stradd(result, "\""); + + /* Style */ + + result = stradd(result, "style=\""); + + switch (segment->pattern->slant) + { + case CAIRO_FONT_SLANT_NORMAL: + result = stradd(result, "normal"); + break; + + case CAIRO_FONT_SLANT_ITALIC: + result = stradd(result, "italic"); + break; + + case CAIRO_FONT_SLANT_OBLIQUE: + result = stradd(result, "oblique"); + break; + + } + + result = stradd(result, "\""); + + /* Epaisseur */ + + result = stradd(result, "weight=\""); + + switch (segment->pattern->weight) + { + case CAIRO_FONT_WEIGHT_NORMAL: + result = stradd(result, "normal"); + break; + + case CAIRO_FONT_WEIGHT_BOLD: + result = stradd(result, "bold"); + break; + + } + + result = stradd(result, "\""); + + /* Conclusion */ + + result = stradd(result, ">"); + + valid = strdup(segment->text); + valid = strrpl(valid, "<", "<"); + valid = strrpl(valid, "&", "&"); + + result = stradd(result, valid); + + free(valid); + + result = stradd(result, ""); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* * +* Description : Fournit la quantité de pixels requise pour l'impression. * +* * +* Retour : Largeur requise par la colonne, en pixel. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint get_line_segment_width(const line_segment *segment) +{ + gint result; /* Largeur à retourner */ + cairo_font_slant_t slant; /* Style d'impression */ + cairo_font_weight_t weight; /* Poids de la police */ + + slant = segment->pattern->slant; + weight = segment->pattern->weight; + + result = _seg_params.x_advances[CAIRO_FONT_INDEX(slant, weight)] * strlen(segment->text); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à consulter. * +* x = position horizontale au niveau du segment. * +* * +* Description : Fournit la position idéale pour un marqueur. * +* * +* Retour : Position dans le segment donné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint get_caret_position_from_line_segment(const line_segment *segment, gint x) +{ + gint result; /* Position à retourner */ + gint width; /* Largeur du segment */ + gint char_width; /* Largeur de police fixe */ + + width = get_line_segment_width(segment); + + if (x <= 0) + result = 0; + + else if (x >= width) + result = width; + + else + { + char_width = width / strlen(segment->text); + + result = (x / char_width) * char_width; + if ((x % char_width) > (char_width / 2)) + result += char_width; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à manipuler. * +* x = position du curseur à faire évoluer. [OUT] * +* ctrl = indique la demande d'un parcours rapide. * +* dir = direction du parcours. * +* * +* Description : Déplace le curseur au sein d'un segment de tampon. * +* * +* Retour : true si un déplacement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool move_caret_on_line_segment(const line_segment *segment, gint *x, bool ctrl, GdkScrollDirection dir) +{ + bool result; /* Bilan d'opération à renvoyer*/ + gint width; /* Largeur du segment */ + gint char_width; /* Largeur de police fixe */ + + result = false; + + width = get_line_segment_width(segment); + char_width = width / strlen(segment->text); + + if (dir == GDK_SCROLL_LEFT) + { + if (*x > width) *x = width + char_width; + + if (*x == 0) goto gbsmc_done; + + if (ctrl) *x = 0; + else *x = MAX(0, *x - char_width); + + result = true; + + } + + else if (dir == GDK_SCROLL_RIGHT) + { + if (*x == width) goto gbsmc_done; + + if (ctrl) *x = width; + else *x = MIN(width, *x + char_width); + + result = true; + + } + + gbsmc_done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à manipuler. * +* cr = contexte graphique à utiliser pour les pinceaux. * +* x = abscisse du point d'impression (à maj). [OUT] * +* y = ordonnée du point d'impression. * +* list = liste de contenus à mettre en évidence. * +* * +* Description : Imprime le fragment de texte représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void draw_line_segment(const line_segment *segment, cairo_t *cr, gint *x, gint y, const segcnt_list *list) +{ + bool selected; /* Marquer une sélection ? */ + gint width; /* Largeur du segment */ + cairo_operator_t old; /* Sauvegarde avant changement */ + const rendering_color_t *used_fg; /* Couleur d'impression utile */ + + selected = selection_list_has_segment_content(list, segment); + + width = get_line_segment_width(segment); + + /* Fond du texte */ + if (selected) + { + cairo_set_source_rgba(cr, + _seg_params.selection_bg.color.red, + _seg_params.selection_bg.color.green, + _seg_params.selection_bg.color.blue, + _seg_params.selection_bg.color.alpha); + + cairo_rectangle(cr, *x, y, width, 17); + + old = cairo_get_operator(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); + cairo_fill(cr); + cairo_set_operator(cr, old); + + } + + /* Couleur d'impression */ + + if (selected) + used_fg = &segment->pattern->inverted; + else + used_fg = &segment->pattern->foreground; + + if (used_fg->has_color) + cairo_set_source_rgba(cr, + used_fg->color.red, + used_fg->color.green, + used_fg->color.blue, + used_fg->color.alpha); + else + cairo_set_source_rgb(cr, 0, 0, 0); + + /* Impression du texte */ + + cairo_select_font_face(cr, "mono", segment->pattern->slant, segment->pattern->weight); + cairo_set_font_size(cr, 13); + + cairo_move_to(cr, *x, y + 17 - 3); /* 3 = font extents.descent */ + + cairo_show_text(cr, segment->text); + + *x += width; + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = éléments à disposition pour l'exportation. * +* type = type d'exportation attendue. * +* * +* Description : Exporte tous les styles utilisés par des segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void export_line_segment_style(buffer_export_context *ctx, BufferExportType type) +{ + size_t i; /* Boucle de parcours */ + const rendering_pattern_t *pattern; /* Modèle à transcrire */ + + for (i = 0; i < RTT_COUNT; i++) + { + pattern = &_seg_params.patterns[i]; + + switch (type) + { + case BET_HTML: + + dprintf(ctx->fd, ".%s {\n", _segment_names[i]); + + if (pattern->foreground.has_color) + dprintf(ctx->fd, "\tcolor: #%02hhx%02hhx%02hhx;\n", + (unsigned char)(pattern->foreground.color.red * 255), + (unsigned char)(pattern->foreground.color.green * 255), + (unsigned char)(pattern->foreground.color.blue * 255)); + + switch (pattern->slant) + { + case CAIRO_FONT_SLANT_ITALIC: + dprintf(ctx->fd, "\tfont-style: italic;\n"); + break; + case CAIRO_FONT_SLANT_OBLIQUE: + dprintf(ctx->fd, "\tfont-style: oblique;\n"); + break; + default: + dprintf(ctx->fd, "\tfont-style: normal;\n"); + break; + } + + switch (pattern->weight) + { + case CAIRO_FONT_WEIGHT_BOLD: + dprintf(ctx->fd, "\tfont-weight: bold;\n"); + break; + default: + dprintf(ctx->fd, "\tfont-weight: normal;\n"); + break; + } + + dprintf(ctx->fd, "}\n"); + + break; + + default: + break; + + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à manipuler. * +* ctx = éléments à disposition pour l'exportation. * +* type = type d'exportation attendue. * +* * +* Description : Exporte le fragment de texte représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void export_line_segment(const line_segment *segment, buffer_export_context *ctx, BufferExportType type) +{ + size_t index; /* Indice du modèle de rendu */ + + switch (type) + { + case BET_HTML: + index = (segment->pattern - _seg_params.patterns); + dprintf(ctx->fd, "", _segment_names[index]); + break; + default: + break; + } + + dprintf(ctx->fd, "%s", segment->text); + + switch (type) + { + case BET_HTML: + dprintf(ctx->fd, ""); + break; + default: + break; + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION OPTIMALE D'UNE LISTE DE CONTENUS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Initilise une liste de contenus de segments. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +segcnt_list *init_segment_content_list(void) +{ + segcnt_list *result; /* Structure à retourner */ + + result = (segcnt_list *)calloc(1, sizeof(segcnt_list)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à traiter. * +* * +* Description : Libère la mémoire occupée par une liste de contenus. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_segment_content_list(segcnt_list *list) +{ + reset_segment_content_list(list); + + free(list); + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à manipuler. * +* * +* Description : Vide, si besoin est, une liste de contenus de segments. * +* * +* Retour : true si des éléments ont été purgés, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool reset_segment_content_list(segcnt_list *list) +{ + bool result; /* Bilan d'action à renvoyer */ + + result = (list->count > 0); + + if (list->hashes != NULL) + { + free(list->hashes); + list->hashes = NULL; + } + + list->count = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à manipuler. * +* segment = fragment de texte à conservr. * +* * +* Description : Marque le contenu d'un segment comme remarquable. * +* * +* Retour : true si la liste a été complétée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_segment_content_to_selection_list(segcnt_list *list, const line_segment *segment) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + static const char white_list[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + result = false; + + for (i = 0; i < (sizeof(white_list) - 1) && !result; i++) + result = (strchr(segment->text, white_list[i]) != NULL); + + if (result) + { + list->hashes = (fnv64_t *)realloc(list->hashes, ++list->count * sizeof(fnv64_t)); + + list->hashes[list->count - 1] = segment->hash; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de références de contenus à consulter. * +* segment = fragment de texte à comparer. * +* * +* Description : Indique si le contenu d'un segment est notable ou non. * +* * +* Retour : true si le segment a un contenu présent dans la sélection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool selection_list_has_segment_content(const segcnt_list *list, const line_segment *segment) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = false; + + for (i = 0; i < list->count && !result; i++) + result = (cmp_fnv_64a(list->hashes[i], segment->hash) == 0); + + return result; + +} diff --git a/src/glibext/linesegment.h b/src/glibext/linesegment.h new file mode 100644 index 0000000..7a5551d --- /dev/null +++ b/src/glibext/linesegment.h @@ -0,0 +1,196 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * linesegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes + * + * Copyright (C) 2010-2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GLIBEXT_LINESEGMENT_H +#define _GLIBEXT_LINESEGMENT_H + + +#include +#include +#include +#include + + + +/* Liste identifiant un ensemble de segments */ +typedef struct _segcnt_list segcnt_list; + + + +/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ + + +/* Procède à l'initialisation des paramètres de rendu de texte. */ +bool load_segment_rendering_parameters(void); + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +typedef struct _line_segment line_segment; + + +/* Initialise la table mémorisant les contenus pour segments. */ +bool init_segment_content_hash_table(void); + +/* Organise la sortie de la table des contenus pour segments. */ +void exit_segment_content_hash_table(void); + + + +/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ + + +/* Types de partie de rendu */ +typedef enum _RenderingTagType +{ + RTT_RAW, /* Contenu brut */ + + RTT_COMMENT, /* Commentaire */ + RTT_INDICATION, /* Aide à la lecture */ + + RTT_PHYS_ADDR_PAD, /* Position physique (début) */ + RTT_PHYS_ADDR, /* Position physique */ + RTT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */ + RTT_VIRT_ADDR, /* Adresse virtuelle */ + RTT_RAW_CODE, /* Code binaire brut */ + + RTT_LABEL, /* Etiquette sur une adresse */ + + RTT_INSTRUCTION, /* Code binaire brut */ + + RTT_IMMEDIATE, /* Valeur immédiate */ + + RTT_REGISTER, /* Registre */ + + RTT_PUNCT, /* Signes de ponctuation */ + RTT_HOOK, /* Crochets '[' et ']' */ + RTT_SIGNS, /* Signes '+', '-' et '*' */ + RTT_LTGT, /* Caractères '<' et '>' */ + + RTT_SECTION, /* Identifiant de section */ + RTT_SEGMENT, /* Indication de segment */ + RTT_STRING, /* Chaîne de caractères avec " */ + + RTT_VAR_NAME, /* Nom de variable */ + + RTT_KEY_WORD, /* Mot clef de langage */ + + RTT_ERROR, /* Erreur "interne" */ + + RTT_COUNT + +} RenderingTagType; + + +/* Crée un nouveau fragment de texte avec des propriétés. */ +line_segment *get_new_line_segment(RenderingTagType, const char *, size_t); + +/* Retire une utilisation à un fragment de texte. */ +void release_line_segment(line_segment *); + +/* Indique le type de rendu associé à un segment de ligne. */ +RenderingTagType get_line_segment_type(const line_segment *); + +/* Fournit le texte brut conservé dans le segment. */ +char *get_line_segment_text(const line_segment *, bool); + +/* Fournit la quantité de pixels requise pour l'impression. */ +gint get_line_segment_width(const line_segment *); + +/* Fournit la position idéale pour un marqueur. */ +gint get_caret_position_from_line_segment(const line_segment *, gint); + +/* Déplace le curseur au sein d'un segment de tampon. */ +bool move_caret_on_line_segment(const line_segment *, gint *, bool, GdkScrollDirection); + +/* Imprime le fragment de texte représenté. */ +void draw_line_segment(const line_segment *, cairo_t *, gint *, gint, const segcnt_list *); + +/* Types d'exportation */ +typedef enum _BufferExportType +{ + BET_TEXT, /* Exportation en texte brut */ + BET_HTML, /* Exportation en HTML */ + + BET_COUNT + +} BufferExportType; + +/* Elements sur lesquels une exportation peut s'appuyer */ +typedef struct _buffer_export_context +{ + union + { + int fd; /* Flux ouvert en écriture */ + + }; + + union + { + /* BET_TEXT */ + const char *sep; /* Séparation entre colonnes */ + + /* BET_HTML */ + struct + { + const char *font_name; /* Police d'impression */ + const char *bg_color; /* Fond du tableau HTML */ + + }; + + }; + +} buffer_export_context; + +/* Exporte tous les styles utilisés par des segments. */ +void export_line_segment_style(buffer_export_context *, BufferExportType); + +/* Exporte le fragment de texte représenté. */ +void export_line_segment(const line_segment *, buffer_export_context *, BufferExportType); + + + +/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ + + +/* Initilise une liste de contenus de segments. */ +segcnt_list *init_segment_content_list(void); + +/* Libère la mémoire occupée par une liste de contenus. */ +void exit_segment_content_list(segcnt_list *); + +/* Vide, si besoin est, une liste de contenus de segments. */ +bool reset_segment_content_list(segcnt_list *); + +/* Marque le contenu d'un segment comme remarquable. */ +bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *); + +/* Indique si le contenu d'un segment est notable ou non. */ +bool selection_list_has_segment_content(const segcnt_list *, const line_segment *); + + + +#endif /* _GLIBEXT_LINESEGMENT_H */ diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index 2d1b51c..ea5d023 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -686,8 +686,11 @@ static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y, if (creator != NULL) g_object_unref(creator); + /* + FIXME : ref() ! if (line != NULL) g_object_unref(G_OBJECT(line)); + */ return result; diff --git a/src/gui/core/core.c b/src/gui/core/core.c index dbff1b8..c2a235f 100644 --- a/src/gui/core/core.c +++ b/src/gui/core/core.c @@ -28,7 +28,7 @@ #include "../../core/params.h" -#include "../../glibext/gbuffersegment.h" +#include "../../glibext/linesegment.h" @@ -48,7 +48,9 @@ bool load_all_gui_components(GObject *ref) { bool result; /* Bilan à retourner */ - result = init_segment_content_hash_table(); + result = load_segment_rendering_parameters(); + + result &= init_segment_content_hash_table(); if (result) load_main_panels(ref); diff --git a/src/gui/dialogs/export.c b/src/gui/dialogs/export.c index 0d7a12b..5f05031 100644 --- a/src/gui/dialogs/export.c +++ b/src/gui/dialogs/export.c @@ -338,7 +338,7 @@ static void do_binary_export(GCodeBuffer *buffer, const vmpa2t *start, const vmp dprintf(ctx->fd, "\tpadding-left: 8px;\n"); dprintf(ctx->fd, "\tpadding-right: 8px;\n"); dprintf(ctx->fd, "}\n"); - g_buffer_segment_export_style(ctx, type); + export_line_segment_style(ctx, type); dprintf(ctx->fd, "\n"); dprintf(ctx->fd, "\n"); break; -- cgit v0.11.2-87-g4458