]>
git.saurik.com Git - apple/libc.git/blob - libdarwin/stdio.c
c1d1585e73521e5e04af1c1d4ffce973203a0eb8
2 * Copyright (c) 2018 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 fcheck_np(FILE *f
, size_t n
, size_t expected
)
38 __builtin_unreachable();
49 if (os_fd_valid(dfd
)) {
60 os_crash("failed to dup fd");
62 os_crash("unhandled error: %s", symerror_np(errno
));
70 zsnprintf_np(char *buff
, size_t len
, const char *fmt
, ...)
76 np
= vsnprintf(buff
, len
, fmt
, ap
);
81 } else if ((size_t)np
>= len
) {
89 crfprintf_np(FILE *f
, const char *fmt
, ...)
94 vcrfprintf_np(f
, fmt
, ap
);
99 vcrfprintf_np(FILE *f
, const char *fmt
, va_list ap
)
101 vfprintf(f
, fmt
, ap
);
106 wfprintf_np(FILE *f
, ssize_t initpad
, size_t pad
, size_t width
,
107 const char *fmt
, ...)
112 vwfprintf_np(f
, initpad
, pad
, width
, fmt
, ap
);
117 vwfprintf_np(FILE *f
, ssize_t initpad
, size_t pad
, size_t width
,
118 const char *fmt
, va_list ap
)
120 char *__os_free string
= NULL
;
121 char *__os_free working
= NULL
;
122 char *__os_free init_padding
= NULL
;
123 char *__os_free padding
= NULL
;
124 const char *curline
= NULL
;;
126 size_t initpad_labs
= (size_t)labs(initpad
);
129 if (width
&& width
<= pad
) {
130 os_crash("width cannot be smaller than pad");
132 if (width
&& (initpad
> 0) && width
<= initpad_labs
) {
133 os_crash("width cannot be smaller than initpad");
135 if (width
&& (initpad
< 0) && width
<= initpad_labs
) {
136 os_crash("width cannot be smaller than negative initpad");
139 ret
= vasprintf(&string
, fmt
, ap
);
140 if (ret
< 0 || !string
) {
147 // The working buffer will always be large enough to handle any individual
148 // line. vasprintf(3) returns the number of characters printed not including
149 // the null terminator, so add space for that.
150 working
= malloc(left
+ 1);
155 init_padding
= malloc(initpad_labs
+ 1);
161 memset(init_padding
, ' ', initpad
);
162 init_padding
[initpad
] = 0;
167 padding
= malloc(pad
+ 1);
172 memset(padding
, ' ', pad
);
176 size_t which_pad
= pad
;
177 char *which_padding
= padding
;
178 bool findspace
= true;
179 size_t n2consume
= 0;
180 char *breakchar
= NULL
;
182 if (curline
== string
) {
183 which_padding
= init_padding
;
184 which_pad
= initpad_labs
;
188 // Width is unconstrained so just consume the entire string and
189 // indent any new lines within.
193 n2consume
= width
- which_pad
;
194 if (n2consume
>= left
) {
200 strlcpy(working
, curline
, n2consume
+ 1);
201 breakchar
= strchr(working
, '\n');
202 if (!breakchar
&& findspace
) {
203 // No new line within our maximally-constrained width of characters,
204 // so search for a space instead.
205 breakchar
= strrchr(working
, ' ');
209 // Found something to break on, so nerf it and only consume the
210 // characters up until that break character.
212 n2consume
= (size_t)(breakchar
- working
);
213 curline
+= n2consume
+ 1;
216 fprintf(f
, "%s%s\n", which_padding
, working
);