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 */
40int	stdout = 1;			/* File descriptor for output */
41int	stderr = 2;			/* File descriptor for errors */
42
43static char *printn();
44static void prf();
45static void doprf();
46static int _write();
47
48/*
49 * printf
50 */
51/*VARARGS1*/
52printf(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*/
67fprintf(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*/
83panic(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*/
103sprintf(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 */
118static void
119prf(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
129static void
130doprf(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];
151loop:
152	while ((c = *fmt++) != '%') {
153		if (c == '\0') {
154			_write(fd, linebuf, lbp - &linebuf[0]);
155			return;
156		}
157		PUTCHAR(c);
158	}
159again:
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;
173number:
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 */
203static char *
204printn(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
239static int
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