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