util/str: add r_str_ansi_crop function and tests

This commit is contained in:
Riccardo Schirone 2015-07-29 21:33:13 +02:00
parent 46ffc1346f
commit 5adf6b4043
3 changed files with 63 additions and 1 deletions

View File

@ -512,6 +512,7 @@ R_API const char *r_str_ansi_chrn(const char *str, int n);
R_API int r_str_ansi_len(const char *str);
R_API int r_str_ansi_chop(char *str, int str_len, int n);
R_API int r_str_ansi_filter(char *str, char **out, int **cposs, int len);
R_API char *r_str_ansi_crop(const char *str, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2);
R_API int r_str_word_count(const char *string);
R_API int r_str_char_count(const char *string, char ch);
R_API char *r_str_word_get0set(char *stra, int stralen, int idx, const char *newstr, int *newlen);

View File

@ -1125,6 +1125,57 @@ R_API int r_str_ansi_filter(char *str, char **out, int **cposs, int len) {
return j;
}
R_API char *r_str_ansi_crop(const char *str, unsigned int x, unsigned int y,
unsigned int x2, unsigned int y2) {
char *r, *ret;
unsigned int ch = 0, cw = 0;
if (x2 < 1 || y2 < 1 || !str)
return strdup ("");
r = ret = strdup (str);
while (*str) {
/* crop height */
if (ch >= y2) {
r--;
break;
}
if (*str == '\n') {
if (ch >= y && ch < y2)
*r++ = *str;
str++;
ch++;
cw = 0;
} else if (*str == 0x1b && str + 1 && *(str + 1) == '[') {
const char *ptr;
/* copy 0x1b and [ */
*r++ = *str++;
*r++ = *str++;
for (ptr = str; *ptr && *ptr != 'J' && *ptr != 'm' && *ptr != 'H'; ++ptr)
*r++ = *ptr;
*r++ = *ptr++;
str = ptr;
} else {
if (ch >= y && ch < y2 && cw >= x && cw < x2)
*r++ = *str;
/* crop width */
/* skip until newline */
if (cw >= x2) {
while (*str && *str != '\n')
str++;
} else {
str++;
}
cw++;
}
}
*r = 0;
return ret;
}
R_API void r_str_filter_zeroline(char *str, int len) {
int i;
for (i=0; i<len && str[i]; i++) {

View File

@ -133,6 +133,16 @@ int main(int argc, char *argv[]) {
res_s = r_str_replace_thunked(orig, str, cpos, l, "ell", "\x1b[31mell\x1b[39;49m", 1);
check("\x1b[30mH\x1b[31mell\x1b[39;49mo\nIt'\x1b[33ms an h\x1b[31mell\x1b[39;49m\n", res_s, "r_str_ansi_filter + replace_thunked");
/* printf ("%s\n", r_file_slurp_line ("/etc/fstab", 4, 0)); */
crop =
"\x1b[30mThis is the \x1b[34mfirst line\n"
"\x1b[32mThis \x1b[31mis the\x1b[39;49m second\n"
"\n"
"And this is the \x1b[32mlast\n";
crop_exp =
"\x1b[30m\x1b[34m\x1b[32mis \x1b[31mis the\x1b[39;49m se\n"
"\n"
"d this is th\n";
check(crop_exp, r_str_ansi_crop(crop, 2, 1, 14, 10), "r_str_ansi_crop");
return 0;
}