line.c (most-5.1.0) | : | line.c (most-5.2.0) | ||
---|---|---|---|---|
/* | /* | |||
This file is part of MOST. | This file is part of MOST. | |||
Copyright (c) 1991, 1999, 2002, 2005-2018, 2019 John E. Davis | Copyright (c) 1991, 1999, 2002, 2005-2021, 2022 John E. Davis | |||
This program is free software; you can redistribute it and/or modify it | This program is free software; you can redistribute it and/or modify it | |||
under the terms of the GNU General Public License as published by the Free | under the terms of the GNU General Public License as published by the Free | |||
Software Foundation; either version 2 of the License, or (at your option) | Software Foundation; either version 2 of the License, or (at your option) | |||
any later version. | any later version. | |||
This program is distributed in the hope that it will be useful, but WITHOUT | This program is distributed in the hope that it will be useful, but WITHOUT | |||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |||
more details. | more details. | |||
skipping to change at line 33 | skipping to change at line 33 | |||
#include <string.h> | #include <string.h> | |||
#include <ctype.h> | #include <ctype.h> | |||
#include <slang.h> | #include <slang.h> | |||
#include "jdmacros.h" | #include "jdmacros.h" | |||
#include "most.h" | #include "most.h" | |||
#include "line.h" | #include "line.h" | |||
#include "window.h" | #include "window.h" | |||
#include "display.h" | #include "display.h" | |||
#include "color.h" | ||||
int Most_Tab_Width = 8; | int Most_Tab_Width = 8; | |||
int Most_Selective_Display = 0; | int Most_Selective_Display = 0; | |||
int Most_Show_Wrap_Marker = 1; | int Most_Show_Wrap_Marker = 1; | |||
#define IS_BYTE_PRINTABLE(b) \ | #define IS_BYTE_PRINTABLE(b) \ | |||
((((b) >= ' ') && ((b) < 0x7F)) \ | ((((b) >= ' ') && ((b) < 0x7F)) \ | |||
|| ((Most_UTF8_Mode == 0) && ((b) >= SLsmg_Display_Eight_Bit))) | || ((Most_UTF8_Mode == 0) && ((b) >= SLsmg_Display_Eight_Bit))) | |||
skipping to change at line 122 | skipping to change at line 123 | |||
end = beg + 16; | end = beg + 16; | |||
if (end > Most_Eob) end = Most_Eob; | if (end > Most_Eob) end = Most_Eob; | |||
sprintf (buf, "0x%08lX: ", (unsigned long) Most_C_Offset); | sprintf (buf, "0x%08lX: ", (unsigned long) Most_C_Offset); | |||
binary_format_line (beg, end, buf + 12); | binary_format_line (beg, end, buf + 12); | |||
SLsmg_write_string (buf); | SLsmg_write_string (buf); | |||
SLsmg_erase_eol (); | SLsmg_erase_eol (); | |||
} | } | |||
/* Here *begp points to the char after \e. | ||||
* The general escape sequence parsed here is assumed to look like: | ||||
* \e[ XX ; ... m | ||||
* If 30 <= XX <= 37, then it specifies the foreground color | ||||
* If 40 <= XX <= 47, then a background color is specified | ||||
* If 0 <= XX <= 8, then an attribute (e.g, 8) is specified. | ||||
* These numbers will be encoded as: | ||||
* offset + (FG-30 + 8*(BG-40 + 9*attribute)) | ||||
*/ | ||||
int most_parse_color_escape (unsigned char **begp, unsigned char *end, int *colo | ||||
rp) | ||||
{ | ||||
unsigned char *beg = *begp; | ||||
int fg = 38, bg = 48, at = 0; | ||||
int xx; | ||||
if ((beg >= end) || (*beg != '[')) | ||||
return -1; | ||||
beg++; /* skip [ */ | ||||
#if 1 | ||||
if ((beg < end) && (*beg == 'K')) | ||||
{ | ||||
if (colorp != NULL) *colorp = -1; | ||||
*begp = beg + 1; | ||||
return 0; | ||||
} | ||||
#endif | ||||
while (1) | ||||
{ | ||||
xx = 0; | ||||
while ((beg < end) && isdigit (*beg)) | ||||
{ | ||||
xx = xx*10 + (*beg - '0'); | ||||
beg++; | ||||
} | ||||
if ((xx >= 0) && (xx <= 8)) | ||||
at = xx; | ||||
else if ((xx >= 20) && (xx <= 28)) | ||||
xx = 0; | ||||
else if ((xx >= 30) && (xx <= 37)) | ||||
fg = xx; | ||||
else if ((xx >= 40) && (xx <= 47)) | ||||
bg = xx; | ||||
else return -1; | ||||
if ((beg < end) && (*beg == ';')) | ||||
{ | ||||
beg++; | ||||
continue; | ||||
} | ||||
if ((beg < end) && ((*beg == 'm') || (*beg == ']'))) | ||||
{ | ||||
*begp = beg + 1; | ||||
if (colorp != NULL) | ||||
{ | ||||
if ((fg != 38) || (bg != 48)) | ||||
xx = ((fg-30) + 9*((bg-40) + 9*at)); | ||||
if (xx != 0) | ||||
xx += MOST_EMBEDDED_COLOR_OFFSET; | ||||
*colorp = xx; | ||||
} | ||||
return 0; | ||||
} | ||||
return -1; | ||||
} | ||||
} | ||||
typedef struct | typedef struct | |||
{ | { | |||
unsigned char *bytes; | unsigned char *bytes; | |||
unsigned char byte; /* used if bytes is NULL */ | unsigned char byte; /* used if bytes is NULL */ | |||
unsigned int len; | unsigned int len; | |||
int color; | int color; | |||
} | } | |||
Multibyte_Cell_Type; | Multibyte_Cell_Type; | |||
static int most_analyse_line (unsigned char *begg, unsigned char *endd, | static int most_analyse_line (unsigned char *begg, unsigned char *endd, | |||
Multibyte_Cell_Type *cells, unsigned int num_cols, | Multibyte_Cell_Type *cells, unsigned int num_cols, | |||
int *start_colorp) | int *start_colorp, int *start_atp) | |||
{ | { | |||
unsigned char *beg, *end; | unsigned char *beg, *end; | |||
unsigned int min_col, max_col, prev_width; | unsigned int min_col, max_col, prev_width; | |||
unsigned int col, max_col_reached; | unsigned int col, max_col_reached; | |||
int default_attr; | int start_attr, start_at; | |||
Multibyte_Cell_Type *cell, *max_cell; | Multibyte_Cell_Type *cell, *max_cell; | |||
beg = begg; | beg = begg; | |||
end = endd; | end = endd; | |||
col = max_col_reached = 0; | col = max_col_reached = 0; | |||
cell = cells; | cell = cells; | |||
max_cell = cell; | max_cell = cell; | |||
min_col = Most_Column - 1; | min_col = Most_Column - 1; | |||
max_col = min_col + num_cols; | max_col = min_col + num_cols; | |||
default_attr = *start_colorp; | start_attr = *start_colorp; | |||
start_at = *start_atp; | ||||
prev_width = 1; | prev_width = 1; | |||
while (beg < end) | while (beg < end) | |||
{ | { | |||
int attr = default_attr; | int attr = start_attr; | |||
unsigned char ch; | unsigned char ch; | |||
unsigned char *pch = beg++; | unsigned char *pch = beg++; | |||
char buf[16]; | char buf[16]; | |||
if ('\n' == (ch = *pch)) | if ('\n' == (ch = *pch)) | |||
break; | break; | |||
if ((ch == '\r') && (Most_V_Opt == 0)) | if ((ch == '\r') && (Most_V_Opt == 0)) | |||
{ | { | |||
if (col > max_col_reached) max_col_reached = col; | if (col > max_col_reached) max_col_reached = col; | |||
skipping to change at line 305 | skipping to change at line 239 | |||
max_cell = cell + 1; | max_cell = cell + 1; | |||
} | } | |||
col++; | col++; | |||
nspaces--; | nspaces--; | |||
} | } | |||
continue; | continue; | |||
} | } | |||
#if 1 | #if 1 | |||
if ((ch == 033) && (Most_V_Opt == 0)) | if ((ch == 033) && (Most_V_Opt == 0)) | |||
{ | { | |||
int color; | int color, at; | |||
if (0 == most_parse_color_escape (&beg, end, &color)) | if (0 == most_parse_color_escape (&beg, end, &color, &at)) | |||
{ | { | |||
if (color != -1) default_attr = color; | if (color != -1) | |||
{ | ||||
start_attr = color; | ||||
start_at = at; | ||||
} | ||||
continue; | continue; | |||
} | } | |||
/* drop */ | /* drop */ | |||
} | } | |||
#endif | #endif | |||
if (ch & 0x80) | if (ch & 0x80) | |||
{ | { | |||
SLwchar_Type wch; | SLwchar_Type wch; | |||
if ((Most_UTF8_Mode) | if ((Most_UTF8_Mode) | |||
&& (NULL != SLutf8_decode (pch, end, &wch, NULL))) | && (NULL != SLutf8_decode (pch, end, &wch, NULL))) | |||
{ | { | |||
int width = SLwchar_wcwidth (wch); | int width = SLwchar_wcwidth (wch); | |||
beg = SLutf8_skip_chars (pch, end, 1, NULL, 1); | beg = SLutf8_skip_chars (pch, end, 1, NULL, 0); | |||
prev_width = width; | prev_width = width; | |||
if (width == 0) | if (width == 0) | |||
{ | { | |||
if (col <= min_col) continue; | ||||
col--; | col--; | |||
if ((col >= min_col) && (col < max_col)) | if (col < max_col) | |||
{ | { | |||
cell = cells + (col-min_col); | cell = cells + (col-min_col); | |||
cell->len += beg-pch; | cell->len += beg-pch; | |||
} | } | |||
col++; | col++; | |||
continue; | continue; | |||
} | } | |||
if ((col >= min_col) && (col < max_col)) | if ((col >= min_col) && (col < max_col)) | |||
{ | { | |||
skipping to change at line 435 | skipping to change at line 375 | |||
cell->byte = '.'; | cell->byte = '.'; | |||
cell->color = 0; | cell->color = 0; | |||
cell->len = 1; | cell->len = 1; | |||
if (cell >= max_cell) | if (cell >= max_cell) | |||
max_cell = cell + 1; | max_cell = cell + 1; | |||
} | } | |||
col++; | col++; | |||
} | } | |||
} | } | |||
} | } | |||
*start_colorp = default_attr; | *start_colorp = start_attr; | |||
*start_atp = start_at; | ||||
return max_cell - cells; | return max_cell - cells; | |||
} | } | |||
static void display_cells (Multibyte_Cell_Type *cell, unsigned int n, char dolla r) | static void display_cells (Multibyte_Cell_Type *cell, unsigned int n, char dolla r) | |||
{ | { | |||
Multibyte_Cell_Type *cell_max; | Multibyte_Cell_Type *cell_max; | |||
int last_color = -1; | int last_color = -1; | |||
cell_max = cell + n; | cell_max = cell + n; | |||
while (cell < cell_max) | while (cell < cell_max) | |||
skipping to change at line 476 | skipping to change at line 417 | |||
void most_display_line (int reset) | void most_display_line (int reset) | |||
{ | { | |||
unsigned char *beg, *end; | unsigned char *beg, *end; | |||
unsigned char dollar; | unsigned char dollar; | |||
static Multibyte_Cell_Type *cells; | static Multibyte_Cell_Type *cells; | |||
static unsigned int num_cells; | static unsigned int num_cells; | |||
unsigned int screen_cols; | unsigned int screen_cols; | |||
unsigned int num_cells_set; | unsigned int num_cells_set; | |||
static int last_color = 0; /* used for a line that wrapped */ | static int last_color = 0; /* used for a line that wrapped */ | |||
static int last_at = 0; | ||||
if (Most_B_Opt) | if (Most_B_Opt) | |||
{ | { | |||
output_binary_formatted_line (); | output_binary_formatted_line (); | |||
return; | return; | |||
} | } | |||
screen_cols = SLtt_Screen_Cols; | screen_cols = SLtt_Screen_Cols; | |||
if (num_cells != screen_cols + 1) | if (num_cells != screen_cols + 1) | |||
{ | { | |||
num_cells = screen_cols + 1; | num_cells = screen_cols + 1; | |||
SLfree ((char *) cells); | SLfree ((char *) cells); | |||
if (NULL == (cells = (Multibyte_Cell_Type *)SLcalloc (num_cells, sizeof ( Multibyte_Cell_Type)))) | if (NULL == (cells = (Multibyte_Cell_Type *)SLcalloc (num_cells, sizeof ( Multibyte_Cell_Type)))) | |||
most_exit_error ("Out of memory"); | most_exit_error ("Out of memory"); | |||
} | } | |||
(void) most_extract_line (&beg, &end); | (void) most_extract_line (&beg, &end); | |||
if (reset || (Most_W_Opt == 0)) | if (reset || (Most_W_Opt == 0)) | |||
last_color = 0; | { | |||
num_cells_set = most_analyse_line (beg, end, cells, num_cells, &last_color); | last_color = 0; | |||
last_at = 0; | ||||
} | ||||
num_cells_set = most_analyse_line (beg, end, cells, num_cells, &last_color, & | ||||
last_at); | ||||
dollar = 0; | dollar = 0; | |||
if (Most_W_Opt) | if (Most_W_Opt) | |||
{ | { | |||
if (Most_Show_Wrap_Marker | if (Most_Show_Wrap_Marker | |||
&& (end < Most_Eob) | && (end < Most_Eob) | |||
&& (*end != '\n')) | && (*end != '\n')) | |||
dollar = '\\'; | dollar = '\\'; | |||
} | } | |||
else if (num_cells_set > screen_cols) | else if (num_cells_set > screen_cols) | |||
dollar = '$'; | dollar = '$'; | |||
display_cells (cells, num_cells_set, dollar); | display_cells (cells, num_cells_set, dollar); | |||
} | } | |||
/* given a position in a line, return apparent distance from bol | /* given a position in a line, return apparent distance from bol | |||
expanding tabs, etc... up to pos */ | expanding tabs, etc... up to pos */ | |||
int most_apparant_distance (unsigned char *pos) | MOST_INT most_apparant_distance (unsigned char *pos) | |||
{ | { | |||
int i, prev_width; | MOST_INT i, prev_width; | |||
unsigned char *save_pos, ch; | unsigned char *save_pos, ch; | |||
unsigned int save_offset; | unsigned int save_offset; | |||
save_offset = Most_C_Offset; | save_offset = Most_C_Offset; | |||
save_pos = pos; | save_pos = pos; | |||
Most_C_Offset = (unsigned int) (pos - Most_Beg); | Most_C_Offset = (MOST_UINT) (pos - Most_Beg); | |||
pos = most_beg_of_line(); | pos = most_beg_of_line(); | |||
Most_C_Offset = save_offset; | Most_C_Offset = save_offset; | |||
i = 0; | i = 0; | |||
prev_width = 1; | prev_width = 1; | |||
while (pos < save_pos) | while (pos < save_pos) | |||
{ | { | |||
ch = *pos++; | ch = *pos++; | |||
if (IS_BYTE_PRINTABLE(ch)) | if (IS_BYTE_PRINTABLE(ch)) | |||
{ | { | |||
skipping to change at line 559 | skipping to change at line 505 | |||
continue; | continue; | |||
} | } | |||
if ((ch == '\t') && (Most_T_Opt == 0)) | if ((ch == '\t') && (Most_T_Opt == 0)) | |||
{ | { | |||
prev_width = Most_Tab_Width * (i/Most_Tab_Width + 1) - i; /* Most_T ab_Width column tabs */ | prev_width = Most_Tab_Width * (i/Most_Tab_Width + 1) - i; /* Most_T ab_Width column tabs */ | |||
i += prev_width; | i += prev_width; | |||
continue; | continue; | |||
} | } | |||
if ((ch == 033) && (Most_V_Opt == 0) | if ((ch == 033) && (Most_V_Opt == 0) | |||
&& (0 == most_parse_color_escape (&pos, save_pos, NULL))) | && (0 == most_parse_color_escape (&pos, save_pos, NULL, NULL))) | |||
continue; | continue; | |||
if (ch & 0x80) | if (ch & 0x80) | |||
{ | { | |||
SLwchar_Type wch; | SLwchar_Type wch; | |||
if ((Most_UTF8_Mode) | if ((Most_UTF8_Mode) | |||
&& (NULL != SLutf8_decode (pos-1, save_pos, &wch, NULL))) | && (NULL != SLutf8_decode (pos-1, save_pos, &wch, NULL))) | |||
{ | { | |||
prev_width = SLwchar_wcwidth (wch); | prev_width = SLwchar_wcwidth (wch); | |||
pos = SLutf8_skip_chars (pos-1, save_pos, 1, NULL, 1); | pos = SLutf8_skip_chars (pos-1, save_pos, 1, NULL, 1); | |||
skipping to change at line 596 | skipping to change at line 542 | |||
* pointed at b. Invisible character runs are not counted toward this | * pointed at b. Invisible character runs are not counted toward this | |||
* limit, i.e. strings that represent attributes, such as "_\b" for | * limit, i.e. strings that represent attributes, such as "_\b" for | |||
* underlines. | * underlines. | |||
* | * | |||
* If multi_column is non-zero, characters spanning more than one | * If multi_column is non-zero, characters spanning more than one | |||
* column will add their extra width to the column count. | * column will add their extra width to the column count. | |||
* | * | |||
* If there the end of the buffer is reached, as delimited by argument | * If there the end of the buffer is reached, as delimited by argument | |||
* e, then e is returned. | * e, then e is returned. | |||
*/ | */ | |||
unsigned char *most_forward_columns (unsigned char *b, unsigned char *e, unsigne d int num_cols) | unsigned char *most_forward_columns (unsigned char *b, unsigned char *e, MOST_UI NT num_cols) | |||
{ | { | |||
unsigned int col = 0; | MOST_UINT col = 0; | |||
unsigned int prev_width = 1; | MOST_UINT prev_width = 1; | |||
while (b < e) | while (b < e) | |||
{ | { | |||
unsigned char ch = *b++; | unsigned char ch = *b++; | |||
if (col >=num_cols) | if (col >=num_cols) | |||
{ | { | |||
if ((ch == 033) && (Most_V_Opt == 0)) | if ((ch == 033) && (Most_V_Opt == 0)) | |||
{ | { | |||
while ((ch == 033) | while ((ch == 033) | |||
&& (0 == most_parse_color_escape (&b, e, NULL)) | && (0 == most_parse_color_escape (&b, e, NULL, NULL)) | |||
&& (b < e)) | && (b < e)) | |||
ch = *b++; | ch = *b++; | |||
} | } | |||
b--; | b--; | |||
break; | break; | |||
} | } | |||
if (IS_BYTE_PRINTABLE(ch)) | if (IS_BYTE_PRINTABLE(ch)) | |||
{ | { | |||
col++; | col++; | |||
skipping to change at line 679 | skipping to change at line 625 | |||
{ | { | |||
prev_width = Most_Tab_Width * (col/Most_Tab_Width + 1) - col; | prev_width = Most_Tab_Width * (col/Most_Tab_Width + 1) - col; | |||
col += prev_width; | col += prev_width; | |||
} | } | |||
else | else | |||
col += 2; /* ^I */ | col += 2; /* ^I */ | |||
continue; | continue; | |||
} | } | |||
if ((ch == 033) && (Most_V_Opt == 0) | if ((ch == 033) && (Most_V_Opt == 0) | |||
&& (0 == most_parse_color_escape (&b, e, NULL))) | && (0 == most_parse_color_escape (&b, e, NULL, NULL))) | |||
continue; | continue; | |||
/* Ctrl-char ^X */ | /* Ctrl-char ^X */ | |||
prev_width = 2; | prev_width = 2; | |||
col += prev_width; | col += prev_width; | |||
} | } | |||
return b; | return b; | |||
} | } | |||
End of changes. 23 change blocks. | ||||
93 lines changed or deleted | 38 lines changed or added |