1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 #pragma ident "%Z%%M% %I% %E% SMI"
23
24 /*
25 * Copyright (c) 1987, 1988, 1989, 1990 by Sun Microsystems, Inc.
26 */
27
28 /* Copyright (c) 1988 AT&T */
29 /* All Rights Reserved */
30
31 /*
32 * Subroutines for the 4.0 compatibility run-time link editor.
33 */
34 #include <varargs.h>
35 #include <sys/types.h>
36
37 /*
38 * Local "printf" & stdio facilities.
39 */
40 int stdout = 1; /* File descriptor for output */
41 int stderr = 2; /* File descriptor for errors */
42
43 static char *printn();
44 static void prf();
45 static void doprf();
46 static int _write();
47
48 /*
49 * printf
50 */
51 /*VARARGS1*/
printf(fmt,va_alist)52 printf(fmt, va_alist)
53 char *fmt;
54 va_dcl
55 {
56 va_list x1;
57
58 va_start(x1);
59 prf(stdout, fmt, x1);
60 va_end(x1);
61 }
62
63 /*
64 * fprintf
65 */
66 /*VARARGS2*/
fprintf(fd,fmt,va_alist)67 fprintf(fd, fmt, va_alist)
68 int fd;
69 char *fmt;
70 va_dcl
71 {
72 va_list x1;
73
74 va_start(x1);
75 prf(fd, fmt, x1);
76 va_end(x1);
77 }
78
79 /*
80 * panic
81 */
82 /*VARARGS2*/
panic(fmt,va_alist)83 panic(fmt, va_alist)
84 char *fmt;
85 va_dcl
86 {
87 va_list x1;
88 extern char *program_name;
89
90 va_start(x1);
91 prf(stderr, "%s (4.x.ld.so): ", program_name);
92 prf(stderr, fmt, x1);
93 prf(stderr, "\n", x1);
94 va_end(x1);
95 _exit(127);
96 /* NOTREACHED */
97 }
98
99 /*
100 * sprintf
101 */
102 /*VARARGS2*/
sprintf(cp,fmt,va_alist)103 sprintf(cp, fmt, va_alist)
104 char *cp;
105 char *fmt;
106 va_dcl
107 {
108 va_list x1;
109
110 va_start(x1);
111 doprf(-1, fmt, x1, cp);
112 va_end(x1);
113 }
114
115 /*
116 * printf worker functions
117 */
118 static void
prf(fd,fmt,adx)119 prf(fd, fmt, adx)
120 int fd;
121 char *fmt;
122 va_list adx;
123 {
124 char linebuf[128];
125
126 doprf(fd, fmt, adx, linebuf);
127 }
128
129 static void
doprf(fd,fmt,adx,linebuf)130 doprf(fd, fmt, adx, linebuf)
131 int fd;
132 register char *fmt;
133 register va_list adx;
134 char *linebuf;
135 {
136 register int c; /* Character temporary */
137 register char *lbp; /* Pointer into stack buffer */
138 register char *s; /* %s temporary */
139 int i; /* General integer temporary */
140 int b; /* Conversion base */
141
142 #define PUTCHAR(c) { \
143 if (lbp >= &linebuf[128]) { \
144 _write(fd, linebuf, lbp - &linebuf[0]); \
145 lbp = &linebuf[0]; \
146 } \
147 *lbp++ = (c); \
148 }
149
150 lbp = &linebuf[0];
151 loop:
152 while ((c = *fmt++) != '%') {
153 if (c == '\0') {
154 _write(fd, linebuf, lbp - &linebuf[0]);
155 return;
156 }
157 PUTCHAR(c);
158 }
159 again:
160 c = *fmt++;
161 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
162 switch (c) {
163
164 case 'x': case 'X':
165 b = 16;
166 goto number;
167 case 'd': case 'D':
168 case 'u': /* what a joke */
169 b = 10;
170 goto number;
171 case 'o': case 'O':
172 b = 8;
173 number:
174 lbp = printn(fd, va_arg(adx, u_long), b, &linebuf[0], lbp,
175 &linebuf[128]);
176 break;
177
178 case 'c':
179 b = va_arg(adx, int);
180 for (i = 24; i >= 0; i -= 8)
181 if (c = (b >> i) & 0x7f) {
182 PUTCHAR(c);
183 }
184 break;
185
186 case 's':
187 s = va_arg(adx, char *);
188 while (c = *s++) {
189 PUTCHAR(c);
190 }
191 break;
192
193 case '%':
194 PUTCHAR('%');
195 break;
196 }
197 goto loop;
198 }
199
200 /*
201 * Printn prints a number n in base b.
202 */
203 static char *
printn(fd,n,b,linebufp,lbp,linebufend)204 printn(fd, n, b, linebufp, lbp, linebufend)
205 int fd; /* File descriptor to get output */
206 u_long n; /* Number */
207 int b; /* Base */
208 char *linebufp; /* Buffer location */
209 register char *lbp; /* Current offset in buffer */
210 char *linebufend; /* Where buffer ends */
211 {
212 char prbuf[11]; /* Local result accumulator */
213 register char *cp;
214
215 #undef PUTCHAR
216 #define PUTCHAR(c) { \
217 if (lbp >= linebufend) { \
218 _write(fd, linebufp, lbp - linebufp); \
219 lbp = linebufp; \
220 } \
221 *lbp++ = (c); \
222 }
223
224 if (b == 10 && (int)n < 0) {
225 PUTCHAR('-');
226 n = (unsigned)(-(int)n);
227 }
228 cp = prbuf;
229 do {
230 *cp++ = "0123456789abcdef"[n%b];
231 n /= b;
232 } while (n);
233 do {
234 PUTCHAR(*--cp);
235 } while (cp > prbuf);
236 return (lbp);
237 }
238
239 static int
_write(fd,buf,len)240 _write(fd, buf, len)
241 int fd;
242 char *buf;
243 int len;
244 {
245
246 if (fd == -1) {
247 *(buf + len) = '\0';
248 return (0);
249 }
250 return (write(fd, buf, len));
251 }
252