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_format_executor.c
File editor
#include "wp_format_executor.h" #include "wp_format_gate.h" #include "wp_fixed_codes.h" #include "wp_layout_metrics.h" #include "wp_layout_status.h" #include "wp_control_codes.h" #include "wp_nested_stream.h" #include "wp_record_parser.h" #include "wp_variable_codes.h" #include <string.h> static uint16_t wp_format_next_tab_stop(uint16_t column, uint8_t tab_width) { uint16_t width = tab_width == 0U ? 8U : tab_width; uint16_t next = (uint16_t)(((uint16_t)(column / width) + 1U) * width); if (next <= column) { return (uint16_t)(column + 1U); } return next; } static void wp_format_note_column(WpFormatExecutorStats *stats) { if (stats != NULL && stats->current_column > stats->max_column) { stats->max_column = stats->current_column; } } static void wp_format_advance_column(WpFormatExecutorStats *stats, const WpFormatExecutorOptions *options, uint16_t columns) { if (stats == NULL) { return; } stats->current_column = (uint16_t)(stats->current_column + columns); wp_format_note_column(stats); if (options != NULL && options->wrap_column != 0U) { while (stats->current_column >= options->wrap_column) { stats->soft_wraps++; stats->lines_seen++; stats->current_column = (uint16_t)(stats->current_column - options->wrap_column); } } } static void wp_format_new_line(WpFormatExecutorStats *stats) { if (stats == NULL) { return; } stats->lines_seen++; stats->current_column = 0U; } static void wp_format_new_page(WpFormatExecutorStats *stats) { if (stats == NULL) { return; } stats->pages_seen++; stats->lines_seen++; stats->current_column = 0U; } static void wp_format_count_record_status(const WpRecord *rec, WpFormatExecutorStats *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++; } } static void wp_format_merge_nested_stats(WpFormatExecutorStats *stats, const WpNestedStreamStats *nested) { if (stats == NULL || nested == NULL) { return; } stats->nested_streams_analyzed += nested->streams_seen; stats->nested_stream_records += nested->records_seen; stats->nested_stream_bytes += nested->bytes_consumed; stats->nested_stream_fixed_codes += nested->fixed_length_codes; stats->nested_stream_variable_codes += nested->variable_length_codes; stats->nested_stream_char_records += nested->char_records; stats->nested_stream_d4_layout_states += nested->d4_layout_state_records; stats->nested_stream_post_compare_packets += nested->variable_repeat_dispatch_packets + nested->variable_extension_scan_packets + nested->variable_refcount_increment_packets + nested->variable_refcount_decrement_packets; stats->nested_stream_repeat_total += nested->variable_repeat_total; if (nested->max_depth_seen > stats->nested_stream_max_depth) { stats->nested_stream_max_depth = nested->max_depth_seen; } stats->nested_stream_recursion_limit_hit = stats->nested_stream_recursion_limit_hit || nested->recursion_limit_hit; stats->nested_stream_parse_gap = stats->nested_stream_parse_gap || nested->stopped_on_parse_gap; stats->nested_stream_allocation_failed = stats->nested_stream_allocation_failed || nested->allocation_failed; } static void wp_format_record_extent_result(WpFormatExecutorStats *stats, const WpLayoutExtentResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_measure_calls++; if (result->heap_window_used) { stats->layout_measure_heap_windows++; } if (result->clamped_to_emit_extent) { stats->layout_measure_clamped++; } if (result->measure_extent > stats->layout_max_measure_extent) { stats->layout_max_measure_extent = result->measure_extent; } if (result->measure_bound > stats->layout_max_measure_bound) { stats->layout_max_measure_bound = result->measure_bound; } } static void wp_format_record_reconcile_result(WpFormatExecutorStats *stats, const WpLayoutReconcileResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_reconcile_calls++; if (result->span_word_changed) { stats->layout_reconcile_span_changes++; } if (result->cursor_word_changed) { stats->layout_reconcile_cursor_changes++; } } static void wp_format_record_variant_result(WpFormatExecutorStats *stats, const WpLayoutVariantResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_variant_adjustments++; if (result->parse_dirty_set) { stats->layout_variant_dirty_sets++; } } static void wp_format_record_balance_result(WpFormatExecutorStats *stats, const WpLayoutVariantBalanceResult *result) { if (stats == NULL || result == NULL) { return; } if (result->reset_total) { stats->layout_variant_total_resets++; } if (result->add_path) { stats->layout_variant_balance_adds++; } if (result->subtract_path) { stats->layout_variant_balance_subtracts++; } if (result->balance_clamped_to_screen) { stats->layout_variant_balance_clamps++; } if (result->heap_borrowed) { stats->layout_variant_heap_borrows++; } if (result->variant_limit_updated) { stats->layout_variant_limit_updates++; } if (result->variant_limit_overflowed) { stats->layout_variant_limit_overflows++; } if (result->far_refresh_would_run) { stats->layout_variant_far_refreshes++; } if (result->secondary_probe_would_run) { stats->layout_variant_secondary_probes++; } } static void wp_format_record_span_reset_result(WpFormatExecutorStats *stats, const WpLayoutMeasuredSpanResetResult *result) { if (stats == NULL || result == NULL || !result->cursor_changed) { return; } stats->layout_measured_span_resets++; if (result->span_a_raised) { stats->layout_measured_span_a_raises++; } if (result->span_b_raised) { stats->layout_measured_span_b_raises++; } if (result->dirty_flags_marked || result->total_flags_marked) { stats->layout_measured_span_dirty_marks++; } } static void wp_format_record_heap_branch_result(WpFormatExecutorStats *stats, const WpLayoutHeapBranchResult *result) { if (stats == NULL || result == NULL || !result->window_changed) { return; } stats->layout_heap_branch_runs++; if (result->measure_ran) { stats->layout_heap_branch_measure_runs++; wp_format_record_extent_result(stats, &result->measure_result); } } static void wp_format_record_flush_span_result(WpFormatExecutorStats *stats, const WpLayoutFlushSpanResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_span_flushes++; if (result->variant_gate_would_trap) { stats->layout_span_flush_variant_traps++; } } static void wp_format_record_status_dirty_result(WpFormatExecutorStats *stats, const WpLayoutStatusDirtyResult *result) { if (stats == NULL || result == NULL) { return; } if (result->gate.gate_alloc_would_run || result->gate.variant_batch_would_run) { stats->layout_emit_gate_resets++; } if (result->dirty_mask_applied) { stats->layout_status_dirty_pulses++; } } static void wp_format_record_display_update_result(WpFormatExecutorStats *stats, const WpLayoutDisplayUpdateResult *result) { if (stats == NULL || result == NULL) { return; } if (result->refresh_would_run) { stats->layout_display_refreshes++; } stats->layout_last_display_metric_44e4 = (uint16_t)result->new_display_metric_44e4; } static void wp_format_record_irq_result(WpFormatExecutorStats *stats, const WpLayoutIrqDirtyPulseResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_irq_dirty_pulses++; if (result->timer_decremented) { stats->layout_irq_timer_decrements++; } if (result->display_update_ran) { stats->layout_irq_display_updates++; wp_format_record_display_update_result(stats, &result->display_update); } } static void wp_format_record_carry_update_result(WpFormatExecutorStats *stats, const WpLayoutCarryUpdateResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_carry_updates++; if (result->saturated_to_zero) { stats->layout_carry_saturations++; } stats->layout_last_status_scaled_width = result->scaled_width; } static void wp_format_record_cursor_metric_result(WpFormatExecutorStats *stats, const WpLayoutCursorMetricResult *result) { if (stats == NULL || result == NULL) { return; } if (result->metric_lookup_path) { stats->layout_cursor_metric_folds++; } if (result->cursor_advanced) { stats->layout_cursor_advances++; } if (result->processed_segments_cleared) { stats->layout_postprocess_cleanups++; } } static void wp_format_record_parse_dirty_result(WpFormatExecutorStats *stats, const WpLayoutParseDirtyUpdateResult *result) { if (stats == NULL || result == NULL) { return; } if (result->skipped_busy) { stats->layout_parse_dirty_busy_skips++; return; } if (result->ran) { stats->layout_parse_dirty_updates++; } if (result->parse_carry_ran) { stats->layout_parse_carry_adjusts++; if (result->carry.threshold_reached) { stats->layout_parse_threshold_hits++; } if (result->carry.variant_decode_would_run || result->carry.no_variants_iteration_would_run) { stats->layout_parse_variant_decode_hints++; } } if (result->dirty_if_balance_ran) { stats->layout_parse_status_dirty_checks++; } if (result->variant_total_reset_ran) { stats->layout_parse_variant_resets++; } } static void wp_format_record_emit_measure_result(WpFormatExecutorStats *stats, const WpLayoutEmitMeasureResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_emit_measure_passes++; if (result->inside_window) { stats->layout_emit_measure_inside_windows++; } if (result->display_limit_reached) { stats->layout_emit_measure_limit_reached++; } stats->layout_emit_measure_scratch_bytes += result->spaces_written; stats->layout_status_line_refreshes += result->status_line_refreshes; if (result->last_refresh.byte_return_wrote) { stats->layout_status_line_buffer_writes++; } stats->layout_last_emit_candidate = result->adjusted_candidate; stats->layout_last_display_metric_44e4 = result->new_display_metric_44e4; stats->layout_last_refresh_index = result->last_refresh.buffer_index; } static void wp_format_record_gate_result(WpFormatExecutorStats *stats, const WpFormatGateResult *result) { if (stats == NULL || result == NULL) { return; } stats->layout_format_gate_inits += result->init_calls; stats->layout_format_gate_slot_zeroes += result->slot_zeroes; stats->layout_format_gate_reuses += result->gate_reuses; stats->layout_format_gate_aux_clears += result->aux_clears; stats->layout_format_gate_word_pair_inits += result->word_pair_inits; stats->layout_format_gate_glyph_checks += result->glyph_rule_calls; stats->layout_format_gate_glyph_load_setups += result->glyph_load_setups; stats->layout_format_gate_video_patches += result->video_patches; stats->layout_format_gate_overlay_polls += result->overlay_polls; stats->layout_format_gate_refcount_increments += result->refcount_increments; stats->layout_format_gate_counter_resets += result->counter_resets; stats->layout_format_gate_failfast_hints += result->failfast_hints; stats->layout_format_gate_high_scratch_gates += result->high_scratch_gates; stats->layout_format_gate_run_count_increments += result->run_count_increments; stats->layout_format_gate_word_pair_flag_sets += result->word_pair_flag_sets; stats->layout_format_gate_display_routes += result->display_routes; stats->layout_format_gate_f8_sets += result->set_refcount_f8; stats->layout_format_gate_repeat_batches += result->repeat_batches; stats->layout_format_gate_repeat_iterations += result->repeat_iterations_requested; stats->layout_format_gate_repeat_simulated += result->repeat_iterations_simulated; } static void wp_format_apply_post_compare(WpLayoutGlobals *runtime, WpFormatGateSlot *format_slot, const WpVariablePostComparePlan *plan, WpFormatExecutorStats *stats) { if (plan == NULL || stats == NULL) { return; } /* Ported from layout_post_compare_record_touch / handle_escape_or_subcommand * around 1000:74ac. The original sets parser_runtime_flags bit 3 on entry, * dispatches repeat groups through either the decode-noise or far-call path, * handles D6 extension scans by setting parse_dirty_flags bit 3, adjusts the * DB layout refcount, then always marks parse_dirty_flags bit 1. This host * executor records and applies those side effects without jumping overlays. */ if (runtime != NULL) { runtime->parser_runtime_flags |= 0x08U; } if ((plan->flags & WP_VARIABLE_POST_REPEAT_DISPATCH) != 0U) { stats->repeat_dispatch_packets++; if (plan->has_repeat_count) { stats->repeat_dispatch_iterations += plan->repeat_count; } else { stats->repeat_dispatch_iterations++; } if (runtime != NULL && format_slot != NULL) { WpFormatGateResult gate_result; size_t repeat_count = plan->has_repeat_count ? plan->repeat_count : 1U; if (wp_format_gate_repeat_batch(runtime, format_slot, repeat_count, 64U, &gate_result)) { wp_format_record_gate_result(stats, &gate_result); } } if (runtime != NULL) { WpLayoutVariantBalanceResult balance_result; runtime->gate_char_7eaf = 1; /* layout_post_compare_record_touch calls layout_update_variant_totals * after each decoded repeat body. The host executor coalesces that * into one bounded reset/flush of the accumulated variant_total. */ if (wp_layout_reset_variant_total_and_update_dirty_flags(runtime, &balance_result)) { wp_format_record_balance_result(stats, &balance_result); } runtime->gate_char_7eaf = 0; } } if (plan->extension_scan) { stats->extension_scan_packets++; if (runtime != NULL && runtime->record_extension_block_count != 0U) { runtime->parse_dirty_flags |= 0x08U; } } if (plan->refcount_increment) { stats->refcount_increment_packets++; if (runtime != NULL) { runtime->layout_refcount_44c6++; } } else if (plan->refcount_decrement) { stats->refcount_decrement_packets++; if (runtime != NULL) { runtime->layout_refcount_44c6--; } } if (runtime != NULL) { runtime->parse_dirty_flags |= 0x02U; } } static void wp_format_apply_pending_span(WpLayoutGlobals *runtime, const WpD4PendingSpanPayload *span, WpFormatExecutorStats *stats) { uint16_t total; if (span == NULL || stats == NULL || !span->is_pending_span) { return; } /* Ported from process_layout_state_records_main: the original emits a * 0x0600 record when measured span A/B needs to be replayed. The host * executor applies the same measured-span words and restored carry width * without committing a DOS record envelope. */ stats->d4_pending_span_records++; stats->d4_pending_span_applied++; total = (uint16_t)(span->span_a + span->span_b); if (total > stats->d4_pending_span_max_total) { stats->d4_pending_span_max_total = total; } if (runtime != NULL) { runtime->measured_span_a = span->span_a; runtime->measured_span_b = span->span_b; runtime->measured_span_total = total; runtime->carry_width = (int)(int16_t)span->carry_width; runtime->measured_span_flags |= 0x80U; runtime->metrics_line_accum_5037 = (int)(int16_t)total; { WpLayoutVariantResult variant_result; if (wp_layout_add_metrics_line_accum_to_variant_anchor_and_total(runtime, &variant_result)) { wp_format_record_variant_result(stats, &variant_result); } } } } static void wp_format_apply_line_window(WpLayoutGlobals *runtime, const WpD4LineWindowPayload *window, WpFormatExecutorStats *stats) { if (window == NULL || stats == NULL || !window->is_line_window) { return; } /* Ported from layout_emit_or_measure_line_window's 0x1400 branch. The * decompiled path stores old line-window words followed by the restored * window and signed carry delta, then optionally appends extension bytes. */ stats->d4_line_window_records++; stats->d4_line_window_applied++; if (window->has_extension_payload) { stats->d4_line_window_extension_records++; stats->d4_line_window_extension_bytes += window->extension_payload_bytes; } if (runtime != NULL) { runtime->emit_record_scratch_5031 = window->new_line_start; runtime->emit_record_scratch_5033 = window->new_line_extent; runtime->record_window_word_502d = window->new_scratch_start; runtime->record_window_word_4b40 = window->old_scratch_start; runtime->carry_width = (int)(int16_t)window->carry_width_after; runtime->render_dirty_flags |= 0x01U; { WpLayoutHeapBranchResult heap_result; if (wp_layout_apply_heap_control_branch(runtime, &heap_result)) { wp_format_record_heap_branch_result(stats, &heap_result); } } if (window->has_extension_payload) { runtime->record_extension_needs_flush = 1; } } } static void wp_format_apply_extension_fragment(WpLayoutGlobals *runtime, const WpD4ExtensionPayload *extension, WpFormatExecutorStats *stats) { if (extension == NULL || stats == NULL || !extension->is_extension_payload) { return; } /* Ported from the record-extension copy loops in layout_emit_or_measure_line_window * and append/restore_layout_state_record. Host code records the flushed bytes * and clears the pending-flush flag without copying arbitrary DOS blocks. */ stats->d4_extension_fragment_records++; stats->d4_extension_fragment_applied++; stats->d4_extension_fragment_bytes += extension->extension_payload_bytes; if (extension->is_block_list) { stats->d4_extension_fragment_block_records++; stats->d4_extension_fragment_block_bytes += extension->block_bytes; } if (runtime != NULL) { if (extension->is_block_list) { runtime->record_extension_block_count = extension->block_count; } runtime->record_extension_needs_flush = 0; runtime->render_dirty_flags |= 0x01U; } } static void wp_format_apply_line_metric(WpLayoutGlobals *runtime, const WpD4LineMetricPayload *metric, WpFormatExecutorStats *stats) { uint16_t max_extent; if (metric == NULL || stats == NULL || !metric->is_line_metric) { return; } /* The decompiled layout_bootstrap_line_from_secondary_gate path emits compact * 0x1200 metric checkpoints. Treat the fixed words as a safe host snapshot * of line start/extent and then replay any attached extension fragment. */ stats->d4_line_metric_records++; stats->d4_line_metric_applied++; max_extent = metric->extent_word_a > metric->extent_word_b ? metric->extent_word_a : metric->extent_word_b; if (max_extent > stats->d4_line_metric_max_extent) { stats->d4_line_metric_max_extent = max_extent; } if (metric->has_extension_payload) { stats->d4_line_metric_extension_records++; stats->d4_line_metric_extension_bytes += metric->extension.extension_payload_bytes; } if (runtime != NULL) { { WpLayoutReconcileResult reconcile_result; if (wp_layout_reconcile_line_build_span_words(runtime, metric->extent_word_a, &reconcile_result)) { wp_format_record_reconcile_result(stats, &reconcile_result); } } runtime->cursor = metric->position_word; { WpLayoutMeasuredSpanResetResult reset_result; if (wp_layout_reset_cursor_aliases_variant_table(runtime, &reset_result)) { wp_format_record_span_reset_result(stats, &reset_result); } } { WpLayoutFlushSpanResult flush_result; if (wp_layout_flush_measured_span_then_scale_width_q8(runtime, 0x80U, false, 0U, &flush_result)) { wp_format_record_flush_span_result(stats, &flush_result); } } runtime->record_window_word_502d = metric->position_word; runtime->line_build_word_51f1 = metric->position_word; runtime->line_build_word_51f3 = metric->line_start_word; runtime->line_build_word_51f5 = metric->extent_word_a; runtime->line_build_word_51f7 = metric->extent_word_b; runtime->line_start = metric->line_start_word; runtime->emit_record_line_extent = metric->extent_word_b; runtime->render_dirty_flags |= 0x02U; { WpLayoutExtentResult extent_result; if (wp_layout_measure_line_extent_dirty_heap(runtime, 0x80U, false, 0U, &extent_result)) { wp_format_record_extent_result(stats, &extent_result); } } } } static void wp_format_apply_line_build_checkpoint(WpLayoutGlobals *runtime, const WpD4LineBuildCheckpointPayload *checkpoint, WpFormatExecutorStats *stats) { if (checkpoint == NULL || stats == NULL || !checkpoint->is_line_build_checkpoint) { return; } /* Ported from layout_bootstrap_line_from_secondary_gate: D4/05 carries the * two line-build checkpoint words written as puVar3[2] and puVar3[3]. */ stats->d4_line_build_checkpoint_records++; stats->d4_line_build_checkpoint_applied++; if (checkpoint->line_build_word_51f3 > stats->d4_line_build_checkpoint_max_word) { stats->d4_line_build_checkpoint_max_word = checkpoint->line_build_word_51f3; } if (runtime != NULL) { runtime->line_build_word_51f1 = checkpoint->line_build_word_51f1; runtime->line_build_word_51f3 = checkpoint->line_build_word_51f3; runtime->line_build_word_51f5 = checkpoint->line_build_word_51f1; runtime->line_build_word_51f7 = checkpoint->line_build_word_51f3; runtime->record_aux_4b34 = (int)(int16_t)checkpoint->line_build_word_51f1; runtime->render_dirty_flags |= 0x02U; } } static void wp_format_apply_variable_record(WpLayoutGlobals *runtime, WpFormatGateSlot *format_slot, const WpRecord *rec, const WpFormatExecutorOptions *options, WpFormatExecutorStats *stats) { WpVariableCommandInfo info; if (rec == NULL || stats == NULL || !wp_variable_classify_record(rec, &info)) { return; } stats->variable_packets++; if (info.scanner_bypass) { stats->scanner_bypass_packets++; } if (info.has_initial_format_table) { stats->d0_initial_format_tables++; stats->d0_format_table_words += info.initial_table.word_count; stats->d0_format_table_groups += info.initial_table.group_count; stats->d0_format_table_sentinels += info.initial_table.sentinel_word_count; stats->d0_format_table_nonmonotonic_steps += info.initial_table.nonmonotonic_step_count; if (info.initial_table.has_positive_step && stats->d0_format_table_first_step == 0U) { stats->d0_format_table_first_step = info.initial_table.first_positive_step; } if (info.initial_table.max_value > stats->d0_format_table_max_value) { stats->d0_format_table_max_value = info.initial_table.max_value; } if (runtime != NULL && info.initial_table.has_positive_step) { runtime->default_span_a = info.initial_table.first_positive_step; runtime->default_span_b = 0U; } } if (info.has_layout_state) { stats->d4_layout_state_records++; if (info.layout_state.has_variant_snapshot) { stats->d4_variant_snapshot_records++; } if (info.layout_state.has_extension_blocks) { stats->d4_extension_block_records++; stats->d4_extension_blocks += info.layout_state.extension_block_count; stats->d4_extension_bytes += info.layout_state.extension_block_bytes; } if (options == NULL || options->apply_layout_state) { if (wp_variable_apply_layout_state(runtime, &info.layout_state)) { stats->d4_layout_state_applied++; } else { stats->d4_layout_state_apply_failures++; } } } if (info.has_pending_span) { stats->d4_pending_span_payload_bytes += rec->data_length; wp_format_apply_pending_span(runtime, &info.pending_span, stats); } if (info.has_line_window) { stats->d4_line_window_payload_bytes += rec->data_length; wp_format_apply_line_window(runtime, &info.line_window, stats); } if (info.has_line_metric) { stats->d4_line_metric_payload_bytes += rec->data_length; wp_format_apply_line_metric(runtime, &info.line_metric, stats); } if (info.has_extension_fragment) { wp_format_apply_extension_fragment(runtime, &info.extension_fragment, stats); } if (info.has_line_build_checkpoint) { wp_format_apply_line_build_checkpoint(runtime, &info.line_build_checkpoint, stats); } if (info.has_post_compare_plan) { wp_format_apply_post_compare(runtime, format_slot, &info.post_compare, stats); } if (info.has_nested_stream_hint) { stats->nested_stream_hints++; if (options == NULL || options->follow_nested_streams) { WpNestedStreamStats nested; if (wp_nested_stream_analyze_record(rec, NULL, &nested)) { wp_format_merge_nested_stats(stats, &nested); } } } } static void wp_format_apply_single_byte(WpLayoutGlobals *runtime, const WpRecord *rec, const WpFormatExecutorOptions *options, WpFormatExecutorStats *stats) { uint16_t next; WpControlInfo control; if (rec == NULL || stats == NULL) { return; } wp_control_decode_byte(rec->code, &control); if ((control.effects & WP_CONTROL_EFFECT_DORMANT) != 0UL) { stats->dormant_controls++; } if ((control.effects & WP_CONTROL_EFFECT_WHITESPACE_GATE) != 0UL) { stats->whitespace_gate_controls++; } if ((control.effects & WP_CONTROL_EFFECT_RENDER_DIRTY_GATE) != 0UL) { stats->render_dirty_gate_controls++; } if ((control.effects & WP_CONTROL_EFFECT_DIRTY_NEUTRAL) != 0UL) { stats->dirty_neutral_controls++; } if ((control.effects & WP_CONTROL_EFFECT_EXTENSION_SCAN_STOP) != 0UL) { stats->extension_scan_stop_controls++; } if (runtime != NULL && ((control.effects & WP_CONTROL_EFFECT_LINE_BREAK) != 0UL || (control.effects & WP_CONTROL_EFFECT_PAGE_BREAK) != 0UL)) { WpLayoutCarryUpdateResult carry_result; uint8_t token = (control.effects & WP_CONTROL_EFFECT_LINE_BREAK) != 0UL ? (uint8_t)'\n' : rec->code; if (wp_layout_status_extend_update(runtime, token, &carry_result)) { wp_format_record_carry_update_result(stats, &carry_result); } } if (runtime != NULL && (control.effects & WP_CONTROL_EFFECT_RENDER_DIRTY_GATE) != 0UL) { WpLayoutStatusDirtyResult dirty_result; if (wp_layout_mark_status_dirty(runtime, &dirty_result)) { wp_format_record_status_dirty_result(stats, &dirty_result); } } switch (rec->code) { case 0x80U: stats->hard_returns++; wp_format_new_line(stats); break; case 0x81U: stats->soft_returns++; wp_format_new_line(stats); break; case 0x82U: stats->hard_pages++; wp_format_new_page(stats); break; case 0x83U: stats->soft_pages++; wp_format_new_page(stats); break; case 0x84U: stats->tabs++; next = wp_format_next_tab_stop(stats->current_column, options != NULL ? options->tab_width : 8U); stats->current_column = next; wp_format_note_column(stats); break; case 0x8DU: stats->indents++; next = wp_format_next_tab_stop(stats->current_column, options != NULL ? options->tab_width : 8U); stats->current_column = next; wp_format_note_column(stats); break; case 0xA0U: stats->normalized_spaces++; wp_format_advance_column(stats, options, 1U); break; case 0xA9U: stats->normalized_hyphens++; wp_format_advance_column(stats, options, 1U); break; default: break; } } void wp_format_executor_default_options(WpFormatExecutorOptions *options) { if (options == NULL) { return; } options->apply_layout_state = true; options->follow_nested_streams = true; options->tab_width = 8U; options->wrap_column = 0U; } void wp_format_executor_stats_clear(WpFormatExecutorStats *stats) { if (stats != NULL) { memset(stats, 0, sizeof(*stats)); stats->lines_seen = 1U; stats->pages_seen = 1U; } } bool wp_format_executor_run_stream(WpLayoutGlobals *wl, const WpFormatExecutorOptions *options, WpFormatExecutorStats *stats) { WpFormatExecutorOptions local_options; WpFormatExecutorStats local_stats; WpLayoutGlobals cursor; WpLayoutGlobals runtime; WpFormatGateSlot format_slot; bool ok = true; if (wl == NULL || stats == NULL) { return false; } if (options == NULL) { wp_format_executor_default_options(&local_options); options = &local_options; } wp_format_executor_stats_clear(&local_stats); cursor = *wl; runtime = *wl; wp_format_gate_slot_clear(&format_slot); 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; } local_stats.records_seen++; local_stats.bytes_consumed += rec.length; wp_format_count_record_status(&rec, &local_stats); switch (rec.type) { case WP_CODE_CHAR: local_stats.char_records++; { WpLayoutCursorMetricResult cursor_result; if (wp_layout_render_dirty_or_advance_cursor(&runtime, rec.code, false, &cursor_result)) { wp_format_record_cursor_metric_result(&local_stats, &cursor_result); } } wp_format_advance_column(&local_stats, options, 1U); break; case WP_CODE_SINGLE_BYTE: local_stats.single_byte_codes++; wp_format_apply_single_byte(&runtime, &rec, options, &local_stats); break; case WP_CODE_FIXED_LENGTH: local_stats.fixed_length_codes++; if (rec.code == 0xC0U) { local_stats.fixed_c0_extended_chars++; { WpLayoutCursorMetricResult cursor_result; uint16_t token_word = (uint16_t)(0x0100U | (uint16_t)rec.code); if (wp_layout_render_dirty_or_advance_cursor(&runtime, token_word, false, &cursor_result)) { wp_format_record_cursor_metric_result(&local_stats, &cursor_result); } } wp_format_advance_column(&local_stats, options, 1U); } else { local_stats.fixed_format_packets++; } break; case WP_CODE_VARIABLE_LENGTH: local_stats.variable_length_codes++; wp_format_apply_variable_record(&runtime, &format_slot, &rec, options, &local_stats); break; } wp_record_free(&rec); } if (runtime.irq_timer_7902_char != 0) { WpLayoutIrqDirtyPulseResult irq_result; if (wp_layout_decrement_irq_timer_and_dirty_flags(&runtime, &irq_result)) { wp_format_record_irq_result(&local_stats, &irq_result); } } if (runtime.parse_dirty_flags != 0U) { WpLayoutParseDirtyUpdateResult parse_result; if (wp_layout_update_parse_dirty_flags(&runtime, &parse_result)) { wp_format_record_parse_dirty_result(&local_stats, &parse_result); } } if ((runtime.render_dirty_flags & 0x08U) != 0U) { WpLayoutEmitMeasureResult emit_result; if (wp_layout_execute_emit_or_measure_pass(&runtime, &emit_result)) { wp_format_record_emit_measure_result(&local_stats, &emit_result); } } local_stats.final_parser_runtime_flags = runtime.parser_runtime_flags; local_stats.final_parse_dirty_flags = runtime.parse_dirty_flags; local_stats.final_state_flags = runtime.state_flags; local_stats.final_runtime_flags = runtime.runtime_flags; local_stats.final_gate_char = (uint8_t)runtime.gate_char_7eaf; local_stats.final_layout_refcount = (int)runtime.layout_refcount_44c6; local_stats.final_carry_width = runtime.carry_width; local_stats.final_wrap_value = runtime.wrap_value; local_stats.final_pending_offset = runtime.pending_offset; local_stats.final_line_start = (uint16_t)runtime.line_start; local_stats.final_line_extent = (uint16_t)runtime.emit_record_line_extent; local_stats.final_line_build_word_51f1 = runtime.line_build_word_51f1; local_stats.final_line_build_word_51f3 = runtime.line_build_word_51f3; local_stats.final_line_build_word_51f5 = runtime.line_build_word_51f5; local_stats.final_line_build_word_51f7 = runtime.line_build_word_51f7; local_stats.final_measure_extent = (uint16_t)runtime.measure_extent_50c8; local_stats.final_measure_bound = (uint16_t)runtime.measure_extent_bound_50c6; local_stats.final_span_compare_word_51fb = (uint16_t)runtime.span_compare_word_51fb; local_stats.final_span_compare_word_51ff = (uint16_t)runtime.span_compare_word_51ff; local_stats.final_record_aux_4b34 = runtime.record_aux_4b34; local_stats.final_cursor_alias_shadow_4b3e = runtime.cursor_alias_shadow_4b3e; local_stats.final_measured_span_a = runtime.measured_span_a; local_stats.final_measured_span_b = runtime.measured_span_b; local_stats.final_variant_balance = runtime.variant_balance_51bd; local_stats.final_variant_total = runtime.variant_total; local_stats.final_heap_delta = runtime.heap_delta_c5b6; local_stats.final_variant_limit = (uint16_t)runtime.variant_limit_c664; local_stats.final_status_dirty_flags = runtime.status_dirty_flags; local_stats.final_status_extend = runtime.status_extend_4976; local_stats.final_render_dirty_flags = runtime.render_dirty_flags; local_stats.final_status_scratch = runtime.status_scratch_479f; local_stats.final_irq_timer = (uint8_t)(unsigned char)runtime.irq_timer_7902_char; local_stats.final_irq_state = (uint8_t)(unsigned char)runtime.irq_state_7903; local_stats.final_fmt_gate = (uint8_t)(unsigned char)runtime.fmt_gate_7ead; local_stats.final_format_slot_selector = format_slot.selector; local_stats.final_format_slot_lead = format_slot.lead_byte; local_stats.final_format_slot_run_count = format_slot.run_count; local_stats.final_format_slot_age = format_slot.age; local_stats.final_format_slot_flags = format_slot.flags; local_stats.final_format_slot_payload_tag = format_slot.payload_tag; local_stats.final_display_metric_44de = runtime.display_metric_44de; local_stats.final_display_metric_44e4 = runtime.display_metric_44e4; { WpLayoutStreamPosition pos; WpLayoutStreamDelta delta; if (wp_layout_record_stream_position(&cursor, &pos)) { local_stats.layout_final_record_pos_low = pos.low_word; local_stats.layout_final_record_pos_high = pos.high_word; } if (wp_layout_secondary_stream_position(&runtime, &pos)) { local_stats.layout_final_secondary_pos_low = pos.low_word; local_stats.layout_final_secondary_pos_high = pos.high_word; } if (wp_layout_span_metric_side_effect_position(&runtime, &pos)) { local_stats.layout_final_span_metric_low = pos.low_word; local_stats.layout_final_span_metric_high = pos.high_word; } if (wp_layout_delta_from_saved_record_offset(&cursor, &delta)) { local_stats.layout_final_stream_delta_low = delta.delta_low_word; local_stats.layout_final_stream_delta_high = delta.delta_high_word; if (delta.underflow) { local_stats.layout_stream_delta_underflows++; } } local_stats.layout_final_line_start_align = wp_layout_line_start_align(&runtime); } *stats = local_stats; return ok && local_stats.incomplete_records == 0U && local_stats.mismatched_trailers == 0U; } /* Raw wrappers for monolith compatibility */ void __cdecl16near layout_emit_gate_run_reset_variant_total(WpLayoutGlobals *wl) { WpLayoutVariantBalanceResult result; (void)wp_layout_reset_variant_total_and_update_dirty_flags(wl, &result); } void __cdecl16near layout_run_variant_batch_format_kernel(WpLayoutGlobals *wl) { /* Handled by host-safe pass in executor */ (void)wl; } void __cdecl16near layout_clear_measured_span_emit_state(WpLayoutGlobals *wl) { wl->measured_span_a = 0; wl->measured_span_b = 0; wl->measured_span_flags = 0; wl->measured_span_total_flags = 0; } void __cdecl16near layout_wrap_retry_until_form_feed_or_variant(WpLayoutGlobals *wl) { /* Stub for the wrap retry loop */ (void)wl; } void __cdecl16near layout_feature_gated_wrap_parse_consume(WpLayoutGlobals *wl) { /* Handled by host executor loops */ (void)wl; } void __cdecl16near layout_post_emit_gate_cleanup(WpLayoutGlobals *wl) { wl->state_flags &= (uint8_t)~0x02; wl->update_depth = 0; wl->render_dirty_flags &= (uint8_t)~0x04; } bool wp_format_executor_run_loaded_file(WpLoadedFile *file, const WpFormatExecutorOptions *options, WpFormatExecutorStats *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_format_executor_run_stream(&wl, options, stats); } bool wp_format_executor_run_file(const char *filename, const WpFormatExecutorOptions *options, WpFormatExecutorStats *stats) { WpLoadedFile file; bool ok; if (filename == NULL || stats == NULL) { return false; } if (!wp_file_load_body(filename, &file)) { return false; } ok = wp_format_executor_run_loaded_file(&file, options, 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