Changeset 3192 for trunk/src/kmk/kmkbuiltin/printf.c
- Timestamp:
- Mar 26, 2018, 10:25:56 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/printf.c
r3188 r3192 46 46 #endif*/ /* not lint */ 47 47 48 #if !defined(kmk_builtin_printf) && !defined(BUILTIN) && !defined(SHELL) 48 49 /********************************************************************************************************************************* 50 * Header Files * 51 *********************************************************************************************************************************/ 52 #if !defined(KMK_BUILTIN_STANDALONE) && !defined(BUILTIN) && !defined(SHELL) 49 53 # include "../makeint.h" 50 54 # include "../filedef.h" … … 83 87 #endif 84 88 85 89 #if 0 90 #ifdef BUILTIN /* csh builtin */ 91 #define kmk_builtin_printf progprintf 92 #endif 93 94 #ifdef SHELL /* sh (aka ash) builtin */ 95 #define kmk_builtin_printf printfcmd 96 #include "../../bin/sh/bltin/bltin.h" 97 #endif /* SHELL */ 98 #endif 99 100 101 /********************************************************************************************************************************* 102 * Defined Constants And Macros * 103 *********************************************************************************************************************************/ 86 104 #if 0 /*def __GNUC__ - bird: gcc complains about non-ISO-standard escape. */ 87 105 #define ESCAPE '\e' … … 90 108 #endif 91 109 92 93 static size_t b_length;94 static char *b_fmt;95 static int rval;96 static char **gargv;97 #if !defined(kmk_builtin_printf) && !defined(BUILTIN) && !defined(SHELL)98 static char *g_o = NULL;99 #endif100 static struct option long_options[] =101 {102 { "help", no_argument, 0, 261 },103 { "version", no_argument, 0, 262 },104 { 0, 0, 0, 0 },105 };106 107 108 static int common_printf(int argc, char *argv[]);109 static void conv_escape_str(char *, void (*)(int));110 static char *conv_escape(char *, char *);111 static char *conv_expand(const char *);112 static int getchr(void);113 static double getdouble(void);114 static int getwidth(void);115 static intmax_t getintmax(void);116 static uintmax_t getuintmax(void);117 static char *getstr(void);118 static char *mklong(const char *, int);119 static void check_conversion(const char *, const char *);120 static int usage(FILE *);121 122 static int flush_buffer(void);123 static void b_count(int);124 static void b_output(int);125 static int wrap_putchar(int ch);126 static int wrap_printf(const char *, ...);127 128 #ifdef BUILTIN /* csh builtin */129 #define kmk_builtin_printf progprintf130 #endif131 132 #ifdef SHELL /* sh (aka ash) builtin */133 #define kmk_builtin_printf printfcmd134 #include "../../bin/sh/bltin/bltin.h"135 #endif /* SHELL */136 137 /* Buffer the output because windows doesn't do line buffering of stdout. */138 static char g_achBuf[256];139 static size_t g_cchBuf;140 141 110 #define PF(f, func) { \ 142 111 if (fieldwidth != -1) { \ 143 112 if (precision != -1) \ 144 (void)wrap_printf( f, fieldwidth, precision, func); \113 (void)wrap_printf(pThis, f, fieldwidth, precision, func); \ 145 114 else \ 146 (void)wrap_printf( f, fieldwidth, func); \115 (void)wrap_printf(pThis, f, fieldwidth, func); \ 147 116 } else if (precision != -1) \ 148 (void)wrap_printf( f, precision, func); \117 (void)wrap_printf(pThis, f, precision, func); \ 149 118 else \ 150 (void)wrap_printf( f, func); \119 (void)wrap_printf(pThis, f, func); \ 151 120 } 152 121 … … 163 132 } 164 133 165 int kmk_builtin_printf(int argc, char *argv[], char **envp) 166 { 167 int rc; 134 135 /********************************************************************************************************************************* 136 * Structures and Typedefs * 137 *********************************************************************************************************************************/ 138 typedef struct PRINTFINSTANCE 139 { 140 PKMKBUILTINCTX pCtx; 141 size_t b_length; 142 char *b_fmt; 143 int rval; 144 char **gargv; 145 #ifndef KMK_BUILTIN_STANDALONE 146 char *g_o; 147 #endif 148 /* Buffer the output because windows doesn't do line buffering of stdout. */ 149 size_t g_cchBuf; 150 char g_achBuf[256]; 151 } PRINTFINSTANCE; 152 typedef PRINTFINSTANCE *PPRINTFINSTANCE; 153 154 155 /********************************************************************************************************************************* 156 * Global Variables * 157 *********************************************************************************************************************************/ 158 static struct option long_options[] = 159 { 160 { "help", no_argument, 0, 261 }, 161 { "version", no_argument, 0, 262 }, 162 { 0, 0, 0, 0 }, 163 }; 164 165 166 /********************************************************************************************************************************* 167 * Internal Functions * 168 *********************************************************************************************************************************/ 169 static int common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[]); 170 static void conv_escape_str(PPRINTFINSTANCE, char *, void (*)(PPRINTFINSTANCE, int)); 171 static char *conv_escape(PPRINTFINSTANCE, char *, char *); 172 static char *conv_expand(const char *); 173 static int getchr(PPRINTFINSTANCE); 174 static double getdouble(PPRINTFINSTANCE); 175 static int getwidth(PPRINTFINSTANCE); 176 static intmax_t getintmax(PPRINTFINSTANCE); 177 static uintmax_t getuintmax(PPRINTFINSTANCE); 178 static char *getstr(PPRINTFINSTANCE); 179 static char *mklong(PPRINTFINSTANCE, const char *, int, char[64]); 180 static void check_conversion(PPRINTFINSTANCE, const char *, const char *); 181 static int usage(PKMKBUILTINCTX, int); 182 183 static int flush_buffer(PPRINTFINSTANCE); 184 static void b_count(PPRINTFINSTANCE, int); 185 static void b_output(PPRINTFINSTANCE, int); 186 static int wrap_putchar(PPRINTFINSTANCE, int ch); 187 static int wrap_printf(PPRINTFINSTANCE, const char *, ...); 188 189 190 191 int kmk_builtin_printf(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx) 192 { 168 193 int ch; 194 PRINTFINSTANCE This; 195 This.pCtx = pCtx; 196 This.b_length = 0; 197 This.b_fmt = NULL; 198 This.rval = 0; 199 This.gargv = NULL; 200 #ifndef KMK_BUILTIN_STANDALONE 201 This.g_o = NULL; 202 #endif 203 This.g_cchBuf = 0; 169 204 170 205 /* kmk: reset getopt, set progname and reset buffer. */ 171 g_progname = argv[0];172 206 opterr = 1; 173 207 optarg = NULL; … … 175 209 optind = 0; /* init */ 176 210 177 #if !defined(SHELL) && !defined(BUILTIN) && !defined(kmk_builtin_printf) /* kmk did this already. */178 (void)setlocale (LC_ALL, "");179 #endif180 181 211 while ((ch = getopt_long(argc, argv, "", long_options, NULL)) != -1) { 182 212 switch (ch) { 183 213 case 261: 184 usage( stdout);214 usage(pCtx, 0); 185 215 return 0; 186 216 case 262: … … 188 218 case '?': 189 219 default: 190 return usage( stderr);220 return usage(pCtx, 1); 191 221 } 192 222 } … … 194 224 argv += optind; 195 225 196 if (argc < 1) { 197 return usage(stderr); 198 } 199 200 rc = common_printf(argc, argv); 201 return rc; 202 } 203 204 #ifndef kmk_builtin_printf 226 if (argc < 1) 227 return usage(pCtx, 1); 228 return common_printf(&This, argc, argv); 229 } 230 231 #ifdef KMK_BUILTIN_STANDALONE 232 int main(int argc, char **argv, char **envp) 233 { 234 KMKBUILTINCTX Ctx = { "kmk_printf", NULL }; 235 setlocale(LC_ALL, ""); 236 return kmk_builtin_printf(argc, argv, envp, &Ctx); 237 } 238 #else /* KMK_BUILTIN_STANDALONE */ 205 239 /* entry point used by function.c $(printf ..,..). */ 206 240 char *kmk_builtin_func_printf(char *o, char **argv, const char *funcname) 207 241 { 242 PRINTFINSTANCE This; 208 243 int rc; 209 244 int argc; … … 211 246 for (argc = 0; argv[argc] != NULL; argc++) 212 247 /* nothing */; 213 214 g_o = o; 215 rc = common_printf(argc, argv); 216 o = g_o; 217 g_o = NULL; 248 if (argc == 0) 249 fatal(NILF, strlen(funcname) + INTSTR_LENGTH, _("$(%s): no format string\n"), funcname); 250 251 This.pCtx = NULL; 252 This.b_length = 0; 253 This.b_fmt = NULL; 254 This.rval = 0; 255 This.gargv = NULL; 256 This.g_cchBuf = 0; 257 This.g_o = o; 258 259 rc = common_printf(&This, argc, argv); 260 o = This.g_o; 218 261 219 262 if (rc != 0) … … 221 264 return o; 222 265 } 223 #endif 224 225 static int common_printf( int argc, char *argv[])266 #endif /* KMK_BUILTIN_STANDALONE */ 267 268 static int common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[]) 226 269 { 227 270 char *fmt, *start; … … 230 273 char *format; 231 274 int ch; 275 char longbuf[64]; 232 276 233 277 /* kmk: reinitialize globals */ 234 b_length = 0; 235 b_fmt = NULL; 236 rval = 0; 237 gargv = NULL; 238 g_cchBuf = 0; 239 278 pThis->b_length = 0; 279 pThis->b_fmt = NULL; 280 pThis->rval = 0; 281 pThis->gargv = NULL; 282 pThis->g_cchBuf = 0; 240 283 format = *argv; 241 gargv = ++argv;284 pThis->gargv = ++argv; 242 285 243 286 #define SKIP1 "#-+ 0" … … 257 300 if (ch == '\\') { 258 301 char c_ch; 259 fmt = conv_escape( fmt, &c_ch);260 wrap_putchar( c_ch);302 fmt = conv_escape(pThis, fmt, &c_ch); 303 wrap_putchar(pThis, c_ch); 261 304 continue; 262 305 } 263 306 if (ch != '%' || (*fmt == '%' && ++fmt)) { 264 (void)wrap_putchar( ch);307 (void)wrap_putchar(pThis, ch); 265 308 continue; 266 309 } … … 272 315 /* skip to field width */ 273 316 fmt += strspn(fmt, SKIP1); 274 fieldwidth = *fmt == '*' ? getwidth( ) : -1;317 fieldwidth = *fmt == '*' ? getwidth(pThis) : -1; 275 318 276 319 /* skip to possible '.', get following precision */ … … 278 321 if (*fmt == '.') 279 322 ++fmt; 280 precision = *fmt == '*' ? getwidth( ) : -1;323 precision = *fmt == '*' ? getwidth(pThis) : -1; 281 324 282 325 fmt += strspn(fmt, SKIP2); … … 284 327 ch = *fmt; 285 328 if (!ch) { 286 flush_buffer( );287 warnx( "missing format character");329 flush_buffer(pThis); 330 warnx(pThis->pCtx, "missing format character"); 288 331 return (1); 289 332 } … … 295 338 296 339 case 'B': { 297 const char *p = conv_expand(getstr( ));340 const char *p = conv_expand(getstr(pThis)); 298 341 *fmt = 's'; 299 342 PF(start, p); … … 305 348 * embedded nulls. */ 306 349 static char *a, *t; 307 char *cp = getstr( );350 char *cp = getstr(pThis); 308 351 /* Free on entry in case shell longjumped out */ 309 352 if (a != NULL) … … 314 357 t = NULL; 315 358 /* Count number of bytes we want to output */ 316 b_length = 0;317 conv_escape_str( cp, b_count);318 t = malloc( b_length + 1);359 pThis->b_length = 0; 360 conv_escape_str(pThis, cp, b_count); 361 t = malloc(pThis->b_length + 1); 319 362 if (t == NULL) 320 363 break; 321 memset(t, 'x', b_length);322 t[ b_length] = 0;364 memset(t, 'x', pThis->b_length); 365 t[pThis->b_length] = 0; 323 366 /* Get printf to calculate the lengths */ 324 367 *fmt = 's'; 325 368 APF(&a, start, t); 326 b_fmt = a;369 pThis->b_fmt = a; 327 370 /* Output leading spaces and data bytes */ 328 conv_escape_str( cp, b_output);371 conv_escape_str(pThis, cp, b_output); 329 372 /* Add any trailing spaces */ 330 wrap_printf( "%s",b_fmt);373 wrap_printf(pThis, "%s", pThis->b_fmt); 331 374 break; 332 375 } 333 376 case 'c': { 334 char p = getchr( );377 char p = getchr(pThis); 335 378 PF(start, p); 336 379 break; 337 380 } 338 381 case 's': { 339 char *p = getstr( );382 char *p = getstr(pThis); 340 383 PF(start, p); 341 384 break; … … 343 386 case 'd': 344 387 case 'i': { 345 intmax_t p = getintmax( );346 char *f = mklong( start, ch);388 intmax_t p = getintmax(pThis); 389 char *f = mklong(pThis, start, ch, longbuf); 347 390 PF(f, p); 348 391 break; … … 352 395 case 'x': 353 396 case 'X': { 354 uintmax_t p = getuintmax( );355 char *f = mklong( start, ch);397 uintmax_t p = getuintmax(pThis); 398 char *f = mklong(pThis, start, ch, longbuf); 356 399 PF(f, p); 357 400 break; … … 362 405 case 'g': 363 406 case 'G': { 364 double p = getdouble( );407 double p = getdouble(pThis); 365 408 PF(start, p); 366 409 break; 367 410 } 368 411 default: 369 flush_buffer( );370 warnx( "%s: invalid directive", start);412 flush_buffer(pThis); 413 warnx(pThis->pCtx, "%s: invalid directive", start); 371 414 return 1; 372 415 } … … 374 417 *fmt = nextch; 375 418 /* escape if a \c was encountered */ 376 if ( rval & 0x100) {377 flush_buffer( );378 return rval & ~0x100;379 } 380 } 381 } while ( gargv != argv && *gargv);382 383 flush_buffer( );384 return rval;419 if (pThis->rval & 0x100) { 420 flush_buffer(pThis); 421 return pThis->rval & ~0x100; 422 } 423 } 424 } while (pThis->gargv != argv && *pThis->gargv); 425 426 flush_buffer(pThis); 427 return pThis->rval; 385 428 } 386 429 … … 390 433 static void 391 434 /*ARGSUSED*/ 392 b_count( int ch)393 { 394 b_length++;435 b_count(PPRINTFINSTANCE pThis, int ch) 436 { 437 pThis->b_length++; 395 438 (void)ch; 396 439 } … … 399 442 400 443 static void 401 b_output( int ch)444 b_output(PPRINTFINSTANCE pThis, int ch) 402 445 { 403 446 for (;;) { 404 switch (* b_fmt++) {447 switch (*pThis->b_fmt++) { 405 448 case 0: 406 b_fmt--;449 pThis->b_fmt--; 407 450 return; 408 451 case ' ': 409 wrap_putchar( ' ');452 wrap_putchar(pThis, ' '); 410 453 break; 411 454 default: 412 wrap_putchar( ch);455 wrap_putchar(pThis, ch); 413 456 return; 414 457 } … … 416 459 } 417 460 418 static int wrap_putchar( int ch)419 { 420 #ifndef kmk_builtin_printf421 if ( g_o) {461 static int wrap_putchar(PPRINTFINSTANCE pThis, int ch) 462 { 463 #ifndef KMK_BUILTIN_STANDALONE 464 if (pThis->g_o) { 422 465 char sz[2]; 423 466 sz[0] = ch; sz[1] = '\0'; 424 g_o = variable_buffer_output(g_o, sz, 1);425 return ch;426 }467 pThis->g_o = variable_buffer_output(pThis->g_o, sz, 1); 468 } 469 else 427 470 #endif 428 471 /* Buffered output. */ 429 if ( g_cchBuf + 1 < sizeof(g_achBuf)) {430 g_achBuf[g_cchBuf++] = ch;472 if (pThis->g_cchBuf + 1 < sizeof(pThis->g_achBuf)) { 473 pThis->g_achBuf[pThis->g_cchBuf++] = ch; 431 474 } else { 432 int rc = flush_buffer( );433 g_achBuf[g_cchBuf++] = ch;475 int rc = flush_buffer(pThis); 476 pThis->g_achBuf[pThis->g_cchBuf++] = ch; 434 477 if (rc) 435 478 return -1; … … 438 481 } 439 482 440 static int wrap_printf( const char * fmt, ...)483 static int wrap_printf(PPRINTFINSTANCE pThis, const char * fmt, ...) 441 484 { 442 485 ssize_t cchRet; … … 448 491 va_end(va); 449 492 if (cchRet >= 0) { 450 #ifndef kmk_builtin_printf451 if ( g_o) {452 g_o = variable_buffer_output(g_o, pszTmp, cchRet);493 #ifndef KMK_BUILTIN_STANDALONE 494 if (pThis->g_o) { 495 pThis->g_o = variable_buffer_output(pThis->g_o, pszTmp, cchRet); 453 496 } else 454 497 #endif 455 498 { 456 if (cchRet + g_cchBuf <= sizeof(g_achBuf)) {499 if (cchRet + pThis->g_cchBuf <= sizeof(pThis->g_achBuf)) { 457 500 /* We've got space in the buffer. */ 458 memcpy(& g_achBuf[g_cchBuf], pszTmp, cchRet);459 g_cchBuf += cchRet;501 memcpy(&pThis->g_achBuf[pThis->g_cchBuf], pszTmp, cchRet); 502 pThis->g_cchBuf += cchRet; 460 503 } else { 461 504 /* Try write out complete lines. */ … … 466 509 const char *pchNewLine = strchr(pszLeft, '\n'); 467 510 ssize_t cchLine = pchNewLine ? pchNewLine - pszLeft + 1 : cchLeft; 468 if ( g_cchBuf + cchLine <= sizeof(g_achBuf)) {469 memcpy(& g_achBuf[g_cchBuf], pszLeft, cchLine);470 g_cchBuf += cchLine;511 if (pThis->g_cchBuf + cchLine <= sizeof(pThis->g_achBuf)) { 512 memcpy(&pThis->g_achBuf[pThis->g_cchBuf], pszLeft, cchLine); 513 pThis->g_cchBuf += cchLine; 471 514 } else { 472 if (flush_buffer( ) < 0) {515 if (flush_buffer(pThis) < 0) { 473 516 return -1; 474 517 } 475 if (fwrite(pszLeft, cchLine, 1, stdout) < 1) { 518 #ifndef KMK_BUILTIN_STANDALONE 519 if (output_write_text(pThis->pCtx->pOut, 0,pszLeft, cchLine) < 1) 520 #else 521 if (fwrite(pszLeft, cchLine, 1, stdout) < 1) 522 #endif 523 476 524 return -1; 477 }478 525 } 479 526 pszLeft += cchLine; … … 490 537 * Flushes the g_abBuf/g_cchBuf. 491 538 */ 492 static int flush_buffer(void) 493 { 494 if (g_cchBuf > 0) { 495 ssize_t cchToWrite = g_cchBuf; 496 ssize_t cchWritten = fwrite(g_achBuf, 1, g_cchBuf, stdout); 497 g_cchBuf = 0; 539 static int flush_buffer(PPRINTFINSTANCE pThis) 540 { 541 ssize_t cchToWrite = pThis->g_cchBuf; 542 if (cchToWrite > 0) { 543 #ifndef KMK_BUILTIN_STANDALONE 544 ssize_t cchWritten = output_write_text(pThis->pCtx->pOut, 0, pThis->g_achBuf, cchToWrite); 545 #else 546 ssize_t cchWritten = fwrite(pThis->g_achBuf, 1, cchToWrite, stdout); 547 #endif 548 pThis->g_cchBuf = 0; 498 549 if (cchWritten >= cchToWrite) { 499 550 /* likely */ … … 509 560 510 561 while (off < cchToWrite) { 511 cchWritten = fwrite(&g_achBuf[off], 1, cchToWrite - off, stdout); 562 #ifndef KMK_BUILTIN_STANDALONE 563 cchWritten = output_write_text(pThis->pCtx->pOut, 0, &pThis->g_achBuf[off], cchToWrite - off); 564 #else 565 cchWritten = fwrite(&pThis->g_achBuf[off], 1, cchToWrite - off, stdout); 566 #endif 512 567 if (cchWritten > 0) { 513 568 off += cchWritten; … … 530 585 */ 531 586 static void 532 conv_escape_str( char *str, void (*do_putchar)(int))587 conv_escape_str(PPRINTFINSTANCE pThis, char *str, void (*do_putchar)(PPRINTFINSTANCE, int)) 533 588 { 534 589 int value; … … 538 593 while ((ch = *str++) != '\0') { 539 594 if (ch != '\\') { 540 do_putchar( ch);595 do_putchar(pThis, ch); 541 596 continue; 542 597 } … … 545 600 if (ch == 'c') { 546 601 /* \c as in SYSV echo - abort all processing.... */ 547 rval |= 0x100;602 pThis->rval |= 0x100; 548 603 break; 549 604 } … … 561 616 octnum = (octnum << 3) | (*str++ - '0'); 562 617 } 563 do_putchar( octnum);618 do_putchar(pThis, octnum); 564 619 continue; 565 620 } … … 567 622 /* \[M][^|-]C as defined by vis(3) */ 568 623 if (ch == 'M' && *str == '-') { 569 do_putchar( 0200 | str[1]);624 do_putchar(pThis, 0200 | str[1]); 570 625 str += 2; 571 626 continue; … … 583 638 else 584 639 value |= ch & 037; 585 do_putchar( value);640 do_putchar(pThis, value); 586 641 continue; 587 642 } 588 643 589 644 /* Finally test for sequences valid in the format string */ 590 str = conv_escape( str - 1, &c);591 do_putchar( c);645 str = conv_escape(pThis, str - 1, &c); 646 do_putchar(pThis, c); 592 647 } 593 648 } … … 597 652 */ 598 653 static char * 599 conv_escape( char *str, char *conv_ch)654 conv_escape(PPRINTFINSTANCE pThis, char *str, char *conv_ch) 600 655 { 601 656 int value; … … 643 698 644 699 default: 645 warnx( "unknown escape sequence `\\%c'", ch);646 rval = 1;700 warnx(pThis->pCtx, "unknown escape sequence `\\%c'", ch); 701 pThis->rval = 1; 647 702 value = ch; 648 703 break; … … 720 775 721 776 static char * 722 mklong(const char *str, int ch) 723 { 724 static char copy[64]; 777 mklong(PPRINTFINSTANCE pThis, const char *str, int ch, char copy[64]) 778 { 725 779 size_t len; 726 780 727 781 len = strlen(str) - 1; 728 if (len > sizeof(copy)- 5) {729 warnx( "format %s too complex\n", str);782 if (len > 64 - 5) { 783 warnx(pThis->pCtx, "format %s too complex\n", str); 730 784 len = 4; 731 785 } … … 744 798 745 799 static int 746 getchr( void)747 { 748 if (!* gargv)800 getchr(PPRINTFINSTANCE pThis) 801 { 802 if (!*pThis->gargv) 749 803 return 0; 750 return (int)** gargv++;804 return (int)**pThis->gargv++; 751 805 } 752 806 753 807 static char * 754 getstr( void)808 getstr(PPRINTFINSTANCE pThis) 755 809 { 756 810 static char empty[] = ""; 757 if (!* gargv)811 if (!*pThis->gargv) 758 812 return empty; 759 return * gargv++;813 return *pThis->gargv++; 760 814 } 761 815 762 816 static int 763 getwidth( void)817 getwidth(PPRINTFINSTANCE pThis) 764 818 { 765 819 long val; 766 820 char *s, *ep; 767 821 768 s = * gargv;769 if (! *gargv)822 s = *pThis->gargv; 823 if (!s) 770 824 return (0); 771 gargv++;825 pThis->gargv++; 772 826 773 827 errno = 0; 774 828 val = strtoul(s, &ep, 0); 775 check_conversion( s, ep);829 check_conversion(pThis, s, ep); 776 830 777 831 /* Arbitrarily 'restrict' field widths to 1Mbyte */ 778 832 if (val < 0 || val > 1 << 20) { 779 warnx( "%s: invalid field width", s);833 warnx(pThis->pCtx, "%s: invalid field width", s); 780 834 return 0; 781 835 } … … 785 839 786 840 static intmax_t 787 getintmax( void)841 getintmax(PPRINTFINSTANCE pThis) 788 842 { 789 843 intmax_t val; 790 844 char *cp, *ep; 791 845 792 cp = * gargv;846 cp = *pThis->gargv; 793 847 if (cp == NULL) 794 848 return 0; 795 gargv++;849 pThis->gargv++; 796 850 797 851 if (*cp == '\"' || *cp == '\'') … … 800 854 errno = 0; 801 855 val = strtoimax(cp, &ep, 0); 802 check_conversion( cp, ep);856 check_conversion(pThis, cp, ep); 803 857 return val; 804 858 } 805 859 806 860 static uintmax_t 807 getuintmax( void)861 getuintmax(PPRINTFINSTANCE pThis) 808 862 { 809 863 uintmax_t val; 810 864 char *cp, *ep; 811 865 812 cp = * gargv;866 cp = *pThis->gargv; 813 867 if (cp == NULL) 814 868 return 0; 815 gargv++;869 pThis->gargv++; 816 870 817 871 if (*cp == '\"' || *cp == '\'') … … 822 876 cp++; 823 877 if (*cp == '-') { 824 warnx( "%s: expected positive numeric value", cp);825 rval = 1;878 warnx(pThis->pCtx, "%s: expected positive numeric value", cp); 879 pThis->rval = 1; 826 880 return 0; 827 881 } … … 829 883 errno = 0; 830 884 val = strtoumax(cp, &ep, 0); 831 check_conversion( cp, ep);885 check_conversion(pThis, cp, ep); 832 886 return val; 833 887 } 834 888 835 889 static double 836 getdouble( void)890 getdouble(PPRINTFINSTANCE pThis) 837 891 { 838 892 double val; 839 893 char *ep; 840 841 if (!*gargv) 894 char *s; 895 896 s = *pThis->gargv; 897 if (!s) 842 898 return (0.0); 843 844 if (**gargv == '\"' || **gargv == '\'') 845 return (double) *((*gargv++)+1); 899 pThis->gargv++; 900 901 if (*s == '\"' || *s == '\'') 902 return (double) s[1]; 846 903 847 904 errno = 0; 848 val = strtod( *gargv, &ep);849 check_conversion( *gargv++, ep);905 val = strtod(s, &ep); 906 check_conversion(pThis, s, ep); 850 907 return val; 851 908 } 852 909 853 910 static void 854 check_conversion( const char *s, const char *ep)911 check_conversion(PPRINTFINSTANCE pThis, const char *s, const char *ep) 855 912 { 856 913 if (*ep) { 857 914 if (ep == s) 858 warnx( "%s: expected numeric value", s);915 warnx(pThis->pCtx, "%s: expected numeric value", s); 859 916 else 860 warnx( "%s: not completely converted", s);861 rval = 1;917 warnx(pThis->pCtx, "%s: not completely converted", s); 918 pThis->rval = 1; 862 919 } else if (errno == ERANGE) { 863 warnx( "%s: %s", s, strerror(ERANGE));864 rval = 1;920 warnx(pThis->pCtx, "%s: %s", s, strerror(ERANGE)); 921 pThis->rval = 1; 865 922 } 866 923 } 867 924 868 925 static int 869 usage(FILE *pf) 870 { 871 fprintf(pf, "usage: %s format [arg ...]\n" 872 " or: %s --help\n" 873 " or: %s --version\n", 874 g_progname, g_progname, g_progname); 926 usage(PKMKBUILTINCTX pCtx, int fIsErr) 927 { 928 kmk_builtin_ctx_printf(pCtx, fIsErr, 929 "usage: %s format [arg ...]\n" 930 " or: %s --help\n" 931 " or: %s --version\n", 932 pCtx->pszProgName, pCtx->pszProgName, pCtx->pszProgName); 875 933 return 1; 876 934 } 935
Note:
See TracChangeset
for help on using the changeset viewer.