1*9b50d902SRodney W. Grimes /* 2*9b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 3*9b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 4*9b50d902SRodney W. Grimes * 5*9b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 6*9b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 7*9b50d902SRodney W. Grimes * are met: 8*9b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 9*9b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 10*9b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 11*9b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 12*9b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 13*9b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 14*9b50d902SRodney W. Grimes * must display the following acknowledgement: 15*9b50d902SRodney W. Grimes * This product includes software developed by the University of 16*9b50d902SRodney W. Grimes * California, Berkeley and its contributors. 17*9b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 18*9b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 19*9b50d902SRodney W. Grimes * without specific prior written permission. 20*9b50d902SRodney W. Grimes * 21*9b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22*9b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23*9b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24*9b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25*9b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26*9b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27*9b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28*9b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29*9b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30*9b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*9b50d902SRodney W. Grimes * SUCH DAMAGE. 32*9b50d902SRodney W. Grimes */ 33*9b50d902SRodney W. Grimes 34*9b50d902SRodney W. Grimes #if !defined(BUILTIN) && !defined(SHELL) 35*9b50d902SRodney W. Grimes #ifndef lint 36*9b50d902SRodney W. Grimes static char copyright[] = 37*9b50d902SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 38*9b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 39*9b50d902SRodney W. Grimes #endif /* not lint */ 40*9b50d902SRodney W. Grimes #endif 41*9b50d902SRodney W. Grimes 42*9b50d902SRodney W. Grimes #ifndef lint 43*9b50d902SRodney W. Grimes static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93"; 44*9b50d902SRodney W. Grimes #endif /* not lint */ 45*9b50d902SRodney W. Grimes 46*9b50d902SRodney W. Grimes #include <sys/types.h> 47*9b50d902SRodney W. Grimes 48*9b50d902SRodney W. Grimes #include <err.h> 49*9b50d902SRodney W. Grimes #include <errno.h> 50*9b50d902SRodney W. Grimes #include <limits.h> 51*9b50d902SRodney W. Grimes #ifdef SHELL 52*9b50d902SRodney W. Grimes #define EOF -1 53*9b50d902SRodney W. Grimes #else 54*9b50d902SRodney W. Grimes #include <stdio.h> 55*9b50d902SRodney W. Grimes #endif 56*9b50d902SRodney W. Grimes #include <stdlib.h> 57*9b50d902SRodney W. Grimes #include <string.h> 58*9b50d902SRodney W. Grimes 59*9b50d902SRodney W. Grimes /* 60*9b50d902SRodney W. Grimes * XXX 61*9b50d902SRodney W. Grimes * This *has* to go away. TK. 62*9b50d902SRodney W. Grimes */ 63*9b50d902SRodney W. Grimes #ifdef SHELL 64*9b50d902SRodney W. Grimes #define main printfcmd 65*9b50d902SRodney W. Grimes #define warnx(a, b, c) { \ 66*9b50d902SRodney W. Grimes char buf[64]; \ 67*9b50d902SRodney W. Grimes (void)sprintf(buf, sizeof(buf), a, b, c); \ 68*9b50d902SRodney W. Grimes error(buf); \ 69*9b50d902SRodney W. Grimes } 70*9b50d902SRodney W. Grimes #include "../../bin/sh/bltin/bltin.h" 71*9b50d902SRodney W. Grimes #endif 72*9b50d902SRodney W. Grimes 73*9b50d902SRodney W. Grimes #define PF(f, func) { \ 74*9b50d902SRodney W. Grimes if (fieldwidth) \ 75*9b50d902SRodney W. Grimes if (precision) \ 76*9b50d902SRodney W. Grimes (void)printf(f, fieldwidth, precision, func); \ 77*9b50d902SRodney W. Grimes else \ 78*9b50d902SRodney W. Grimes (void)printf(f, fieldwidth, func); \ 79*9b50d902SRodney W. Grimes else if (precision) \ 80*9b50d902SRodney W. Grimes (void)printf(f, precision, func); \ 81*9b50d902SRodney W. Grimes else \ 82*9b50d902SRodney W. Grimes (void)printf(f, func); \ 83*9b50d902SRodney W. Grimes } 84*9b50d902SRodney W. Grimes 85*9b50d902SRodney W. Grimes static int asciicode __P((void)); 86*9b50d902SRodney W. Grimes static void escape __P((char *)); 87*9b50d902SRodney W. Grimes static int getchr __P((void)); 88*9b50d902SRodney W. Grimes static double getdouble __P((void)); 89*9b50d902SRodney W. Grimes static int getint __P((int *)); 90*9b50d902SRodney W. Grimes static int getlong __P((long *)); 91*9b50d902SRodney W. Grimes static char *getstr __P((void)); 92*9b50d902SRodney W. Grimes static char *mklong __P((char *, int)); 93*9b50d902SRodney W. Grimes static void usage __P((void)); 94*9b50d902SRodney W. Grimes 95*9b50d902SRodney W. Grimes static char **gargv; 96*9b50d902SRodney W. Grimes 97*9b50d902SRodney W. Grimes int 98*9b50d902SRodney W. Grimes #ifdef BUILTIN 99*9b50d902SRodney W. Grimes progprintf(argc, argv) 100*9b50d902SRodney W. Grimes #else 101*9b50d902SRodney W. Grimes main(argc, argv) 102*9b50d902SRodney W. Grimes #endif 103*9b50d902SRodney W. Grimes int argc; 104*9b50d902SRodney W. Grimes char *argv[]; 105*9b50d902SRodney W. Grimes { 106*9b50d902SRodney W. Grimes extern int optind; 107*9b50d902SRodney W. Grimes static char *skip1, *skip2; 108*9b50d902SRodney W. Grimes int ch, end, fieldwidth, precision; 109*9b50d902SRodney W. Grimes char convch, nextch, *format, *fmt, *start; 110*9b50d902SRodney W. Grimes 111*9b50d902SRodney W. Grimes while ((ch = getopt(argc, argv, "")) != EOF) 112*9b50d902SRodney W. Grimes switch (ch) { 113*9b50d902SRodney W. Grimes case '?': 114*9b50d902SRodney W. Grimes default: 115*9b50d902SRodney W. Grimes usage(); 116*9b50d902SRodney W. Grimes return (1); 117*9b50d902SRodney W. Grimes } 118*9b50d902SRodney W. Grimes argc -= optind; 119*9b50d902SRodney W. Grimes argv += optind; 120*9b50d902SRodney W. Grimes 121*9b50d902SRodney W. Grimes if (argc < 1) { 122*9b50d902SRodney W. Grimes usage(); 123*9b50d902SRodney W. Grimes return (1); 124*9b50d902SRodney W. Grimes } 125*9b50d902SRodney W. Grimes 126*9b50d902SRodney W. Grimes /* 127*9b50d902SRodney W. Grimes * Basic algorithm is to scan the format string for conversion 128*9b50d902SRodney W. Grimes * specifications -- once one is found, find out if the field 129*9b50d902SRodney W. Grimes * width or precision is a '*'; if it is, gather up value. Note, 130*9b50d902SRodney W. Grimes * format strings are reused as necessary to use up the provided 131*9b50d902SRodney W. Grimes * arguments, arguments of zero/null string are provided to use 132*9b50d902SRodney W. Grimes * up the format string. 133*9b50d902SRodney W. Grimes */ 134*9b50d902SRodney W. Grimes skip1 = "#-+ 0"; 135*9b50d902SRodney W. Grimes skip2 = "*0123456789"; 136*9b50d902SRodney W. Grimes 137*9b50d902SRodney W. Grimes escape(fmt = format = *argv); /* backslash interpretation */ 138*9b50d902SRodney W. Grimes gargv = ++argv; 139*9b50d902SRodney W. Grimes for (;;) { 140*9b50d902SRodney W. Grimes end = 0; 141*9b50d902SRodney W. Grimes /* find next format specification */ 142*9b50d902SRodney W. Grimes next: for (start = fmt;; ++fmt) { 143*9b50d902SRodney W. Grimes if (!*fmt) { 144*9b50d902SRodney W. Grimes /* avoid infinite loop */ 145*9b50d902SRodney W. Grimes if (end == 1) { 146*9b50d902SRodney W. Grimes warnx("missing format character", 147*9b50d902SRodney W. Grimes NULL, NULL); 148*9b50d902SRodney W. Grimes return (1); 149*9b50d902SRodney W. Grimes } 150*9b50d902SRodney W. Grimes end = 1; 151*9b50d902SRodney W. Grimes if (fmt > start) 152*9b50d902SRodney W. Grimes (void)printf("%s", start); 153*9b50d902SRodney W. Grimes if (!*gargv) 154*9b50d902SRodney W. Grimes return (0); 155*9b50d902SRodney W. Grimes fmt = format; 156*9b50d902SRodney W. Grimes goto next; 157*9b50d902SRodney W. Grimes } 158*9b50d902SRodney W. Grimes /* %% prints a % */ 159*9b50d902SRodney W. Grimes if (*fmt == '%') { 160*9b50d902SRodney W. Grimes if (*++fmt != '%') 161*9b50d902SRodney W. Grimes break; 162*9b50d902SRodney W. Grimes *fmt++ = '\0'; 163*9b50d902SRodney W. Grimes (void)printf("%s", start); 164*9b50d902SRodney W. Grimes goto next; 165*9b50d902SRodney W. Grimes } 166*9b50d902SRodney W. Grimes } 167*9b50d902SRodney W. Grimes 168*9b50d902SRodney W. Grimes /* skip to field width */ 169*9b50d902SRodney W. Grimes for (; strchr(skip1, *fmt); ++fmt); 170*9b50d902SRodney W. Grimes if (*fmt == '*') { 171*9b50d902SRodney W. Grimes if (getint(&fieldwidth)) 172*9b50d902SRodney W. Grimes return (1); 173*9b50d902SRodney W. Grimes } else 174*9b50d902SRodney W. Grimes fieldwidth = 0; 175*9b50d902SRodney W. Grimes 176*9b50d902SRodney W. Grimes /* skip to possible '.', get following precision */ 177*9b50d902SRodney W. Grimes for (; strchr(skip2, *fmt); ++fmt); 178*9b50d902SRodney W. Grimes if (*fmt == '.') 179*9b50d902SRodney W. Grimes ++fmt; 180*9b50d902SRodney W. Grimes if (*fmt == '*') { 181*9b50d902SRodney W. Grimes if (getint(&precision)) 182*9b50d902SRodney W. Grimes return (1); 183*9b50d902SRodney W. Grimes } else 184*9b50d902SRodney W. Grimes precision = 0; 185*9b50d902SRodney W. Grimes 186*9b50d902SRodney W. Grimes /* skip to conversion char */ 187*9b50d902SRodney W. Grimes for (; strchr(skip2, *fmt); ++fmt); 188*9b50d902SRodney W. Grimes if (!*fmt) { 189*9b50d902SRodney W. Grimes warnx("missing format character", NULL, NULL); 190*9b50d902SRodney W. Grimes return (1); 191*9b50d902SRodney W. Grimes } 192*9b50d902SRodney W. Grimes 193*9b50d902SRodney W. Grimes convch = *fmt; 194*9b50d902SRodney W. Grimes nextch = *++fmt; 195*9b50d902SRodney W. Grimes *fmt = '\0'; 196*9b50d902SRodney W. Grimes switch(convch) { 197*9b50d902SRodney W. Grimes case 'c': { 198*9b50d902SRodney W. Grimes char p; 199*9b50d902SRodney W. Grimes 200*9b50d902SRodney W. Grimes p = getchr(); 201*9b50d902SRodney W. Grimes PF(start, p); 202*9b50d902SRodney W. Grimes break; 203*9b50d902SRodney W. Grimes } 204*9b50d902SRodney W. Grimes case 's': { 205*9b50d902SRodney W. Grimes char *p; 206*9b50d902SRodney W. Grimes 207*9b50d902SRodney W. Grimes p = getstr(); 208*9b50d902SRodney W. Grimes PF(start, p); 209*9b50d902SRodney W. Grimes break; 210*9b50d902SRodney W. Grimes } 211*9b50d902SRodney W. Grimes case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { 212*9b50d902SRodney W. Grimes long p; 213*9b50d902SRodney W. Grimes char *f; 214*9b50d902SRodney W. Grimes 215*9b50d902SRodney W. Grimes if ((f = mklong(start, convch)) == NULL) 216*9b50d902SRodney W. Grimes return (1); 217*9b50d902SRodney W. Grimes if (getlong(&p)) 218*9b50d902SRodney W. Grimes return (1); 219*9b50d902SRodney W. Grimes PF(f, p); 220*9b50d902SRodney W. Grimes break; 221*9b50d902SRodney W. Grimes } 222*9b50d902SRodney W. Grimes case 'e': case 'E': case 'f': case 'g': case 'G': { 223*9b50d902SRodney W. Grimes double p; 224*9b50d902SRodney W. Grimes 225*9b50d902SRodney W. Grimes p = getdouble(); 226*9b50d902SRodney W. Grimes PF(start, p); 227*9b50d902SRodney W. Grimes break; 228*9b50d902SRodney W. Grimes } 229*9b50d902SRodney W. Grimes default: 230*9b50d902SRodney W. Grimes warnx("illegal format character", NULL, NULL); 231*9b50d902SRodney W. Grimes return (1); 232*9b50d902SRodney W. Grimes } 233*9b50d902SRodney W. Grimes *fmt = nextch; 234*9b50d902SRodney W. Grimes } 235*9b50d902SRodney W. Grimes /* NOTREACHED */ 236*9b50d902SRodney W. Grimes } 237*9b50d902SRodney W. Grimes 238*9b50d902SRodney W. Grimes static char * 239*9b50d902SRodney W. Grimes mklong(str, ch) 240*9b50d902SRodney W. Grimes char *str; 241*9b50d902SRodney W. Grimes int ch; 242*9b50d902SRodney W. Grimes { 243*9b50d902SRodney W. Grimes static char copy[64]; 244*9b50d902SRodney W. Grimes int len; 245*9b50d902SRodney W. Grimes 246*9b50d902SRodney W. Grimes len = strlen(str) + 2; 247*9b50d902SRodney W. Grimes memmove(copy, str, len - 3); 248*9b50d902SRodney W. Grimes copy[len - 3] = 'l'; 249*9b50d902SRodney W. Grimes copy[len - 2] = ch; 250*9b50d902SRodney W. Grimes copy[len - 1] = '\0'; 251*9b50d902SRodney W. Grimes return (copy); 252*9b50d902SRodney W. Grimes } 253*9b50d902SRodney W. Grimes 254*9b50d902SRodney W. Grimes static void 255*9b50d902SRodney W. Grimes escape(fmt) 256*9b50d902SRodney W. Grimes register char *fmt; 257*9b50d902SRodney W. Grimes { 258*9b50d902SRodney W. Grimes register char *store; 259*9b50d902SRodney W. Grimes register int value, c; 260*9b50d902SRodney W. Grimes 261*9b50d902SRodney W. Grimes for (store = fmt; c = *fmt; ++fmt, ++store) { 262*9b50d902SRodney W. Grimes if (c != '\\') { 263*9b50d902SRodney W. Grimes *store = c; 264*9b50d902SRodney W. Grimes continue; 265*9b50d902SRodney W. Grimes } 266*9b50d902SRodney W. Grimes switch (*++fmt) { 267*9b50d902SRodney W. Grimes case '\0': /* EOS, user error */ 268*9b50d902SRodney W. Grimes *store = '\\'; 269*9b50d902SRodney W. Grimes *++store = '\0'; 270*9b50d902SRodney W. Grimes return; 271*9b50d902SRodney W. Grimes case '\\': /* backslash */ 272*9b50d902SRodney W. Grimes case '\'': /* single quote */ 273*9b50d902SRodney W. Grimes *store = *fmt; 274*9b50d902SRodney W. Grimes break; 275*9b50d902SRodney W. Grimes case 'a': /* bell/alert */ 276*9b50d902SRodney W. Grimes *store = '\7'; 277*9b50d902SRodney W. Grimes break; 278*9b50d902SRodney W. Grimes case 'b': /* backspace */ 279*9b50d902SRodney W. Grimes *store = '\b'; 280*9b50d902SRodney W. Grimes break; 281*9b50d902SRodney W. Grimes case 'f': /* form-feed */ 282*9b50d902SRodney W. Grimes *store = '\f'; 283*9b50d902SRodney W. Grimes break; 284*9b50d902SRodney W. Grimes case 'n': /* newline */ 285*9b50d902SRodney W. Grimes *store = '\n'; 286*9b50d902SRodney W. Grimes break; 287*9b50d902SRodney W. Grimes case 'r': /* carriage-return */ 288*9b50d902SRodney W. Grimes *store = '\r'; 289*9b50d902SRodney W. Grimes break; 290*9b50d902SRodney W. Grimes case 't': /* horizontal tab */ 291*9b50d902SRodney W. Grimes *store = '\t'; 292*9b50d902SRodney W. Grimes break; 293*9b50d902SRodney W. Grimes case 'v': /* vertical tab */ 294*9b50d902SRodney W. Grimes *store = '\13'; 295*9b50d902SRodney W. Grimes break; 296*9b50d902SRodney W. Grimes /* octal constant */ 297*9b50d902SRodney W. Grimes case '0': case '1': case '2': case '3': 298*9b50d902SRodney W. Grimes case '4': case '5': case '6': case '7': 299*9b50d902SRodney W. Grimes for (c = 3, value = 0; 300*9b50d902SRodney W. Grimes c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) { 301*9b50d902SRodney W. Grimes value <<= 3; 302*9b50d902SRodney W. Grimes value += *fmt - '0'; 303*9b50d902SRodney W. Grimes } 304*9b50d902SRodney W. Grimes --fmt; 305*9b50d902SRodney W. Grimes *store = value; 306*9b50d902SRodney W. Grimes break; 307*9b50d902SRodney W. Grimes default: 308*9b50d902SRodney W. Grimes *store = *fmt; 309*9b50d902SRodney W. Grimes break; 310*9b50d902SRodney W. Grimes } 311*9b50d902SRodney W. Grimes } 312*9b50d902SRodney W. Grimes *store = '\0'; 313*9b50d902SRodney W. Grimes } 314*9b50d902SRodney W. Grimes 315*9b50d902SRodney W. Grimes static int 316*9b50d902SRodney W. Grimes getchr() 317*9b50d902SRodney W. Grimes { 318*9b50d902SRodney W. Grimes if (!*gargv) 319*9b50d902SRodney W. Grimes return ('\0'); 320*9b50d902SRodney W. Grimes return ((int)**gargv++); 321*9b50d902SRodney W. Grimes } 322*9b50d902SRodney W. Grimes 323*9b50d902SRodney W. Grimes static char * 324*9b50d902SRodney W. Grimes getstr() 325*9b50d902SRodney W. Grimes { 326*9b50d902SRodney W. Grimes if (!*gargv) 327*9b50d902SRodney W. Grimes return (""); 328*9b50d902SRodney W. Grimes return (*gargv++); 329*9b50d902SRodney W. Grimes } 330*9b50d902SRodney W. Grimes 331*9b50d902SRodney W. Grimes static char *Number = "+-.0123456789"; 332*9b50d902SRodney W. Grimes static int 333*9b50d902SRodney W. Grimes getint(ip) 334*9b50d902SRodney W. Grimes int *ip; 335*9b50d902SRodney W. Grimes { 336*9b50d902SRodney W. Grimes long val; 337*9b50d902SRodney W. Grimes 338*9b50d902SRodney W. Grimes if (getlong(&val)) 339*9b50d902SRodney W. Grimes return (1); 340*9b50d902SRodney W. Grimes if (val > INT_MAX) { 341*9b50d902SRodney W. Grimes warnx("%s: %s", *gargv, strerror(ERANGE)); 342*9b50d902SRodney W. Grimes return (1); 343*9b50d902SRodney W. Grimes } 344*9b50d902SRodney W. Grimes *ip = val; 345*9b50d902SRodney W. Grimes return (0); 346*9b50d902SRodney W. Grimes } 347*9b50d902SRodney W. Grimes 348*9b50d902SRodney W. Grimes static int 349*9b50d902SRodney W. Grimes getlong(lp) 350*9b50d902SRodney W. Grimes long *lp; 351*9b50d902SRodney W. Grimes { 352*9b50d902SRodney W. Grimes long val; 353*9b50d902SRodney W. Grimes char *ep; 354*9b50d902SRodney W. Grimes 355*9b50d902SRodney W. Grimes if (!*gargv) { 356*9b50d902SRodney W. Grimes *lp = 0; 357*9b50d902SRodney W. Grimes return (0); 358*9b50d902SRodney W. Grimes } 359*9b50d902SRodney W. Grimes if (strchr(Number, **gargv)) { 360*9b50d902SRodney W. Grimes errno = 0; 361*9b50d902SRodney W. Grimes val = strtol(*gargv, &ep, 0); 362*9b50d902SRodney W. Grimes if (*ep != '\0') { 363*9b50d902SRodney W. Grimes warnx("%s: illegal number", *gargv, NULL); 364*9b50d902SRodney W. Grimes return (1); 365*9b50d902SRodney W. Grimes } 366*9b50d902SRodney W. Grimes if (errno == ERANGE) 367*9b50d902SRodney W. Grimes if (val == LONG_MAX) { 368*9b50d902SRodney W. Grimes warnx("%s: %s", *gargv, strerror(ERANGE)); 369*9b50d902SRodney W. Grimes return (1); 370*9b50d902SRodney W. Grimes } 371*9b50d902SRodney W. Grimes if (val == LONG_MIN) { 372*9b50d902SRodney W. Grimes warnx("%s: %s", *gargv, strerror(ERANGE)); 373*9b50d902SRodney W. Grimes return (1); 374*9b50d902SRodney W. Grimes } 375*9b50d902SRodney W. Grimes 376*9b50d902SRodney W. Grimes *lp = val; 377*9b50d902SRodney W. Grimes ++gargv; 378*9b50d902SRodney W. Grimes return (0); 379*9b50d902SRodney W. Grimes } 380*9b50d902SRodney W. Grimes *lp = (long)asciicode(); 381*9b50d902SRodney W. Grimes return (0); 382*9b50d902SRodney W. Grimes } 383*9b50d902SRodney W. Grimes 384*9b50d902SRodney W. Grimes static double 385*9b50d902SRodney W. Grimes getdouble() 386*9b50d902SRodney W. Grimes { 387*9b50d902SRodney W. Grimes if (!*gargv) 388*9b50d902SRodney W. Grimes return ((double)0); 389*9b50d902SRodney W. Grimes if (strchr(Number, **gargv)) 390*9b50d902SRodney W. Grimes return (atof(*gargv++)); 391*9b50d902SRodney W. Grimes return ((double)asciicode()); 392*9b50d902SRodney W. Grimes } 393*9b50d902SRodney W. Grimes 394*9b50d902SRodney W. Grimes static int 395*9b50d902SRodney W. Grimes asciicode() 396*9b50d902SRodney W. Grimes { 397*9b50d902SRodney W. Grimes register int ch; 398*9b50d902SRodney W. Grimes 399*9b50d902SRodney W. Grimes ch = **gargv; 400*9b50d902SRodney W. Grimes if (ch == '\'' || ch == '"') 401*9b50d902SRodney W. Grimes ch = (*gargv)[1]; 402*9b50d902SRodney W. Grimes ++gargv; 403*9b50d902SRodney W. Grimes return (ch); 404*9b50d902SRodney W. Grimes } 405*9b50d902SRodney W. Grimes 406*9b50d902SRodney W. Grimes static void 407*9b50d902SRodney W. Grimes usage() 408*9b50d902SRodney W. Grimes { 409*9b50d902SRodney W. Grimes (void)fprintf(stderr, "usage: printf format [arg ...]\n"); 410*9b50d902SRodney W. Grimes } 411