printf.c (92921) | printf.c (95300) |
---|---|
1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 30 unchanged lines hidden (view full) --- 39#endif /* not lint */ 40#endif 41 42#ifndef lint 43#if 0 44static char const sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93"; 45#endif 46static const char rcsid[] = | 1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 30 unchanged lines hidden (view full) --- 39#endif /* not lint */ 40#endif 41 42#ifndef lint 43#if 0 44static char const sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93"; 45#endif 46static const char rcsid[] = |
47 "$FreeBSD: head/usr.bin/printf/printf.c 92921 2002-03-22 01:33:25Z imp $"; | 47 "$FreeBSD: head/usr.bin/printf/printf.c 95300 2002-04-23 02:56:16Z jmallett $"; |
48#endif /* not lint */ 49 50#include <sys/types.h> 51 52#include <err.h> 53#include <errno.h> 54#include <limits.h> 55#include <stdio.h> --- 28 unchanged lines hidden (view full) --- 84 (void)asprintf(&b, f, func); \ 85 if (b) { \ 86 (void)fputs(b, stdout); \ 87 free(b); \ 88 } \ 89} 90 91static int asciicode(void); | 48#endif /* not lint */ 49 50#include <sys/types.h> 51 52#include <err.h> 53#include <errno.h> 54#include <limits.h> 55#include <stdio.h> --- 28 unchanged lines hidden (view full) --- 84 (void)asprintf(&b, f, func); \ 85 if (b) { \ 86 (void)fputs(b, stdout); \ 87 free(b); \ 88 } \ 89} 90 91static int asciicode(void); |
92static void escape(char *); | 92static int escape(char *); |
93static int getchr(void); 94static double getdouble(void); 95static int getint(int *); 96static int getquad(quad_t *); 97static const char *getstr(void); 98static char *mklong(char *, int); 99static void usage(void); 100 --- 4 unchanged lines hidden (view full) --- 105progprintf(argc, argv) 106#else 107main(argc, argv) 108#endif 109 int argc; 110 char *argv[]; 111{ 112 static const char *skip1, *skip2; | 93static int getchr(void); 94static double getdouble(void); 95static int getint(int *); 96static int getquad(quad_t *); 97static const char *getstr(void); 98static char *mklong(char *, int); 99static void usage(void); 100 --- 4 unchanged lines hidden (view full) --- 105progprintf(argc, argv) 106#else 107main(argc, argv) 108#endif 109 int argc; 110 char *argv[]; 111{ 112 static const char *skip1, *skip2; |
113 int ch, end, fieldwidth, precision; | 113 int ch, chopped, end, fieldwidth, precision; |
114 char convch, nextch, *format, *fmt, *start; 115 116#ifndef BUILTIN 117 (void) setlocale(LC_NUMERIC, ""); 118#endif 119 while ((ch = getopt(argc, argv, "")) != -1) 120 switch (ch) { 121 case '?': --- 15 unchanged lines hidden (view full) --- 137 * width or precision is a '*'; if it is, gather up value. Note, 138 * format strings are reused as necessary to use up the provided 139 * arguments, arguments of zero/null string are provided to use 140 * up the format string. 141 */ 142 skip1 = "#-+ 0"; 143 skip2 = "0123456789"; 144 | 114 char convch, nextch, *format, *fmt, *start; 115 116#ifndef BUILTIN 117 (void) setlocale(LC_NUMERIC, ""); 118#endif 119 while ((ch = getopt(argc, argv, "")) != -1) 120 switch (ch) { 121 case '?': --- 15 unchanged lines hidden (view full) --- 137 * width or precision is a '*'; if it is, gather up value. Note, 138 * format strings are reused as necessary to use up the provided 139 * arguments, arguments of zero/null string are provided to use 140 * up the format string. 141 */ 142 skip1 = "#-+ 0"; 143 skip2 = "0123456789"; 144 |
145 escape(fmt = format = *argv); /* backslash interpretation */ | 145 chopped = escape(fmt = format = *argv); /* backslash interpretation */ |
146 gargv = ++argv; 147 for (;;) { 148 end = 0; 149 /* find next format specification */ 150next: for (start = fmt;; ++fmt) { 151 if (!*fmt) { 152 /* avoid infinite loop */ | 146 gargv = ++argv; 147 for (;;) { 148 end = 0; 149 /* find next format specification */ 150next: for (start = fmt;; ++fmt) { 151 if (!*fmt) { 152 /* avoid infinite loop */ |
153 if (chopped) { 154 (void)printf("%s", start); 155 return (0); 156 } |
|
153 if (end == 1) { 154 warnx1("missing format character", 155 NULL, NULL); 156 return (1); 157 } 158 end = 1; 159 if (fmt > start) 160 (void)printf("%s", start); --- 43 unchanged lines hidden (view full) --- 204 warnx1("missing format character", NULL, NULL); 205 return (1); 206 } 207 208 convch = *fmt; 209 nextch = *++fmt; 210 *fmt = '\0'; 211 switch(convch) { | 157 if (end == 1) { 158 warnx1("missing format character", 159 NULL, NULL); 160 return (1); 161 } 162 end = 1; 163 if (fmt > start) 164 (void)printf("%s", start); --- 43 unchanged lines hidden (view full) --- 208 warnx1("missing format character", NULL, NULL); 209 return (1); 210 } 211 212 convch = *fmt; 213 nextch = *++fmt; 214 *fmt = '\0'; 215 switch(convch) { |
216 case 'b': { 217 char *p; 218 int getout; 219 220 if ((p = strdup(getstr())) == NULL) 221 err(1, NULL); 222 getout = escape(p); 223 *(fmt - 1) = 's'; 224 PF(start, p) 225 *(fmt - 1) = 'b'; 226 free(p); 227 if (getout) 228 return (0); 229 break; 230 } |
|
212 case 'c': { 213 char p; 214 215 p = getchr(); 216 PF(start, p); 217 break; 218 } 219 case 's': { 220 const char *p; 221 222 p = getstr(); 223 PF(start, p); 224 break; 225 } 226 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { 227 quad_t p; 228 char *f; 229 | 231 case 'c': { 232 char p; 233 234 p = getchr(); 235 PF(start, p); 236 break; 237 } 238 case 's': { 239 const char *p; 240 241 p = getstr(); 242 PF(start, p); 243 break; 244 } 245 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { 246 quad_t p; 247 char *f; 248 |
230 if ((f = mklong(start, convch)) == NULL) 231 return (1); 232 if (getquad(&p)) 233 return (1); 234 PF(f, p); | 249 if ((f = mklong(start, convch)) != NULL && 250 !getquad(&p)) { 251 PF(f, p); 252 } |
235 break; 236 } 237 case 'e': case 'E': case 'f': case 'g': case 'G': { 238 double p; 239 240 p = getdouble(); 241 PF(start, p); 242 break; --- 32 unchanged lines hidden (view full) --- 275 276 memmove(copy, str, len - 3); 277 copy[len - 3] = 'q'; 278 copy[len - 2] = ch; 279 copy[len - 1] = '\0'; 280 return (copy); 281} 282 | 253 break; 254 } 255 case 'e': case 'E': case 'f': case 'g': case 'G': { 256 double p; 257 258 p = getdouble(); 259 PF(start, p); 260 break; --- 32 unchanged lines hidden (view full) --- 293 294 memmove(copy, str, len - 3); 295 copy[len - 3] = 'q'; 296 copy[len - 2] = ch; 297 copy[len - 1] = '\0'; 298 return (copy); 299} 300 |
283static void | 301static int |
284escape(fmt) 285 register char *fmt; 286{ 287 register char *store; 288 register int value, c; 289 290 for (store = fmt; (c = *fmt); ++fmt, ++store) { 291 if (c != '\\') { 292 *store = c; 293 continue; 294 } 295 switch (*++fmt) { 296 case '\0': /* EOS, user error */ 297 *store = '\\'; 298 *++store = '\0'; | 302escape(fmt) 303 register char *fmt; 304{ 305 register char *store; 306 register int value, c; 307 308 for (store = fmt; (c = *fmt); ++fmt, ++store) { 309 if (c != '\\') { 310 *store = c; 311 continue; 312 } 313 switch (*++fmt) { 314 case '\0': /* EOS, user error */ 315 *store = '\\'; 316 *++store = '\0'; |
299 return; | 317 return (0); |
300 case '\\': /* backslash */ 301 case '\'': /* single quote */ 302 *store = *fmt; 303 break; 304 case 'a': /* bell/alert */ 305 *store = '\7'; 306 break; 307 case 'b': /* backspace */ 308 *store = '\b'; 309 break; | 318 case '\\': /* backslash */ 319 case '\'': /* single quote */ 320 *store = *fmt; 321 break; 322 case 'a': /* bell/alert */ 323 *store = '\7'; 324 break; 325 case 'b': /* backspace */ 326 *store = '\b'; 327 break; |
328 case 'c': 329 *store = '\0'; 330 return (1); |
|
310 case 'f': /* form-feed */ 311 *store = '\f'; 312 break; 313 case 'n': /* newline */ 314 *store = '\n'; 315 break; 316 case 'r': /* carriage-return */ 317 *store = '\r'; 318 break; 319 case 't': /* horizontal tab */ 320 *store = '\t'; 321 break; 322 case 'v': /* vertical tab */ 323 *store = '\13'; 324 break; 325 /* octal constant */ 326 case '0': case '1': case '2': case '3': 327 case '4': case '5': case '6': case '7': | 331 case 'f': /* form-feed */ 332 *store = '\f'; 333 break; 334 case 'n': /* newline */ 335 *store = '\n'; 336 break; 337 case 'r': /* carriage-return */ 338 *store = '\r'; 339 break; 340 case 't': /* horizontal tab */ 341 *store = '\t'; 342 break; 343 case 'v': /* vertical tab */ 344 *store = '\13'; 345 break; 346 /* octal constant */ 347 case '0': case '1': case '2': case '3': 348 case '4': case '5': case '6': case '7': |
328 for (c = 3, value = 0; | 349 for (c = *fmt == '0' ? 4 : 3, value = 0; |
329 c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) { 330 value <<= 3; 331 value += *fmt - '0'; 332 } 333 --fmt; 334 *store = value; 335 break; 336 default: 337 *store = *fmt; 338 break; 339 } 340 } 341 *store = '\0'; | 350 c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) { 351 value <<= 3; 352 value += *fmt - '0'; 353 } 354 --fmt; 355 *store = value; 356 break; 357 default: 358 *store = *fmt; 359 break; 360 } 361 } 362 *store = '\0'; |
363 return (0); |
|
342} 343 344static int 345getchr() 346{ 347 if (!*gargv) 348 return ('\0'); 349 return ((int)**gargv++); 350} 351 352static const char * 353getstr() 354{ 355 if (!*gargv) 356 return (""); 357 return (*gargv++); 358} 359 | 364} 365 366static int 367getchr() 368{ 369 if (!*gargv) 370 return ('\0'); 371 return ((int)**gargv++); 372} 373 374static const char * 375getstr() 376{ 377 if (!*gargv) 378 return (""); 379 return (*gargv++); 380} 381 |
360static const char *Number = "+-.0123456789"; | |
361static int 362getint(ip) 363 int *ip; 364{ 365 quad_t val; 366 367 if (getquad(&val)) 368 return (1); | 382static int 383getint(ip) 384 int *ip; 385{ 386 quad_t val; 387 388 if (getquad(&val)) 389 return (1); |
369 if (val < INT_MIN || val > INT_MAX) { | 390 if (val < INT_MIN || val > INT_MAX) |
370 warnx3("%s: %s", *gargv, strerror(ERANGE)); | 391 warnx3("%s: %s", *gargv, strerror(ERANGE)); |
371 return (1); 372 } | |
373 *ip = (int)val; 374 return (0); 375} 376 377static int 378getquad(lp) 379 quad_t *lp; 380{ 381 quad_t val; 382 char *ep; 383 384 if (!*gargv) { 385 *lp = 0; 386 return (0); 387 } | 392 *ip = (int)val; 393 return (0); 394} 395 396static int 397getquad(lp) 398 quad_t *lp; 399{ 400 quad_t val; 401 char *ep; 402 403 if (!*gargv) { 404 *lp = 0; 405 return (0); 406 } |
388 if (strchr(Number, **gargv)) { 389 errno = 0; 390 val = strtoq(*gargv, &ep, 0); 391 if (*ep != '\0') { 392 warnx2("%s: illegal number", *gargv, NULL); 393 return (1); 394 } 395 if (errno == ERANGE) 396 if (val == QUAD_MAX) { 397 warnx3("%s: %s", *gargv, strerror(ERANGE)); 398 return (1); 399 } 400 if (val == QUAD_MIN) { 401 warnx3("%s: %s", *gargv, strerror(ERANGE)); 402 return (1); 403 } | |
404 | 407 |
405 *lp = val; 406 ++gargv; | 408 if (**gargv == '"' || **gargv == '\'') { 409 *lp = (quad_t)asciicode(); |
407 return (0); 408 } | 410 return (0); 411 } |
409 *lp = (long)asciicode(); | 412 413 errno = 0; 414 val = strtoq(*gargv, &ep, 0); 415 if (ep == *gargv) 416 warnx2("%s: expected numeric value", *gargv, NULL); 417 else if (*ep != '\0') 418 warnx2("%s: not completely converted", *gargv, NULL); 419 if (errno == ERANGE) 420 warnx3("%s: %s", *gargv, strerror(ERANGE)); 421 *lp = val; 422 ++gargv; |
410 return (0); 411} 412 413static double 414getdouble() 415{ | 423 return (0); 424} 425 426static double 427getdouble() 428{ |
429 double val; 430 char *ep; 431 |
|
416 if (!*gargv) 417 return ((double)0); | 432 if (!*gargv) 433 return ((double)0); |
418 if (strchr(Number, **gargv)) 419 return (atof(*gargv++)); 420 return ((double)asciicode()); | 434 435 if (**gargv == '"' || **gargv == '\'') { 436 val = (double)asciicode(); 437 return (val); 438 } 439 440 errno = 0; 441 val = strtod(*gargv, &ep); 442 if (ep == *gargv) 443 warnx2("%s: expected numeric value", *gargv, NULL); 444 else if (*ep != '\0') 445 warnx2("%s: not completely converted", *gargv, NULL); 446 if (errno == ERANGE) 447 warnx3("%s: %s", *gargv, strerror(ERANGE)); 448 ++gargv; 449 return (val); |
421} 422 423static int 424asciicode() 425{ 426 register int ch; 427 428 ch = **gargv; 429 if (ch == '\'' || ch == '"') 430 ch = (*gargv)[1]; 431 ++gargv; 432 return (ch); 433} 434 435static void 436usage() 437{ 438 (void)fprintf(stderr, "usage: printf format [arg ...]\n"); 439} | 450} 451 452static int 453asciicode() 454{ 455 register int ch; 456 457 ch = **gargv; 458 if (ch == '\'' || ch == '"') 459 ch = (*gargv)[1]; 460 ++gargv; 461 return (ch); 462} 463 464static void 465usage() 466{ 467 (void)fprintf(stderr, "usage: printf format [arg ...]\n"); 468} |