"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/line.c" between
most-5.0.0a.tar.gz and most-5.1.0.tar.gz

About: most is a textfile paging program (supports multiple windows and can scroll left and right).

line.c  (most-5.0.0a):line.c  (most-5.1.0)
/* /*
This file is part of MOST. This file is part of MOST.
Copyright (c) 1991, 1999, 2002, 2005, 2006, 2007 John E. Davis Copyright (c) 1991, 1999, 2002, 2005-2018, 2019 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 131 skipping to change at line 131
/* Here *begp points to the char after \e. /* Here *begp points to the char after \e.
* The general escape sequence parsed here is assumed to look like: * The general escape sequence parsed here is assumed to look like:
* \e[ XX ; ... m * \e[ XX ; ... m
* If 30 <= XX <= 37, then it specifies the foreground color * If 30 <= XX <= 37, then it specifies the foreground color
* If 40 <= XX <= 47, then a background color is specified * If 40 <= XX <= 47, then a background color is specified
* If 0 <= XX <= 8, then an attribute (e.g, 8) is specified. * If 0 <= XX <= 8, then an attribute (e.g, 8) is specified.
* These numbers will be encoded as: * These numbers will be encoded as:
* offset + (FG-30 + 8*(BG-40 + 9*attribute)) * offset + (FG-30 + 8*(BG-40 + 9*attribute))
*/ */
static int parse_escape (unsigned char **begp, unsigned char *end, int *colorp) int most_parse_color_escape (unsigned char **begp, unsigned char *end, int *colo rp)
{ {
unsigned char *beg = *begp; unsigned char *beg = *begp;
int fg = 38, bg = 48, at = 0; int fg = 38, bg = 48, at = 0;
int xx; int xx;
if ((beg >= end) || (*beg != '[')) if ((beg >= end) || (*beg != '['))
return -1; return -1;
beg++; /* skip [ */ beg++; /* skip [ */
#if 1
if ((beg < end) && (*beg == 'K'))
{
if (colorp != NULL) *colorp = -1;
*begp = beg + 1;
return 0;
}
#endif
while (1) while (1)
{ {
xx = 0; xx = 0;
while ((beg < end) && isdigit (*beg)) while ((beg < end) && isdigit (*beg))
{ {
xx = xx*10 + (*beg - '0'); xx = xx*10 + (*beg - '0');
beg++; beg++;
} }
if ((xx >= 0) && (xx <= 8)) if ((xx >= 0) && (xx <= 8))
at = xx; at = xx;
skipping to change at line 192 skipping to change at line 201
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)
{ {
unsigned char *beg, *end; unsigned char *beg, *end;
unsigned int min_col, max_col; unsigned int min_col, max_col, prev_width;
unsigned int col, max_col_reached; unsigned int col, max_col_reached;
int default_attr; int default_attr;
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 = 0; default_attr = *start_colorp;
prev_width = 1;
while (beg < end) while (beg < end)
{ {
int attr = default_attr; int attr = default_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;
col = 0; col = 0;
prev_width = 1;
continue; continue;
} }
if ((ch == '\b') && (Most_V_Opt == 0)) if ((ch == '\b') && (Most_V_Opt == 0))
{ {
if (col > max_col_reached) max_col_reached = col; if (col > max_col_reached) max_col_reached = col;
/* FIXME: This does not account for double-width characters */ if (col < prev_width)
if (col > 0) col = 0;
col--; else
col -= prev_width;
continue; continue;
} }
if (col < max_col_reached) /* overstrike */ if (col < max_col_reached) /* overstrike */
{ {
attr = MOST_BOLD_COLOR; attr = MOST_BOLD_COLOR;
if ((col >= min_col) && (col < max_col)) if ((col >= min_col) && (col < max_col))
{ {
cell = cells + (col-min_col); cell = cells + (col-min_col);
if (cell->bytes[0] == '_') if (cell->bytes[0] == '_')
skipping to change at line 265 skipping to change at line 277
if ((col >= min_col) && (col < max_col)) if ((col >= min_col) && (col < max_col))
{ {
cell = cells + (col-min_col); cell = cells + (col-min_col);
cell->bytes = pch; cell->bytes = pch;
cell->len = 1; cell->len = 1;
cell->color = attr; cell->color = attr;
if (cell >= max_cell) if (cell >= max_cell)
max_cell = cell + 1; max_cell = cell + 1;
} }
col++; col++;
prev_width = 1;
continue; continue;
} }
if ((ch == '\t') && (Most_T_Opt == 0) && (Most_Tab_Width)) if ((ch == '\t') && (Most_T_Opt == 0) && (Most_Tab_Width))
{ {
int nspaces = Most_Tab_Width * (col/Most_Tab_Width + 1) - col; int nspaces = Most_Tab_Width * (col/Most_Tab_Width + 1) - col;
prev_width = nspaces;
while (nspaces > 0) while (nspaces > 0)
{ {
if ((col >= min_col) && (col < max_col)) if ((col >= min_col) && (col < max_col))
{ {
cell = cells + (col-min_col); cell = cells + (col-min_col);
cell->bytes = &cell->byte; cell->bytes = &cell->byte;
cell->byte = ' '; cell->byte = ' ';
cell->color = attr; cell->color = attr;
cell->len = 1; cell->len = 1;
if (cell >= max_cell) if (cell >= max_cell)
skipping to change at line 292 skipping to change at line 306
} }
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;
if (0 == parse_escape (&beg, end, &color)) if (0 == most_parse_color_escape (&beg, end, &color))
{ {
default_attr = color; if (color != -1) default_attr = color;
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, 1);
prev_width = width;
if (width == 0) if (width == 0)
{ {
col--; col--;
if ((col >= min_col) && (col < max_col)) if ((col >= min_col) && (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;
skipping to change at line 350 skipping to change at line 365
if (cell >= max_cell) if (cell >= max_cell)
max_cell = cell + 1; max_cell = cell + 1;
} }
col++; col++;
} }
continue; continue;
} }
/* Otherwise, this displays as <XX> and takes up 4 character cells * / /* Otherwise, this displays as <XX> and takes up 4 character cells * /
sprintf (buf, "<%02X>", (unsigned int) ch); sprintf (buf, "<%02X>", (unsigned int) ch);
prev_width = 4;
/* drop */ /* drop */
} }
else else
{ {
/* Otherwise we have a Ctrl-char displayed as ^X */ /* Otherwise we have a Ctrl-char displayed as ^X */
if (ch == 0x7F) ch = '?'; if (ch == 0x7F) ch = '?';
else ch += '@'; else ch += '@';
sprintf (buf, "^%c", ch); sprintf (buf, "^%c", ch);
prev_width = 2;
} }
pch = (unsigned char *)buf; pch = (unsigned char *)buf;
while (*pch) while (*pch)
{ {
if ((col >= min_col) && (col < max_col)) if ((col >= min_col) && (col < max_col))
{ {
cell = cells + (col-min_col); cell = cells + (col-min_col);
cell->bytes = &cell->byte; cell->bytes = &cell->byte;
cell->byte = *pch; cell->byte = *pch;
skipping to change at line 418 skipping to change at line 435
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;
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; int last_color = -1;
last_color = -1;
cell_max = cell + n; cell_max = cell + n;
while (cell < cell_max) while (cell < cell_max)
{ {
if (last_color != cell->color) if (last_color != cell->color)
{ {
last_color = cell->color; last_color = cell->color;
SLsmg_set_color (last_color); SLsmg_set_color (last_color);
} }
SLsmg_write_chars (cell->bytes, cell->bytes + cell->len); SLsmg_write_chars (cell->bytes, cell->bytes + cell->len);
cell++; cell++;
skipping to change at line 450 skipping to change at line 467
SLsmg_set_color (0); SLsmg_set_color (0);
SLsmg_erase_eol (); SLsmg_erase_eol ();
if (dollar) if (dollar)
{ {
SLsmg_gotorc (SLsmg_get_row (), SLtt_Screen_Cols-1); SLsmg_gotorc (SLsmg_get_row (), SLtt_Screen_Cols-1);
SLsmg_write_nchars (&dollar, 1); SLsmg_write_nchars (&dollar, 1);
} }
} }
void most_display_line (void) 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 */
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 *)SLmalloc (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);
num_cells_set = most_analyse_line (beg, end, cells, num_cells);
if (reset || (Most_W_Opt == 0))
last_color = 0;
num_cells_set = most_analyse_line (beg, end, cells, num_cells, &last_color);
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 apparant 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) int most_apparant_distance (unsigned char *pos)
{ {
int i; 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 = (unsigned int) (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;
while (pos < save_pos) while (pos < save_pos)
{ {
ch = *pos++; ch = *pos++;
if (IS_BYTE_PRINTABLE(ch)) if (IS_BYTE_PRINTABLE(ch))
{ {
i++; i++;
prev_width = 1;
continue; continue;
} }
if ((ch == '\b') && (Most_V_Opt == 0)) if ((ch == '\b') && (Most_V_Opt == 0))
{ {
if (i > 0) i--; i -= prev_width;
if (i < 0) i = 0;
continue; continue;
} }
if ((ch == '\015') && (Most_V_Opt == 0)) if ((ch == '\r') && (Most_V_Opt == 0))
{ {
if (i != 1) i = 0; if (i != 1) i = 0;
prev_width = 1;
continue; continue;
} }
if ((ch == '\t') && (Most_T_Opt == 0)) if ((ch == '\t') && (Most_T_Opt == 0))
{ {
i = Most_Tab_Width * (i/Most_Tab_Width + 1); /* Most_Tab_Width colu prev_width = Most_Tab_Width * (i/Most_Tab_Width + 1) - i; /* Most_T
mn tabs */ ab_Width column tabs */
i += prev_width;
continue; continue;
} }
if ((ch == 033) && (Most_V_Opt == 0) if ((ch == 033) && (Most_V_Opt == 0)
&& (0 == parse_escape (&pos, save_pos, NULL))) && (0 == most_parse_color_escape (&pos, save_pos, 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);
pos = SLutf8_skip_chars (pos-1, save_pos, 1, NULL, 1); pos = SLutf8_skip_chars (pos-1, save_pos, 1, NULL, 1);
i++; i += prev_width;
continue; continue;
} }
i += 4; /* <XX> */ prev_width = 4;
i += prev_width; /* <XX> */
continue; continue;
} }
i += 2; /* ^X */ prev_width = 2;
i += prev_width; /* ^X */
} }
return i; return i;
} }
/* /*
* Returns a pointer to the num_cols'th character after the one * Returns a pointer to the num_cols'th character after the one
* 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.
* *
skipping to change at line 572 skipping to change at line 601
* 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, unsigne d int num_cols)
{ {
unsigned int col = 0; unsigned int col = 0;
unsigned int prev_width = 1; unsigned int prev_width = 1;
while ((b < e) while (b < e)
&& (col < num_cols))
{ {
unsigned char ch = *b++; unsigned char ch = *b++;
if (IS_BYTE_PRINTABLE(ch)) if (col >=num_cols)
{ {
col++; if ((ch == 033) && (Most_V_Opt == 0))
prev_width = 1; {
continue; while ((ch == 033)
&& (0 == most_parse_color_escape (&b, e, NULL))
&& (b < e))
ch = *b++;
}
b--;
break;
} }
if ((ch == '\b') || (ch == '\t') || (ch == '\r')) if (IS_BYTE_PRINTABLE(ch))
{ {
switch (ch) col++;
{ prev_width = 1;
case '\b':
if (Most_V_Opt == 0)
{
if (col < prev_width)
col = 0;
else
col -= prev_width;
}
else col += 2; /* ^H */
break;
case '\r':
if (Most_V_Opt == 0)
{
prev_width = 1;
col = 0;
}
else col += 2; /* ^M */
break;
case '\t':
if (Most_T_Opt == 0)
{
prev_width = Most_Tab_Width * (col/Most_Tab_Width + 1) - c
ol;
col += prev_width;
}
else
col += 2; /* ^I */
break;
}
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 (b-1, e, &wch, NULL))) && (NULL != SLutf8_decode (b-1, e, &wch, NULL)))
{ {
b = SLutf8_skip_chars (b-1, e, 1, NULL, 1); b = SLutf8_skip_chars (b-1, e, 1, NULL, 1);
prev_width = SLwchar_wcwidth (wch); prev_width = SLwchar_wcwidth (wch);
col += prev_width; col += prev_width;
continue; continue;
} }
prev_width = 4; prev_width = 4;
col += prev_width; /* <XX> */ col += prev_width; /* <XX> */
continue; continue;
} }
if (ch == '\b')
{
if (Most_V_Opt == 0)
{
if (col < prev_width)
col = 0;
else
col -= prev_width;
}
else col += 2; /* ^H */
continue;
}
if (ch == '\r')
{
if (Most_V_Opt == 0)
{
prev_width = 1;
col = 0;
}
else col += 2; /* ^M */
continue;
}
if (ch == '\t')
{
if (Most_T_Opt == 0)
{
prev_width = Most_Tab_Width * (col/Most_Tab_Width + 1) - col;
col += prev_width;
}
else
col += 2; /* ^I */
continue;
}
if ((ch == 033) && (Most_V_Opt == 0) if ((ch == 033) && (Most_V_Opt == 0)
&& (0 == parse_escape (&b, e, NULL))) && (0 == most_parse_color_escape (&b, e, 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. 42 change blocks. 
66 lines changed or deleted 105 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)