Annotation of src/usr.bin/less/cvt.c, Revision 1.1.1.2
1.1 shadchin 1: /*
1.1.1.2 ! 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.1.1.2 ! shadchin 7: * For more information, see the README file.
1.1 shadchin 8: */
9:
10: /*
11: * Routines to convert text in various ways. Used by search.
12: */
13:
14: #include "less.h"
15: #include "charset.h"
16:
17: extern int utf_mode;
18:
19: /*
20: * Get the length of a buffer needed to convert a string.
21: */
22: public int
23: cvt_length(len, ops)
24: int len;
25: int ops;
26: {
27: if (utf_mode)
28: /*
29: * Just copying a string in UTF-8 mode can cause it to grow
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: */
40: public int *
41: cvt_alloc_chpos(len)
42: int len;
43: {
44: int i;
45: int *chpos = (int *) ecalloc(sizeof(int), len);
46: /* Initialize all entries to an invalid position. */
47: for (i = 0; i < len; i++)
48: chpos[i] = -1;
49: return (chpos);
50: }
51:
52: /*
53: * Convert text. Perform the transformations specified by ops.
54: * Returns converted text in odst. The original offset of each
55: * odst character (when it was in osrc) is returned in the chpos array.
56: */
57: public void
58: cvt_text(odst, osrc, chpos, lenp, ops)
59: char *odst;
60: char *osrc;
61: int *chpos;
62: int *lenp;
63: int ops;
64: {
65: char *dst;
1.1.1.2 ! shadchin 66: char *edst = odst;
1.1 shadchin 67: char *src;
68: register char *src_end;
69: LWCHAR ch;
70:
71: if (lenp != NULL)
72: src_end = osrc + *lenp;
73: else
74: src_end = osrc + strlen(osrc);
75:
76: for (src = osrc, dst = odst; src < src_end; )
77: {
78: int src_pos = src - osrc;
79: int dst_pos = dst - odst;
80: ch = step_char(&src, +1, src_end);
81: if ((ops & CVT_BS) && ch == '\b' && dst > odst)
82: {
83: /* Delete backspace and preceding char. */
84: do {
85: dst--;
86: } while (dst > odst &&
87: !IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
88: } else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
89: {
90: /* Skip to end of ANSI escape sequence. */
91: src++; /* skip the CSI start char */
92: while (src < src_end)
93: if (!is_ansi_middle(*src++))
94: break;
95: } else
96: {
97: /* Just copy the char to the destination buffer. */
98: if ((ops & CVT_TO_LC) && IS_UPPER(ch))
99: ch = TO_LOWER(ch);
1.1.1.2 ! shadchin 100: #if !SMALL
1.1 shadchin 101: put_wchar(&dst, ch);
1.1.1.2 ! shadchin 102: #else
! 103: *dst++ = (char)ch;
! 104: #endif /* !SMALL */
! 105: /* Record the original position of the char. */
! 106: if (chpos != NULL)
1.1 shadchin 107: chpos[dst_pos] = src_pos;
108: }
1.1.1.2 ! shadchin 109: if (dst > edst)
! 110: edst = dst;
1.1 shadchin 111: }
1.1.1.2 ! shadchin 112: if ((ops & CVT_CRLF) && edst > odst && edst[-1] == '\r')
! 113: edst--;
! 114: *edst = '\0';
1.1 shadchin 115: if (lenp != NULL)
1.1.1.2 ! shadchin 116: *lenp = edst - odst;
! 117: /* FIXME: why was this here? if (chpos != NULL) chpos[dst - odst] = src - osrc; */
1.1 shadchin 118: }