gdb - Local mods (compile)
[dragonfly.git] / bin / ls / util.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Michael Fischbein.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
dc71b7ab 16 * 3. Neither the name of the University nor the names of its contributors
984263bc
MD
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
1de703da
MD
31 *
32 * @(#)util.c 8.3 (Berkeley) 4/2/94
aae9ea87 33 * $FreeBSD: src/bin/ls/util.c,v 1.35 2004/05/03 11:48:55 tjr Exp $
92c726f6 34 * $DragonFly: src/bin/ls/util.c,v 1.8 2008/02/14 09:33:24 matthias Exp $
984263bc
MD
35 */
36
984263bc
MD
37#include <sys/types.h>
38#include <sys/stat.h>
39
40#include <ctype.h>
41#include <err.h>
42#include <fts.h>
aae9ea87 43#include <limits.h>
984263bc
MD
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
aae9ea87
JR
47#include <wchar.h>
48#include <wctype.h>
984263bc
MD
49
50#include "ls.h"
51#include "extern.h"
52
aae9ea87
JR
53int
54prn_normal(const char *s)
55{
56 mbstate_t mbs;
57 wchar_t wc;
58 int i, n;
59 size_t clen;
60
61 memset(&mbs, 0, sizeof(mbs));
62 n = 0;
63 while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
64 if (clen == (size_t)-2) {
65 n += printf("%s", s);
66 break;
67 }
68 if (clen == (size_t)-1) {
69 memset(&mbs, 0, sizeof(mbs));
70 putchar((unsigned char)*s);
71 s++;
72 n++;
73 continue;
74 }
75 for (i = 0; i < (int)clen; i++)
76 putchar((unsigned char)s[i]);
77 s += clen;
78 if (iswprint(wc))
79 n += wcwidth(wc);
80 }
81 return (n);
82}
83
984263bc
MD
84int
85prn_printable(const char *s)
86{
aae9ea87
JR
87 mbstate_t mbs;
88 wchar_t wc;
89 int i, n;
90 size_t clen;
984263bc 91
aae9ea87
JR
92 memset(&mbs, 0, sizeof(mbs));
93 n = 0;
94 while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
95 if (clen == (size_t)-1) {
96 putchar('?');
97 s++;
98 n++;
99 memset(&mbs, 0, sizeof(mbs));
100 continue;
101 }
102 if (clen == (size_t)-2) {
984263bc 103 putchar('?');
aae9ea87
JR
104 n++;
105 break;
106 }
107 if (!iswprint(wc)) {
108 putchar('?');
109 s += clen;
110 n++;
111 continue;
112 }
113 for (i = 0; i < (int)clen; i++)
114 putchar((unsigned char)s[i]);
115 s += clen;
116 n += wcwidth(wc);
117 }
118 return (n);
984263bc
MD
119}
120
121/*
122 * The fts system makes it difficult to replace fts_name with a different-
123 * sized string, so we just calculate the real length here and do the
124 * conversion in prn_octal()
125 *
126 * XXX when using f_octal_escape (-b) rather than f_octal (-B), the
127 * length computed by len_octal may be too big. I just can't be buggered
128 * to fix this as an efficient fix would involve a lookup table. Same goes
129 * for the rather inelegant code in prn_octal.
130 *
131 * DES 1998/04/23
132 */
133
134size_t
135len_octal(const char *s, int len)
136{
aae9ea87
JR
137 mbstate_t mbs;
138 wchar_t wc;
139 size_t clen, r;
984263bc 140
aae9ea87
JR
141 memset(&mbs, 0, sizeof(mbs));
142 r = 0;
143 while (len != 0 && (clen = mbrtowc(&wc, s, len, &mbs)) != 0) {
144 if (clen == (size_t)-1) {
145 r += 4;
146 s++;
147 len--;
148 memset(&mbs, 0, sizeof(mbs));
149 continue;
150 }
151 if (clen == (size_t)-2) {
152 r += 4 * len;
153 break;
154 }
155 if (iswprint(wc))
156 r++;
157 else
158 r += 4 * clen;
159 s += clen;
160 }
161 return (r);
984263bc
MD
162}
163
164int
165prn_octal(const char *s)
166{
aae9ea87
JR
167 static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
168 const char *p;
169 mbstate_t mbs;
170 wchar_t wc;
171 size_t clen;
172 unsigned char ch;
173 int goodchar, i, len, prtlen;
174
175 memset(&mbs, 0, sizeof(mbs));
176 len = 0;
177 while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
178 goodchar = clen != (size_t)-1 && clen != (size_t)-2;
179 if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
180 for (i = 0; i < (int)clen; i++)
181 putchar((unsigned char)s[i]);
182 len += wcwidth(wc);
183 } else if (goodchar && f_octal_escape && wc >= 0 &&
184 wc <= (wchar_t)UCHAR_MAX &&
185 (p = strchr(esc, (char)wc)) != NULL) {
186 putchar('\\');
187 putchar(p[1]);
188 len += 2;
189 } else {
190 if (goodchar)
191 prtlen = clen;
192 else if (clen == (size_t)-1)
193 prtlen = 1;
194 else
195 prtlen = strlen(s);
196 for (i = 0; i < prtlen; i++) {
197 ch = (unsigned char)s[i];
198 putchar('\\');
984263bc
MD
199 putchar('0' + (ch >> 6));
200 putchar('0' + ((ch >> 3) & 7));
201 putchar('0' + (ch & 7));
aae9ea87 202 len += 4;
984263bc 203 }
984263bc 204 }
aae9ea87
JR
205 if (clen == (size_t)-2)
206 break;
207 if (clen == (size_t)-1) {
208 memset(&mbs, 0, sizeof(mbs));
209 s++;
210 } else
211 s += clen;
984263bc 212 }
aae9ea87 213 return (len);
984263bc
MD
214}
215
216void
217usage(void)
218{
57fed2af 219 fprintf(stderr,
984263bc 220#ifdef COLORLS
7d364f99 221 "usage: ls [-ABCFGHILPRSTWabcdfghiklmnopqrstuwxy1]"
984263bc 222#else
7d364f99 223 "usage: ls [-ABCFHILPRSTWabcdfghiklmnopqrstuwxy1]"
984263bc
MD
224#endif
225 " [file ...]\n");
226 exit(1);
227}