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