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*/ 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*/ 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*/ 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*/ 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 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 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 * 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 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