88#include "core/zr_diff.h"
99
1010#include "util/zr_checked.h"
11+ #include "util/zr_macros.h"
1112#include "util/zr_string_builder.h"
1213
1314#include <stdbool.h>
@@ -93,6 +94,15 @@ static const uint8_t ZR_ANSI16_PALETTE[16][3] = {
9394#define ZR_ASCII_ST_FINAL ((uint8_t)'\\')
9495#define ZR_ASCII_DEL 0x7Fu
9596
97+ /*
98+ VT CSI introducer (ESC '[').
99+
100+ Reference: ECMA-48 / ISO-6429 control sequence syntax used by VT100/xterm.
101+ */
102+ static bool zr_diff_write_csi (zr_sb_t * sb ) {
103+ return zr_sb_write_u8 (sb , ZR_ASCII_ESC ) && zr_sb_write_u8 (sb , (uint8_t )'[' );
104+ }
105+
96106/* Adaptive sweep threshold tuning (dirty-row density, percent). */
97107#define ZR_DIFF_SWEEP_DIRTY_LINE_PCT_BASE 35u
98108#define ZR_DIFF_SWEEP_DIRTY_LINE_PCT_WIDE_FRAME 30u
@@ -584,8 +594,7 @@ static bool zr_emit_cup(zr_sb_t* sb, zr_term_state_t* ts, uint32_t x, uint32_t y
584594 if (zr_term_cursor_pos_is_valid (ts ) && ts -> cursor_x == x && ts -> cursor_y == y ) {
585595 return true;
586596 }
587- const uint8_t esc = 0x1Bu ;
588- if (!zr_sb_write_u8 (sb , esc ) || !zr_sb_write_u8 (sb , (uint8_t )'[' )) {
597+ if (!zr_diff_write_csi (sb )) {
589598 return false;
590599 }
591600 if (!zr_sb_write_u32_dec (sb , y + 1u ) || !zr_sb_write_u8 (sb , (uint8_t )';' ) || !zr_sb_write_u32_dec (sb , x + 1u ) ||
@@ -648,8 +657,8 @@ static bool zr_emit_cursor_shape(zr_sb_t* sb, zr_term_state_t* ts, uint8_t shape
648657 }
649658
650659 const uint32_t ps = zr_cursor_shape_ps (shape , blink );
651- if (!zr_sb_write_u8 (sb , 0x1Bu ) || !zr_sb_write_u8 (sb , ( uint8_t ) '[' ) || !zr_sb_write_u32_dec (sb , ps ) ||
652- !zr_sb_write_u8 (sb , (uint8_t )' ' ) || ! zr_sb_write_u8 ( sb , ( uint8_t ) ' q' )) {
660+ if (!zr_diff_write_csi (sb ) || !zr_sb_write_u32_dec (sb , ps ) || !zr_sb_write_u8 (sb , ( uint8_t ) ' ' ) ||
661+ !zr_sb_write_u8 (sb , (uint8_t )'q' )) {
653662 return false;
654663 }
655664
@@ -831,20 +840,20 @@ static bool zr_emit_sgr_absolute(zr_sb_t* sb, zr_term_state_t* ts, zr_style_t de
831840 return true;
832841 }
833842
834- if (!zr_sb_write_u8 (sb , 0x1Bu ) || ! zr_sb_write_u8 ( sb , ( uint8_t ) '[' ) || !zr_sb_write_u32_dec (sb , ZR_SGR_RESET )) {
843+ if (!zr_diff_write_csi (sb ) || !zr_sb_write_u32_dec (sb , ZR_SGR_RESET )) {
835844 return false;
836845 }
837846
838847 if (!zr_emit_sgr_attr_params (sb , desired .attrs , ZR_SGR_ATTRS_PRE_UNDERLINE ,
839- sizeof (ZR_SGR_ATTRS_PRE_UNDERLINE ) / sizeof ( ZR_SGR_ATTRS_PRE_UNDERLINE [ 0 ] ))) {
848+ ZR_ARRAYLEN (ZR_SGR_ATTRS_PRE_UNDERLINE ))) {
840849 return false;
841850 }
842851 if ((desired .attrs & ZR_STYLE_ATTR_UNDERLINE ) != 0u &&
843852 (!zr_sb_write_u8 (sb , (uint8_t )';' ) || !zr_emit_sgr_underline_style_param (sb , desired , caps ))) {
844853 return false;
845854 }
846855 if (!zr_emit_sgr_attr_params (sb , desired .attrs , ZR_SGR_ATTRS_POST_UNDERLINE ,
847- sizeof (ZR_SGR_ATTRS_POST_UNDERLINE ) / sizeof ( ZR_SGR_ATTRS_POST_UNDERLINE [ 0 ] ))) {
856+ ZR_ARRAYLEN (ZR_SGR_ATTRS_POST_UNDERLINE ))) {
848857 return false;
849858 }
850859 if (desired_has_underline_color &&
@@ -1320,7 +1329,7 @@ static bool zr_emit_decstbm(zr_sb_t* sb, zr_term_state_t* ts, uint32_t top, uint
13201329 if (!sb || !ts ) {
13211330 return false;
13221331 }
1323- if (!zr_sb_write_u8 (sb , 0x1Bu ) || ! zr_sb_write_u8 ( sb , ( uint8_t ) '[' )) {
1332+ if (!zr_diff_write_csi (sb )) {
13241333 return false;
13251334 }
13261335 if (!zr_sb_write_u32_dec (sb , top + 1u ) || !zr_sb_write_u8 (sb , (uint8_t )';' ) ||
@@ -1341,7 +1350,7 @@ static bool zr_emit_scroll_op(zr_sb_t* sb, zr_term_state_t* ts, bool up, uint32_
13411350 if (lines == 0u ) {
13421351 return true;
13431352 }
1344- if (!zr_sb_write_u8 (sb , 0x1Bu ) || ! zr_sb_write_u8 ( sb , ( uint8_t ) '[' )) {
1353+ if (!zr_diff_write_csi (sb )) {
13451354 return false;
13461355 }
13471356 if (!zr_sb_write_u32_dec (sb , lines ) || !zr_sb_write_u8 (sb , up ? (uint8_t )'S' : (uint8_t )'T' )) {
@@ -1354,7 +1363,7 @@ static bool zr_emit_decstbm_reset(zr_sb_t* sb, zr_term_state_t* ts) {
13541363 if (!sb || !ts ) {
13551364 return false;
13561365 }
1357- if (!zr_sb_write_u8 (sb , 0x1Bu ) || ! zr_sb_write_u8 ( sb , ( uint8_t ) '[' ) || !zr_sb_write_u8 (sb , (uint8_t )'r' )) {
1366+ if (!zr_diff_write_csi (sb ) || !zr_sb_write_u8 (sb , (uint8_t )'r' )) {
13581367 return false;
13591368 }
13601369 ts -> cursor_x = 0u ;
0 commit comments