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_control_codes.c
File editor
#include "wp_control_codes.h" #include "wp_record_parser.h" #include <string.h> WpDecompilerTokenClass wp_control_decompiled_token_class(uint8_t code) { /* Exact bucket logic recovered from parser_process_token_stream around * decompiled_wp_exe.c 1000:2109: * i=1 for >=C0, i=2 for 80-BF, i=3 for <=1F, i=4 for 20-7F. */ if (code >= 0xC0U) { return WP_DECOMP_TOKEN_PACKET; } if (code >= 0x80U) { return WP_DECOMP_TOKEN_SINGLE_BYTE_FORMAT; } if (code > 0x1FU) { return WP_DECOMP_TOKEN_TEXT; } return WP_DECOMP_TOKEN_ASCII_CONTROL; } const char *wp_control_decompiled_token_class_name(WpDecompilerTokenClass token_class) { switch (token_class) { case WP_DECOMP_TOKEN_ASCII_CONTROL: return "ASCII/control byte"; case WP_DECOMP_TOKEN_TEXT: return "printable text byte"; case WP_DECOMP_TOKEN_SINGLE_BYTE_FORMAT: return "single-byte format code"; case WP_DECOMP_TOKEN_PACKET: return "C0+/D0+ packet code"; default: return "unknown byte class"; } } static bool wp_control_in_range(uint8_t code, uint8_t first, uint8_t last) { return code >= first && code <= last; } void wp_control_decode_byte(uint8_t code, WpControlInfo *out_info) { WpControlInfo info; if (out_info == NULL) { return; } memset(&info, 0, sizeof(info)); info.code = code; info.token_class = wp_control_decompiled_token_class(code); info.label = wp_control_decompiled_token_class_name(info.token_class); info.marker = NULL; switch (info.token_class) { case WP_DECOMP_TOKEN_ASCII_CONTROL: info.effects |= WP_CONTROL_EFFECT_ASCII_CONTROL; info.label = "ASCII/control byte"; if (code == '\n' || code == '\r') { info.effects |= WP_CONTROL_EFFECT_LINE_BREAK | WP_CONTROL_EFFECT_WHITESPACE_GATE; info.label = "Host newline/control"; info.marker = "[NL]"; } else if (code == '\t') { info.effects |= WP_CONTROL_EFFECT_TAB_STOP | WP_CONTROL_EFFECT_WHITESPACE_GATE; info.label = "Host tab/control"; info.marker = "[Tab]"; } break; case WP_DECOMP_TOKEN_TEXT: info.effects |= WP_CONTROL_EFFECT_TEXT | WP_CONTROL_EFFECT_PRINTABLE_HOST_BYTE; info.display_columns = 1U; if (code == 0x20U) { info.effects |= WP_CONTROL_EFFECT_WHITESPACE_GATE; info.label = "ASCII space / whitespace gate"; info.marker = "[Space]"; } else if (code == 0x7FU) { info.effects &= ~WP_CONTROL_EFFECT_PRINTABLE_HOST_BYTE; info.effects |= WP_CONTROL_EFFECT_ASCII_CONTROL; info.display_columns = 0U; info.label = "ASCII DEL/control byte"; info.marker = "[DEL]"; } else { info.label = "Text character"; } break; case WP_DECOMP_TOKEN_SINGLE_BYTE_FORMAT: info.effects |= WP_CONTROL_EFFECT_SINGLE_BYTE_FORMAT; info.label = "Single-byte format code"; break; case WP_DECOMP_TOKEN_PACKET: info.effects |= WP_CONTROL_EFFECT_PACKET; info.label = "C0+/D0+ packet code"; break; } switch (code) { case 0x80U: info.label = "Hard return"; info.marker = "[HRt]"; info.effects |= WP_CONTROL_EFFECT_LINE_BREAK | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x81U: info.label = "Soft return"; info.marker = "[SRt]"; info.effects |= WP_CONTROL_EFFECT_LINE_BREAK | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x82U: info.label = "Hard page"; info.marker = "[HPg]"; info.effects |= WP_CONTROL_EFFECT_PAGE_BREAK | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x83U: info.label = "Soft page"; info.marker = "[SPg]"; info.effects |= WP_CONTROL_EFFECT_PAGE_BREAK | WP_CONTROL_EFFECT_WHITESPACE_GATE | WP_CONTROL_EFFECT_DIRTY_EXEMPT; break; case 0x84U: info.label = "Tab"; info.marker = "[Tab]"; info.effects |= WP_CONTROL_EFFECT_TAB_STOP | WP_CONTROL_EFFECT_WHITESPACE_GATE; info.tab_columns = 8U; break; case 0x85U: info.label = "Dormant hard return / extension-scan stop"; info.marker = "[DormHRt]"; info.effects |= WP_CONTROL_EFFECT_LINE_BREAK | WP_CONTROL_EFFECT_DORMANT | WP_CONTROL_EFFECT_EXTENSION_SCAN_STOP | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x86U: info.label = "Dormant soft return"; info.marker = "[DormSRt]"; info.effects |= WP_CONTROL_EFFECT_LINE_BREAK | WP_CONTROL_EFFECT_DORMANT | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x87U: info.label = "Dormant hard page"; info.marker = "[DormHPg]"; info.effects |= WP_CONTROL_EFFECT_PAGE_BREAK | WP_CONTROL_EFFECT_DORMANT | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x88U: info.label = "Dormant soft page"; info.marker = "[DormSPg]"; info.effects |= WP_CONTROL_EFFECT_PAGE_BREAK | WP_CONTROL_EFFECT_DORMANT | WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x8AU: info.label = "Text Services Manager highlight off"; info.marker = "[HighliteOff]"; info.effects |= WP_CONTROL_EFFECT_TSM_HIGHLIGHT; break; case 0x8CU: info.label = "Whitespace/gate control 8C"; info.marker = "[Gate8C]"; info.effects |= WP_CONTROL_EFFECT_WHITESPACE_GATE; break; case 0x8DU: info.label = "Indent"; info.marker = "[Indent]"; info.effects |= WP_CONTROL_EFFECT_INDENT | WP_CONTROL_EFFECT_TAB_STOP | WP_CONTROL_EFFECT_WHITESPACE_GATE; info.tab_columns = 8U; break; case 0x96U: info.label = "Dirty-neutral parser control 96"; info.marker = "[Ctrl96]"; info.effects |= WP_CONTROL_EFFECT_DIRTY_NEUTRAL; break; case 0x97U: info.label = "Dirty-neutral parser control 97"; info.marker = "[Ctrl97]"; info.effects |= WP_CONTROL_EFFECT_DIRTY_NEUTRAL; break; case 0x9AU: info.label = "Cancel hyphenation for word"; info.marker = "[HyphCancel]"; info.effects |= WP_CONTROL_EFFECT_HYPHENATION_SUPPRESS; break; case 0x9EU: info.label = "Hide functions on"; info.marker = "[HideOn]"; info.effects |= WP_CONTROL_EFFECT_HIDDEN_FUNCTION_GATE; break; case 0x9FU: info.label = "Hide functions off"; info.marker = "[HideOff]"; info.effects |= WP_CONTROL_EFFECT_HIDDEN_FUNCTION_GATE; break; case 0xA0U: info.label = "Scanner-normalized space"; info.marker = "[Space]"; info.effects |= WP_CONTROL_EFFECT_NORMALIZED_SPACE | WP_CONTROL_EFFECT_WHITESPACE_GATE | WP_CONTROL_EFFECT_PRINTABLE_HOST_BYTE; info.display_columns = 1U; break; case 0xA9U: info.label = "Scanner-normalized hyphen"; info.marker = "[Hyphen]"; info.effects |= WP_CONTROL_EFFECT_NORMALIZED_HYPHEN | WP_CONTROL_EFFECT_WHITESPACE_GATE | WP_CONTROL_EFFECT_RENDER_DIRTY_GATE | WP_CONTROL_EFFECT_PRINTABLE_HOST_BYTE; info.display_columns = 1U; break; case 0xC6U: info.label = "C6 fixed dirty-exempt command packet"; info.marker = "[C6]"; info.effects |= WP_CONTROL_EFFECT_DIRTY_EXEMPT; break; case 0xD4U: info.label = "D4 dirty-exempt layout-state packet"; info.marker = "[D4]"; info.effects |= WP_CONTROL_EFFECT_DIRTY_EXEMPT; break; default: break; } if (wp_control_in_range(code, 0x93U, 0x95U)) { info.label = "Layout whitespace/gate control 93-95"; info.marker = "[Gate93-95]"; info.effects |= WP_CONTROL_EFFECT_WHITESPACE_GATE; } if (wp_control_in_range(code, 0xA9U, 0xAEU)) { info.effects |= WP_CONTROL_EFFECT_WHITESPACE_GATE | WP_CONTROL_EFFECT_RENDER_DIRTY_GATE; if (code != 0xA9U) { info.label = "Layout render-dirty gate control A9-AE"; info.marker = "[DirtyGate]"; } } else if (wp_control_in_range(code, 0xAFU, 0xB0U)) { info.label = "Layout whitespace/gate control AF-B0"; info.marker = "[GateAF-B0]"; info.effects |= WP_CONTROL_EFFECT_WHITESPACE_GATE; } *out_info = info; } const char *wp_control_code_label(uint8_t code) { WpControlInfo info; wp_control_decode_byte(code, &info); return info.label; } const char *wp_control_code_marker(uint8_t code) { WpControlInfo info; wp_control_decode_byte(code, &info); return info.marker; } bool wp_control_has_effect(uint8_t code, unsigned long effect_mask) { WpControlInfo info; wp_control_decode_byte(code, &info); return (info.effects & effect_mask) != 0UL; } uint8_t wp_control_display_columns(uint8_t code) { WpControlInfo info; wp_control_decode_byte(code, &info); return info.display_columns; } void wp_control_summary_stats_clear(WpControlSummaryStats *stats) { if (stats != NULL) { memset(stats, 0, sizeof(*stats)); } } bool wp_control_summary_add_record(WpControlSummaryStats *stats, const WpRecord *rec) { WpControlInfo info; if (stats == NULL || rec == NULL) { return false; } wp_control_decode_byte(rec->code, &info); stats->records_seen++; stats->bytes_consumed += rec->length; stats->code_histogram[rec->code]++; switch (info.token_class) { case WP_DECOMP_TOKEN_ASCII_CONTROL: stats->ascii_control_records++; break; case WP_DECOMP_TOKEN_TEXT: stats->printable_text_records++; break; case WP_DECOMP_TOKEN_SINGLE_BYTE_FORMAT: stats->single_byte_format_records++; break; case WP_DECOMP_TOKEN_PACKET: stats->packet_records++; break; } if ((info.effects & WP_CONTROL_EFFECT_LINE_BREAK) != 0UL) { stats->line_break_records++; } if ((info.effects & WP_CONTROL_EFFECT_PAGE_BREAK) != 0UL) { stats->page_break_records++; } if ((info.effects & WP_CONTROL_EFFECT_WHITESPACE_GATE) != 0UL) { stats->whitespace_gate_records++; } if ((info.effects & WP_CONTROL_EFFECT_RENDER_DIRTY_GATE) != 0UL) { stats->render_dirty_gate_records++; } if ((info.effects & WP_CONTROL_EFFECT_DIRTY_EXEMPT) != 0UL) { stats->dirty_exempt_records++; } if ((info.effects & WP_CONTROL_EFFECT_DIRTY_NEUTRAL) != 0UL) { stats->dirty_neutral_records++; } if ((info.effects & WP_CONTROL_EFFECT_EXTENSION_SCAN_STOP) != 0UL) { stats->extension_scan_stop_records++; } if ((info.effects & WP_CONTROL_EFFECT_TSM_HIGHLIGHT) != 0UL) { stats->tsm_highlight_records++; } if ((info.effects & WP_CONTROL_EFFECT_HYPHENATION_SUPPRESS) != 0UL) { stats->hyphenation_suppression_records++; } if ((info.effects & WP_CONTROL_EFFECT_HIDDEN_FUNCTION_GATE) != 0UL) { stats->hidden_function_gate_records++; } if ((info.effects & WP_CONTROL_EFFECT_NORMALIZED_SPACE) != 0UL) { stats->normalized_spaces++; } if ((info.effects & WP_CONTROL_EFFECT_NORMALIZED_HYPHEN) != 0UL) { stats->normalized_hyphens++; } stats->display_columns += info.display_columns; switch (rec->code) { case 0x80U: stats->hard_returns++; break; case 0x81U: stats->soft_returns++; break; case 0x82U: stats->hard_pages++; break; case 0x83U: stats->soft_pages++; break; case 0x84U: stats->tabs++; break; case 0x85U: case 0x86U: stats->dormant_returns++; break; case 0x87U: case 0x88U: stats->dormant_pages++; break; case 0x8DU: stats->indents++; break; default: if (rec->type == WP_CODE_SINGLE_BYTE && info.marker == NULL) { stats->unknown_single_byte_records++; } break; } return true; } bool wp_control_summary_run_stream(WpLayoutGlobals *wl, WpControlSummaryStats *stats) { WpLayoutGlobals cursor; WpControlSummaryStats local; bool ok = true; if (wl == NULL || stats == NULL) { return false; } wp_control_summary_stats_clear(&local); cursor = *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_control_summary_add_record(&local, &rec)) { ok = false; } wp_record_free(&rec); } *stats = local; return ok; } bool wp_control_summary_run_loaded_file(WpLoadedFile *file, WpControlSummaryStats *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_control_summary_run_stream(&wl, stats); } bool wp_control_summary_run_file(const char *filename, WpControlSummaryStats *stats) { WpLoadedFile file; bool ok; if (filename == NULL || stats == NULL) { return false; } if (!wp_file_load_body(filename, &file)) { return false; } ok = wp_control_summary_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