From 848f144ab976a8cefebb029052c207cdfeb34968 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 14:42:27 -0700 Subject: [PATCH] distinguish between expr strings and code strings in schemas; use normal autocompletion in meta-evaluation spaces only when editing expr strings, whereas code strings you want to look like code but do not generally refer to things that expressions can, e.g. it is a label --- src/raddbg/generated/raddbg.meta.c | 22 ++++++++--------- src/raddbg/raddbg.mdesk | 38 +++++++++++++++--------------- src/raddbg/raddbg_core.c | 28 ++++++++++++++++------ src/raddbg/raddbg_eval.c | 3 ++- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 125914fd..2669a578 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -411,19 +411,19 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': code_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, -{str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, -{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': code_string,\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, +{str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, -{str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':code_string, 'expr':code_string}")}, +{str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index db258abe..5851ebe6 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -448,7 +448,7 @@ RD_VocabTable: 'row_height': @range[1.75f, 5.f] f32, 'label': code_string, @description("The root expression which is evaluated to produce the watch window.") - 'expression': code_string, + 'expression': expr_string, @no_expand 'watches': query, } ``` @@ -459,7 +459,7 @@ RD_VocabTable: @inherit(tab) x: { @description("An expression to describe data which should be viewed as text or code.") - 'expression': code_string, + 'expression': expr_string, @description("The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.") 'lang': code_string, @default(1) @description("Controls whether or not line numbers are shown.") @@ -475,10 +475,10 @@ RD_VocabTable: @inherit(tab) x: { @description("An expression to describe the base address or offset of the disassembly.") - 'expression': code_string, + 'expression': expr_string, 'arch': code_string, 'syntax': code_string, - 'size': code_string, + 'size': expr_string, @default(1) @description("Controls whether or not addresses are shown in the disassembly text.") 'show_addresses': bool, @default(0) @description("Controls whether or not code bytes are shown in the disassembly text.") @@ -498,11 +498,11 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Base Address") @description("An expression to describe the base address or offset of the memory view.") - 'expression': code_string, + 'expression': expr_string, @display_name("Address Range Size") @description("The number of bytes of the viewed memory range.") - 'size': code_string, + 'size': expr_string, @display_name("Cursor Address") @description("The address of the cursor.") - 'cursor': code_string, + 'cursor': expr_string, @display_name("Cursor Size") @description("The size, in bytes, of the cursor.") 'cursor_size': @range[1, 16] u64, @default(16) @description("The number of columns to build before building new rows.") @@ -516,7 +516,7 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Base Pointer") @description("An expression to describe the base address or offset of the bitmap data.") - 'expression': code_string, + 'expression': expr_string, @order(0) 'w': u64, @order(1) 'h': u64, @display_name("Bitmap Format") @description("The pixel format that the bitmap data should be interpreted as being within.") @@ -530,7 +530,7 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Value") @description("An expression to describe the value or location of the color.") - 'expression': code_string, + 'expression': expr_string, } ``` } @@ -540,10 +540,10 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Expression") @description("An expression to describe the base address of the index buffer.") - 'expression': code_string, - 'count': code_string, - 'vtx': code_string, - 'vtx_size': code_string, + 'expression': expr_string, + 'count': expr_string, + 'vtx': expr_string, + 'vtx_size': expr_string, 'yaw': @range[0, 1] f32, 'pitch': @range[-0.5, 0] f32, 'zoom': @range[0, 100] f32, @@ -573,7 +573,7 @@ RD_VocabTable: 'executable': path, 'arguments': string, 'working_directory': path, - 'entry_point': code_string, + 'entry_point': expr_string, 'stdout_path': path, 'stderr_path': path, 'stdin_path': path, @@ -593,9 +593,9 @@ RD_VocabTable: x: { 'label': code_string, - 'condition': code_string, + 'condition': expr_string, 'source_location': string, - 'address_location': code_string, + 'address_location': expr_string, 'hit_count': u64, 'address_range_size': @or(0, 1, 2, 4, 8) u64, 'break_on_write': bool, @@ -614,9 +614,9 @@ RD_VocabTable: @collection_commands(add_watch_pin, toggle_watch_pin) x: { - 'expression': code_string, + 'expression': expr_string, 'source_location': string, - 'address_location': code_string, + 'address_location': expr_string, } ```, } @@ -630,7 +630,7 @@ RD_VocabTable: //- rjf: type views { type_view, - ```@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':code_string, 'expr':code_string}```, + ```@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}```, } //- rjf: recent projects diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bbc2a650..20dd15e7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1846,6 +1846,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) String8 child_type_name = child_schema->first->string; if(str8_match(child_type_name, str8_lit("path"), 0) || str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("expr_string"), 0) || str8_match(child_type_name, str8_lit("string"), 0)) { read_data = cfg->first->string; @@ -9736,18 +9737,31 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) String8 list_expr = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); { E_TypeKey maybe_enum_type = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); - if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg && str8_match(e_string_from_id(dst_eval.space.u64s[1]), str8_lit("theme"), 0)) + if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - list_expr = str8_lit("query:themes"); - expr_based_replace = 0; - force_allow = 1; + RD_Cfg *parent = rd_cfg_from_eval_space(dst_eval.space); + String8 child_key = e_string_from_id(dst_eval.space.u64s[1]); + MD_NodePtrList schemas = rd_schemas_from_name(parent->string); + MD_Node *child_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; n != 0 && md_node_is_nil(child_schema); n = n->next) + { + child_schema = md_child_from_string(n->v, child_key, 0); + } + if(str8_match(child_key, str8_lit("theme"), 0)) + { + list_expr = str8_lit("query:themes"); + expr_based_replace = 0; + force_allow = 1; + } + else if(!str8_match(child_schema->first->string, str8_lit("expr_string"), 0)) + { + MemoryZeroStruct(&list_expr); + } } -#if 0 else if(e_type_kind_from_key(maybe_enum_type) == E_TypeKind_Enum) { - list_expr = e_type_string_from_key(arena, maybe_enum_type); + list_expr = e_type_string_from_key(scratch.arena, maybe_enum_type); } -#endif } // rjf: determine if autocompletion lister is allowed diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 84df2423..6317af59 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -322,7 +322,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) } //- rjf: cfg members - else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) + else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0) || + str8_match(child_schema->first->string, str8_lit("expr_string"), 0)) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); }