Annotation of src/usr.bin/less/cvt.c, Revision 1.10
1.1 shadchin 1: /*
1.3 shadchin 2: * Copyright (C) 1984-2012 Mark Nudelman
1.5 nicm 3: * Modified for use with illumos by Garrett D'Amore.
4: * Copyright 2014 Garrett D'Amore <garrett@damore.org>
1.1 shadchin 5: *
6: * You may distribute under the terms of either the GNU General Public
7: * License or the Less License, as specified in the README file.
8: *
1.3 shadchin 9: * For more information, see the README file.
1.4 nicm 10: */
1.1 shadchin 11:
12: /*
13: * Routines to convert text in various ways. Used by search.
14: */
15:
1.7 mmcc 16: #include "charset.h"
1.1 shadchin 17: #include "less.h"
18:
19: extern int utf_mode;
20:
21: /*
22: * Get the length of a buffer needed to convert a string.
23: */
1.4 nicm 24: int
25: cvt_length(int len)
1.1 shadchin 26: {
27: if (utf_mode)
28: /*
1.4 nicm 29: * Just copying a string in UTF-8 mode can cause it to grow
1.1 shadchin 30: * in length.
31: * Four output bytes for one input byte is the worst case.
32: */
33: len *= 4;
34: return (len + 1);
35: }
36:
37: /*
38: * Allocate a chpos array for use by cvt_text.
39: */
1.4 nicm 40: int *
41: cvt_alloc_chpos(int len)
1.1 shadchin 42: {
43: int i;
1.4 nicm 44: int *chpos = ecalloc(sizeof (int), len);
1.1 shadchin 45: /* Initialize all entries to an invalid position. */
1.8 deraadt 46: for (i = 0; i < len; i++)
1.1 shadchin 47: chpos[i] = -1;
48: return (chpos);
49: }
50:
51: /*
52: * Convert text. Perform the transformations specified by ops.
53: * Returns converted text in odst. The original offset of each
54: * odst character (when it was in osrc) is returned in the chpos array.
55: */
1.4 nicm 56: void
57: cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops)
1.1 shadchin 58: {
59: char *dst;
1.3 shadchin 60: char *edst = odst;
1.1 shadchin 61: char *src;
1.4 nicm 62: char *src_end;
1.10 ! schwarze 63: wchar_t ch;
! 64: int len;
1.1 shadchin 65:
66: if (lenp != NULL)
67: src_end = osrc + *lenp;
68: else
69: src_end = osrc + strlen(osrc);
70:
1.8 deraadt 71: for (src = osrc, dst = odst; src < src_end; ) {
1.1 shadchin 72: int src_pos = src - osrc;
73: int dst_pos = dst - odst;
1.10 ! schwarze 74: if ((len = mbtowc(&ch, src, src_end - src)) < 1)
! 75: ch = L'\0';
1.4 nicm 76: if ((ops & CVT_BS) && ch == '\b' && dst > odst) {
1.10 ! schwarze 77: src++;
1.1 shadchin 78: /* Delete backspace and preceding char. */
79: do {
80: dst--;
81: } while (dst > odst &&
1.4 nicm 82: !IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
1.9 schwarze 83: } else if ((ops & CVT_ANSI) && ch == ESC) {
1.1 shadchin 84: /* Skip to end of ANSI escape sequence. */
1.8 deraadt 85: src++; /* skip the CSI start char */
1.1 shadchin 86: while (src < src_end)
87: if (!is_ansi_middle(*src++))
88: break;
1.10 ! schwarze 89: } else if (len < 1) {
! 90: *dst++ = *src++;
! 91: if (chpos != NULL)
! 92: chpos[dst_pos] = src_pos;
1.4 nicm 93: } else {
1.10 ! schwarze 94: src += len;
1.1 shadchin 95: /* Just copy the char to the destination buffer. */
1.6 mmcc 96: if ((ops & CVT_TO_LC) && iswupper(ch))
97: ch = towlower(ch);
1.10 ! schwarze 98: dst += wctomb(dst, ch);
1.3 shadchin 99: /* Record the original position of the char. */
100: if (chpos != NULL)
1.1 shadchin 101: chpos[dst_pos] = src_pos;
102: }
1.3 shadchin 103: if (dst > edst)
104: edst = dst;
1.1 shadchin 105: }
1.3 shadchin 106: if ((ops & CVT_CRLF) && edst > odst && edst[-1] == '\r')
107: edst--;
108: *edst = '\0';
1.1 shadchin 109: if (lenp != NULL)
1.3 shadchin 110: *lenp = edst - odst;
1.1 shadchin 111: }