Word Unperfect
public
Read
Owner: themaster
Branch: main
Commits: 0
Git CLI clone URL
git clone https://www.xt-emporium.com/git/word-unperfect.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
word-unperfect
/
rev
/
wp_parser_command.c
File editor
#include "wp_parser_command.h" #include "wp_control_codes.h" #include "wp_variable_codes.h" #include <string.h> static void wp_parser_command_count_status(const WpRecord *rec, WpParserCommandStats *stats) { if (rec == NULL || stats == NULL) { return; } if (!rec->is_complete && !rec->trailer_present) { stats->incomplete_records++; } if (rec->trailer_present && !rec->trailer_matches) { stats->mismatched_trailers++; } } const char *wp_parser_command_class_name(WpParserCommandClass command_class) { switch (command_class) { case WP_PARSER_COMMAND_TEXT: return "text byte"; case WP_PARSER_COMMAND_SINGLE_CONTROL: return "single-byte control"; case WP_PARSER_COMMAND_FIXED_PACKET: return "fixed command packet"; case WP_PARSER_COMMAND_VARIABLE_PACKET: return "variable command packet"; default: return "unknown"; } } const char *wp_parser_command_exempt_reason_name(WpParserCommandExemptReason reason) { switch (reason) { case WP_PARSER_COMMAND_EXEMPT_SOFT_PAGE_83: return "0x83 soft-page command"; case WP_PARSER_COMMAND_EXEMPT_FIXED_C6: return "0xC6 fixed command"; case WP_PARSER_COMMAND_EXEMPT_LAYOUT_D4: return "0xD4 layout-state command"; case WP_PARSER_COMMAND_EXEMPT_NONE: default: return "none"; } } void wp_parser_command_stats_clear(WpParserCommandStats *stats) { if (stats != NULL) { memset(stats, 0, sizeof(*stats)); } } bool wp_parser_command_plan_record(const WpRecord *rec, WpParserCommandPlan *out_plan) { WpParserCommandPlan plan; if (out_plan != NULL) { memset(out_plan, 0, sizeof(*out_plan)); } if (rec == NULL) { return false; } memset(&plan, 0, sizeof(plan)); plan.code = rec->code; plan.sub_code = rec->sub_code; plan.commanded_record_bytes = rec->length; if (rec->length > 0U) { plan.bytes_to_skip_after_lead = (uint16_t)(rec->length - 1U); } switch (rec->type) { case WP_CODE_CHAR: plan.command_class = WP_PARSER_COMMAND_TEXT; break; case WP_CODE_SINGLE_BYTE: plan.command_class = WP_PARSER_COMMAND_SINGLE_CONTROL; break; case WP_CODE_FIXED_LENGTH: plan.command_class = WP_PARSER_COMMAND_FIXED_PACKET; plan.uses_fixed_normalize_path = true; break; case WP_CODE_VARIABLE_LENGTH: plan.command_class = WP_PARSER_COMMAND_VARIABLE_PACKET; plan.uses_variable_skip_path = true; if (rec->code == 0xD4U) { plan.refreshes_d4_length_word = true; } break; default: return false; } /* Port of parser_parse_and_append_command_token_variant @ 1000:2f63: * after the variant-balance call, the consumed byte marks parser/layout * dirty unless it is exactly D4, C6, or 83. */ if (wp_control_has_effect(rec->code, WP_CONTROL_EFFECT_DIRTY_EXEMPT)) { if (rec->code == 0x83U) { plan.exempt_reason = WP_PARSER_COMMAND_EXEMPT_SOFT_PAGE_83; } else if (rec->code == 0xC6U) { plan.exempt_reason = WP_PARSER_COMMAND_EXEMPT_FIXED_C6; } else if (rec->code == 0xD4U) { plan.exempt_reason = WP_PARSER_COMMAND_EXEMPT_LAYOUT_D4; } } else { plan.marks_parser_dirty = true; plan.parser_runtime_or = 0x08U; plan.secondary_stream_or = 0x05U; plan.layout_runtime_or = 0x08U; } if (rec->type == WP_CODE_VARIABLE_LENGTH) { WpVariableCommandInfo info; if (wp_variable_classify_record(rec, &info)) { plan.scanner_bypass = info.scanner_bypass; if (info.has_post_compare_plan) { plan.has_post_compare_plan = true; plan.repeat_dispatch = (info.post_compare.flags & WP_VARIABLE_POST_REPEAT_DISPATCH) != 0U; plan.extension_scan = info.post_compare.extension_scan; plan.refcount_increment = info.post_compare.refcount_increment; plan.refcount_decrement = info.post_compare.refcount_decrement; plan.has_repeat_count = info.post_compare.has_repeat_count; plan.repeat_count = info.post_compare.repeat_count; plan.repeat_count_offset = info.post_compare.repeat_count_offset; plan.repeat_count_offset_valid = info.post_compare.repeat_count_offset_valid; } } } if (out_plan != NULL) { *out_plan = plan; } return true; } void wp_parser_command_apply_plan(WpLayoutGlobals *runtime, const WpParserCommandPlan *plan, WpParserCommandStats *stats) { uint16_t iterations; if (plan == NULL || stats == NULL) { return; } switch (plan->command_class) { case WP_PARSER_COMMAND_TEXT: stats->text_records++; break; case WP_PARSER_COMMAND_SINGLE_CONTROL: stats->single_control_records++; break; case WP_PARSER_COMMAND_FIXED_PACKET: stats->fixed_command_records++; break; case WP_PARSER_COMMAND_VARIABLE_PACKET: stats->variable_command_records++; break; default: break; } if (plan->marks_parser_dirty) { stats->dirty_mark_records++; if (runtime != NULL) { runtime->parser_runtime_flags |= plan->parser_runtime_or; runtime->secondary_stream_flags_54a6 |= plan->secondary_stream_or; runtime->runtime_flags |= plan->layout_runtime_or; } } else { stats->dirty_exempt_records++; switch (plan->exempt_reason) { case WP_PARSER_COMMAND_EXEMPT_SOFT_PAGE_83: stats->dirty_exempt_soft_page_83++; break; case WP_PARSER_COMMAND_EXEMPT_FIXED_C6: stats->dirty_exempt_fixed_c6++; break; case WP_PARSER_COMMAND_EXEMPT_LAYOUT_D4: stats->dirty_exempt_layout_d4++; break; case WP_PARSER_COMMAND_EXEMPT_NONE: default: break; } } if (plan->uses_fixed_normalize_path) { stats->fixed_normalize_paths++; } if (plan->uses_variable_skip_path) { stats->variable_skip_paths++; } if (plan->refreshes_d4_length_word) { stats->d4_length_refreshes++; } stats->command_skip_bytes += plan->bytes_to_skip_after_lead; if (plan->scanner_bypass) { stats->scanner_bypass_packets++; } if (plan->has_post_compare_plan) { stats->post_compare_packets++; if (runtime != NULL) { runtime->parser_runtime_flags |= 0x08U; } } if (plan->repeat_dispatch) { stats->repeat_dispatch_packets++; iterations = plan->has_repeat_count ? plan->repeat_count : 1U; stats->repeat_dispatch_iterations += iterations; if (plan->code == 0xD5U) { stats->d5_repeat_packets++; } else if (plan->code == 0xD6U) { stats->d6_repeat_packets++; } else if (plan->code == 0xDAU) { stats->da_object_dispatch_packets++; } /* parser_parse_and_append_command_token_variant dispatches repeated * parser calls through one of two far-call routes depending on the high * bit of layout_refcount_44c6. The host pass cannot jump overlays, but * it preserves the observable branch and iteration count. */ if (runtime != NULL && ((uint8_t)runtime->layout_refcount_44c6 & 0x80U) != 0U) { stats->repeat_dispatch_alt_iterations += iterations; } else { stats->repeat_dispatch_main_iterations += iterations; } } if (plan->extension_scan) { stats->extension_scan_packets++; if (runtime != NULL && runtime->record_extension_block_count != 0U) { runtime->parse_dirty_flags |= 0x08U; stats->extension_scan_dirty_sets++; } } if (plan->refcount_increment) { stats->db_refcount_packets++; stats->refcount_increment_packets++; if (runtime != NULL) { runtime->layout_refcount_44c6++; } } else if (plan->refcount_decrement) { stats->db_refcount_packets++; stats->refcount_decrement_packets++; if (runtime != NULL) { runtime->layout_refcount_44c6--; } } if (plan->has_post_compare_plan && runtime != NULL) { runtime->parse_dirty_flags |= 0x02U; } } bool wp_parser_command_apply_record(WpLayoutGlobals *runtime, const WpRecord *rec, WpParserCommandStats *stats) { WpParserCommandPlan plan; if (rec == NULL || stats == NULL) { return false; } if (!wp_parser_command_plan_record(rec, &plan)) { return false; } stats->records_seen++; stats->bytes_consumed += rec->length; wp_parser_command_count_status(rec, stats); wp_parser_command_apply_plan(runtime, &plan, stats); return true; } bool wp_parser_command_run_stream(WpLayoutGlobals *wl, WpParserCommandStats *stats) { WpLayoutGlobals cursor; WpLayoutGlobals runtime; WpParserCommandStats local_stats; bool ok = true; if (wl == NULL || stats == NULL) { return false; } wp_parser_command_stats_clear(&local_stats); cursor = *wl; runtime = *wl; while (cursor.record_used_bytes > 0) { WpRecord rec; int before = cursor.record_used_bytes; wp_parser_consume_record(&cursor, &rec); if (rec.length == 0U || cursor.record_used_bytes >= before) { wp_record_free(&rec); ok = false; break; } if (!wp_parser_command_apply_record(&runtime, &rec, &local_stats)) { ok = false; } wp_record_free(&rec); } local_stats.final_parser_runtime_flags = runtime.parser_runtime_flags; local_stats.final_secondary_stream_flags = runtime.secondary_stream_flags_54a6; local_stats.final_runtime_flags = runtime.runtime_flags; local_stats.final_parse_dirty_flags = runtime.parse_dirty_flags; local_stats.final_layout_refcount = (int)runtime.layout_refcount_44c6; *stats = local_stats; return ok && local_stats.incomplete_records == 0U && local_stats.mismatched_trailers == 0U; } bool wp_parser_command_run_loaded_file(WpLoadedFile *file, WpParserCommandStats *stats) { WpLayoutGlobals wl; if (file == NULL || stats == NULL) { return false; } memset(&wl, 0, sizeof(wl)); if (!wp_file_bind_primary_stream(file, &wl, 4096U)) { return false; } return wp_parser_command_run_stream(&wl, stats); } bool wp_parser_command_run_file(const char *filename, WpParserCommandStats *stats) { WpLoadedFile file; bool ok; if (filename == NULL || stats == NULL) { return false; } if (!wp_file_load_body(filename, &file)) { return false; } ok = wp_parser_command_run_loaded_file(&file, stats); wp_file_free(&file); return ok; }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
main
Visibility
public
Your access
Read
Remote
None
File activity
View file history