00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #include <ctype.h>
00066 #include <string.h>
00067 #include <stdlib.h>
00068 #include <stdarg.h>
00069 #include <sys/types.h>
00070
00071 #include "common.h"
00072 #include "global.h"
00073 #include "tools.h"
00074
00075 #ifndef NO_CONFIG_H
00076 #include "config.h"
00077 #endif
00078
00079
00080 #ifdef HAVE_LONG_DOUBLE
00081 #define LDOUBLE long double
00082 #else
00083 #define LDOUBLE double
00084 #endif
00085
00086 #ifdef HAVE_LONG_LONG
00087 #define LLONG long long
00088 #else
00089 #define LLONG long
00090 #endif
00091
00092 static size_t dopr(char *buffer, size_t maxlen, const char *format,
00093 va_list args);
00094 static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
00095 char *value, int flags, int min, int max);
00096 static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
00097 long value, int base, int min, int max, int flags);
00098 static void fmtqword(char *buffer, size_t *currlen, size_t maxlen,
00099 sint64 value, int base, int min, int max, int flags);
00100 static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
00101 LDOUBLE fvalue, int min, int max, int flags);
00102 static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
00103
00104
00105
00106
00107
00108
00109 #define DP_S_DEFAULT 0
00110 #define DP_S_FLAGS 1
00111 #define DP_S_MIN 2
00112 #define DP_S_DOT 3
00113 #define DP_S_MAX 4
00114 #define DP_S_MOD 5
00115 #define DP_S_CONV 6
00116 #define DP_S_DONE 7
00117
00118
00119 #define DP_F_MINUS (1 << 0)
00120 #define DP_F_PLUS (1 << 1)
00121 #define DP_F_SPACE (1 << 2)
00122 #define DP_F_NUM (1 << 3)
00123 #define DP_F_ZERO (1 << 4)
00124 #define DP_F_UP (1 << 5)
00125 #define DP_F_UNSIGNED (1 << 6)
00126
00127
00128 #define DP_C_SHORT 1
00129 #define DP_C_LONG 2
00130 #define DP_C_LDOUBLE 3
00131 #define DP_C_LLONG 4
00132 #define DP_C_QWORD 5
00133
00134 #define char_to_int(p) ((p)- '0')
00135 #ifndef MAX
00136 #define MAX(p,q) (((p) >= (q)) ? (p) : (q))
00137 #endif
00138
00139 static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
00140 {
00141 char ch;
00142 LLONG value;
00143 LDOUBLE fvalue;
00144 char *strvalue;
00145 int min;
00146 int max;
00147 int state;
00148 int flags;
00149 int cflags;
00150 size_t currlen;
00151
00152 state = DP_S_DEFAULT;
00153 currlen = flags = cflags = min = 0;
00154 max = -1;
00155 ch = *format++;
00156
00157 while (state != DP_S_DONE) {
00158 if (ch == '\0')
00159 state = DP_S_DONE;
00160
00161 switch(state) {
00162 case DP_S_DEFAULT:
00163 if (ch == '%')
00164 state = DP_S_FLAGS;
00165 else
00166 dopr_outch (buffer, &currlen, maxlen, ch);
00167 ch = *format++;
00168 break;
00169 case DP_S_FLAGS:
00170 switch (ch) {
00171 case '-':
00172 flags |= DP_F_MINUS;
00173 ch = *format++;
00174 break;
00175 case '+':
00176 flags |= DP_F_PLUS;
00177 ch = *format++;
00178 break;
00179 case ' ':
00180 flags |= DP_F_SPACE;
00181 ch = *format++;
00182 break;
00183 case '#':
00184 flags |= DP_F_NUM;
00185 ch = *format++;
00186 break;
00187 case '0':
00188 flags |= DP_F_ZERO;
00189 ch = *format++;
00190 break;
00191 default:
00192 state = DP_S_MIN;
00193 break;
00194 }
00195 break;
00196 case DP_S_MIN:
00197 if (isdigit((unsigned char)ch)) {
00198 min = 10*min + char_to_int (ch);
00199 ch = *format++;
00200 } else if (ch == '*') {
00201 min = va_arg (args, int);
00202 ch = *format++;
00203 state = DP_S_DOT;
00204 } else {
00205 state = DP_S_DOT;
00206 }
00207 break;
00208 case DP_S_DOT:
00209 if (ch == '.') {
00210 state = DP_S_MAX;
00211 ch = *format++;
00212 } else {
00213 state = DP_S_MOD;
00214 }
00215 break;
00216 case DP_S_MAX:
00217 if (isdigit((unsigned char)ch)) {
00218 if (max < 0)
00219 max = 0;
00220 max = 10*max + char_to_int (ch);
00221 ch = *format++;
00222 } else if (ch == '*') {
00223 max = va_arg (args, int);
00224 ch = *format++;
00225 state = DP_S_MOD;
00226 } else {
00227 state = DP_S_MOD;
00228 }
00229 break;
00230 case DP_S_MOD:
00231 switch (ch) {
00232 case 'h':
00233 cflags = DP_C_SHORT;
00234 ch = *format++;
00235 break;
00236 case 'l':
00237 cflags = DP_C_LONG;
00238 ch = *format++;
00239 if (ch == 'l') {
00240 cflags = DP_C_LLONG;
00241 ch = *format++;
00242 }
00243 break;
00244 case 'L':
00245 cflags = DP_C_LDOUBLE;
00246 ch = *format++;
00247 break;
00248 case 'q':
00249 cflags = DP_C_QWORD;
00250 ch = *format++;
00251 break;
00252 default:
00253 break;
00254 }
00255 state = DP_S_CONV;
00256 break;
00257 case DP_S_CONV:
00258 switch (ch) {
00259 case 'b':
00260 flags |= DP_F_UNSIGNED;
00261 if (cflags == DP_C_SHORT)
00262 value = va_arg (args, unsigned int);
00263 else if (cflags == DP_C_LONG)
00264 value = (long)va_arg (args, unsigned long int);
00265 else if (cflags == DP_C_LLONG)
00266 value = (LLONG)va_arg (args, unsigned LLONG);
00267 else if (cflags == DP_C_QWORD) {
00268 sint64 *q = va_arg (args, sint64 *);
00269 fmtqword(buffer, &currlen, maxlen, *q, 2, min, max, flags);
00270 break;
00271 } else
00272 value = (long)va_arg (args, unsigned int);
00273 fmtint (buffer, &currlen, maxlen, value, 2, min, max, flags);
00274 break;
00275 case 'd':
00276 case 'i':
00277 if (cflags == DP_C_SHORT)
00278 value = va_arg (args, int);
00279 else if (cflags == DP_C_LONG)
00280 value = va_arg (args, long int);
00281 else if (cflags == DP_C_LLONG)
00282 value = va_arg (args, LLONG);
00283 else if (cflags == DP_C_QWORD) {
00284 sint64 *q = va_arg (args, sint64 *);
00285 fmtqword(buffer, &currlen, maxlen, *q, 10, min, max, flags);
00286 break;
00287 } else
00288 value = va_arg (args, int);
00289 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
00290 break;
00291 case 'o':
00292 flags |= DP_F_UNSIGNED;
00293 if (cflags == DP_C_SHORT)
00294 value = va_arg (args, unsigned int);
00295 else if (cflags == DP_C_LONG)
00296 value = (long)va_arg (args, unsigned long int);
00297 else if (cflags == DP_C_LLONG)
00298 value = (long)va_arg (args, unsigned LLONG);
00299 else if (cflags == DP_C_QWORD) {
00300 sint64 *q = va_arg (args, sint64 *);
00301 fmtqword(buffer, &currlen, maxlen, *q, 8, min, max, flags);
00302 break;
00303 } else
00304 value = (long)va_arg (args, unsigned int);
00305 fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
00306 break;
00307 case 'u':
00308 flags |= DP_F_UNSIGNED;
00309 if (cflags == DP_C_SHORT)
00310 value = va_arg (args, unsigned int);
00311 else if (cflags == DP_C_LONG)
00312 value = (long)va_arg (args, unsigned long int);
00313 else if (cflags == DP_C_LLONG)
00314 value = (LLONG)va_arg (args, unsigned LLONG);
00315 else if (cflags == DP_C_QWORD) {
00316 sint64 *q = va_arg (args, sint64 *);
00317 fmtqword(buffer, &currlen, maxlen, *q, 10, min, max, flags);
00318 break;
00319 } else
00320 value = (long)va_arg (args, unsigned int);
00321 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
00322 break;
00323 case 'X':
00324 flags |= DP_F_UP;
00325 case 'x':
00326 flags |= DP_F_UNSIGNED;
00327 if (cflags == DP_C_SHORT)
00328 value = va_arg (args, unsigned int);
00329 else if (cflags == DP_C_LONG)
00330 value = (long)va_arg (args, unsigned long int);
00331 else if (cflags == DP_C_LLONG)
00332 value = (LLONG)va_arg (args, unsigned LLONG);
00333 else if (cflags == DP_C_QWORD) {
00334 sint64 *q = va_arg (args, sint64 *);
00335 fmtqword(buffer, &currlen, maxlen, *q, 16, min, max, flags);
00336 break;
00337 } else
00338 value = (long)va_arg (args, unsigned int);
00339 fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
00340 break;
00341 case 'f':
00342 if (cflags == DP_C_LDOUBLE)
00343 fvalue = va_arg (args, LDOUBLE);
00344 else
00345 fvalue = va_arg (args, double);
00346
00347 fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
00348 break;
00349 case 'E':
00350 flags |= DP_F_UP;
00351 case 'e':
00352 if (cflags == DP_C_LDOUBLE)
00353 fvalue = va_arg (args, LDOUBLE);
00354 else
00355 fvalue = va_arg (args, double);
00356 break;
00357 case 'G':
00358 flags |= DP_F_UP;
00359 case 'g':
00360 if (cflags == DP_C_LDOUBLE)
00361 fvalue = va_arg (args, LDOUBLE);
00362 else
00363 fvalue = va_arg (args, double);
00364 break;
00365 case 'c':
00366 dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
00367 break;
00368 case 's':
00369 strvalue = va_arg (args, char *);
00370 if (!strvalue) strvalue = "(null)";
00371 if (max == -1) {
00372 max = strlen(strvalue);
00373 }
00374 if (min > 0 && max >= 0 && min > max) max = min;
00375 fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
00376 break;
00377 case 'p':
00378 strvalue = va_arg (args, char *);
00379 fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
00380 break;
00381 case 'n':
00382 if (cflags == DP_C_SHORT) {
00383 short int *num;
00384 num = va_arg (args, short int *);
00385 *num = currlen;
00386 } else if (cflags == DP_C_LONG) {
00387 long int *num;
00388 num = va_arg (args, long int *);
00389 *num = (long int)currlen;
00390 } else if (cflags == DP_C_LLONG) {
00391 LLONG *num;
00392 num = va_arg (args, LLONG *);
00393 *num = (LLONG)currlen;
00394 } else {
00395 int *num;
00396 num = va_arg (args, int *);
00397 *num = currlen;
00398 }
00399 break;
00400 case '%':
00401 dopr_outch (buffer, &currlen, maxlen, ch);
00402 break;
00403 case 'w':
00404
00405 ch = *format++;
00406 break;
00407 case 'y':
00408
00409 strvalue = va_arg (args, char *);
00410 currlen += ((Object*)strvalue)->toString(buffer+currlen, maxlen - currlen);
00411 break;
00412 default:
00413
00414 break;
00415 }
00416 ch = *format++;
00417 state = DP_S_DEFAULT;
00418 flags = cflags = min = 0;
00419 max = -1;
00420 break;
00421 case DP_S_DONE:
00422 break;
00423 default:
00424
00425 break;
00426 }
00427 }
00428 if (maxlen != 0) {
00429 if (currlen < maxlen - 1)
00430 buffer[currlen] = '\0';
00431 else if (maxlen > 0)
00432 buffer[maxlen - 1] = '\0';
00433 }
00434
00435 return currlen;
00436 }
00437
00438 static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
00439 char *value, int flags, int min, int max)
00440 {
00441 int padlen, strln;
00442 int cnt = 0;
00443
00444 #ifdef DEBUG_SNPRINTF
00445 printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
00446 #endif
00447 if (value == 0) {
00448 value = "<NULL>";
00449 }
00450
00451 for (strln = 0; value[strln]; ++strln);
00452 padlen = min - strln;
00453 if (padlen < 0)
00454 padlen = 0;
00455 if (flags & DP_F_MINUS)
00456 padlen = -padlen;
00457
00458 while ((padlen > 0) && (cnt < max)) {
00459 dopr_outch (buffer, currlen, maxlen, ' ');
00460 --padlen;
00461 ++cnt;
00462 }
00463 while (*value && (cnt < max)) {
00464 dopr_outch (buffer, currlen, maxlen, *value++);
00465 ++cnt;
00466 }
00467 while ((padlen < 0) && (cnt < max)) {
00468 dopr_outch (buffer, currlen, maxlen, ' ');
00469 ++padlen;
00470 ++cnt;
00471 }
00472 }
00473
00474
00475
00476 static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
00477 long value, int base, int min, int max, int flags)
00478 {
00479 #define MAX_CONVERT_PLACES 40
00480 int signvalue = 0;
00481 unsigned long uvalue;
00482 char convert[MAX_CONVERT_PLACES];
00483 int place = 0;
00484 int spadlen = 0;
00485 int zpadlen = 0;
00486 int caps = 0;
00487
00488 if (max < 0)
00489 max = 0;
00490
00491 uvalue = value;
00492
00493 if(!(flags & DP_F_UNSIGNED)) {
00494 if( value < 0 ) {
00495 signvalue = '-';
00496 uvalue = -value;
00497 } else {
00498 if (flags & DP_F_PLUS)
00499 signvalue = '+';
00500 else if (flags & DP_F_SPACE)
00501 signvalue = ' ';
00502 }
00503 }
00504
00505 if (flags & DP_F_UP) caps = 1;
00506
00507 do {
00508 convert[place++] =
00509 (caps? "0123456789ABCDEF":"0123456789abcdef")
00510 [uvalue % (unsigned)base ];
00511 uvalue = (uvalue / (unsigned)base );
00512 } while(uvalue && (place < MAX_CONVERT_PLACES));
00513 if (place == MAX_CONVERT_PLACES) place--;
00514 convert[place] = 0;
00515
00516 zpadlen = max - place;
00517 spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
00518 if (zpadlen < 0) zpadlen = 0;
00519 if (spadlen < 0) spadlen = 0;
00520 if (flags & DP_F_ZERO) {
00521 zpadlen = MAX(zpadlen, spadlen);
00522 spadlen = 0;
00523 }
00524 if (flags & DP_F_MINUS)
00525 spadlen = -spadlen;
00526
00527 #ifdef DEBUG_SNPRINTF
00528 printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
00529 zpadlen, spadlen, min, max, place);
00530 #endif
00531
00532
00533 while (spadlen > 0) {
00534 dopr_outch (buffer, currlen, maxlen, ' ');
00535 --spadlen;
00536 }
00537
00538
00539 if (signvalue)
00540 dopr_outch (buffer, currlen, maxlen, signvalue);
00541
00542
00543 if (zpadlen > 0) {
00544 while (zpadlen > 0) {
00545 dopr_outch (buffer, currlen, maxlen, '0');
00546 --zpadlen;
00547 }
00548 }
00549
00550
00551 while (place > 0)
00552 dopr_outch (buffer, currlen, maxlen, convert[--place]);
00553
00554
00555 while (spadlen < 0) {
00556 dopr_outch (buffer, currlen, maxlen, ' ');
00557 ++spadlen;
00558 }
00559 }
00560
00561 static void fmtqword(char *buffer, size_t *currlen, size_t maxlen,
00562 sint64 value, int base, int min, int max, int flags)
00563 {
00564 #undef MAX_CONVERT_PLACES
00565 #define MAX_CONVERT_PLACES 80
00566 int signvalue = 0;
00567 uint64 uvalue;
00568 char convert[MAX_CONVERT_PLACES];
00569 int place = 0;
00570 int spadlen = 0;
00571 int zpadlen = 0;
00572 int caps = 0;
00573
00574 if (max < 0)
00575 max = 0;
00576
00577 uvalue = to_uint64(value);
00578
00579 if (!(flags & DP_F_UNSIGNED)) {
00580 if (value < to_sint64(0)) {
00581 signvalue = '-';
00582 uvalue = to_uint64(-value);
00583 } else {
00584 if (flags & DP_F_PLUS)
00585 signvalue = '+';
00586 else if (flags & DP_F_SPACE)
00587 signvalue = ' ';
00588 }
00589 }
00590
00591 if (flags & DP_F_UP) caps = 1;
00592
00593 do {
00594 qword uv = uvalue % to_qword((unsigned)base);
00595 convert[place++] =
00596 (caps? "0123456789ABCDEF":"0123456789abcdef")
00597 [uv.lo];
00598 uvalue = (uvalue / to_qword((unsigned)base));
00599 } while ((uvalue != to_qword(0)) && (place < MAX_CONVERT_PLACES));
00600 if (place == MAX_CONVERT_PLACES) place--;
00601 convert[place] = 0;
00602
00603 zpadlen = max - place;
00604 spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
00605 if (zpadlen < 0) zpadlen = 0;
00606 if (spadlen < 0) spadlen = 0;
00607 if (flags & DP_F_ZERO) {
00608 zpadlen = MAX(zpadlen, spadlen);
00609 spadlen = 0;
00610 }
00611 if (flags & DP_F_MINUS)
00612 spadlen = -spadlen;
00613
00614 #ifdef DEBUG_SNPRINTF
00615 printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
00616 zpadlen, spadlen, min, max, place);
00617 #endif
00618
00619
00620 while (spadlen > 0) {
00621 dopr_outch (buffer, currlen, maxlen, ' ');
00622 --spadlen;
00623 }
00624
00625
00626 if (signvalue)
00627 dopr_outch (buffer, currlen, maxlen, signvalue);
00628
00629
00630 if (zpadlen > 0) {
00631 while (zpadlen > 0) {
00632 dopr_outch (buffer, currlen, maxlen, '0');
00633 --zpadlen;
00634 }
00635 }
00636
00637
00638 while (place > 0)
00639 dopr_outch (buffer, currlen, maxlen, convert[--place]);
00640
00641
00642 while (spadlen < 0) {
00643 dopr_outch (buffer, currlen, maxlen, ' ');
00644 ++spadlen;
00645 }
00646 }
00647
00648 static LDOUBLE abs_val(LDOUBLE value)
00649 {
00650 LDOUBLE result = value;
00651
00652 if (value < 0)
00653 result = -value;
00654
00655 return result;
00656 }
00657
00658 static LDOUBLE POW10(int exp)
00659 {
00660 LDOUBLE result = 1;
00661
00662 while (exp) {
00663 result *= 10;
00664 exp--;
00665 }
00666
00667 return result;
00668 }
00669
00670 static LLONG ROUND(LDOUBLE value)
00671 {
00672 LLONG intpart;
00673
00674 intpart = (LLONG)value;
00675 value = value - intpart;
00676 if (value >= 0.5) intpart++;
00677
00678 return intpart;
00679 }
00680
00681
00682
00683 static double my_modf(double x0, double *iptr)
00684 {
00685 int i;
00686 long l;
00687 double x = x0;
00688 double f = 1.0;
00689
00690 for (i=0;i<100;i++) {
00691 l = (long)x;
00692 if (l <= (x+1) && l >= (x-1)) break;
00693 x *= 0.1;
00694 f *= 10.0;
00695 }
00696
00697 if (i == 100) {
00698
00699 (*iptr) = 0;
00700 return 0;
00701 }
00702
00703 if (i != 0) {
00704 double i2;
00705 double ret;
00706
00707 ret = my_modf(x0-l*f, &i2);
00708 (*iptr) = l*f + i2;
00709 return ret;
00710 }
00711
00712 (*iptr) = l;
00713 return x - (*iptr);
00714 }
00715
00716
00717 static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
00718 LDOUBLE fvalue, int min, int max, int flags)
00719 {
00720 int signvalue = 0;
00721 double ufvalue;
00722 char iconvert[311];
00723 char fconvert[311];
00724 int iplace = 0;
00725 int fplace = 0;
00726 int padlen = 0;
00727 int zpadlen = 0;
00728 int caps = 0;
00729 int index;
00730 double intpart;
00731 double fracpart;
00732 double temp;
00733
00734
00735
00736
00737
00738 if (max < 0)
00739 max = 6;
00740
00741 ufvalue = abs_val (fvalue);
00742
00743 if (fvalue < 0) {
00744 signvalue = '-';
00745 } else {
00746 if (flags & DP_F_PLUS) {
00747 signvalue = '+';
00748 } else {
00749 if (flags & DP_F_SPACE)
00750 signvalue = ' ';
00751 }
00752 }
00753
00754 #if 0
00755 if (flags & DP_F_UP) caps = 1;
00756 #endif
00757
00758 #if 0
00759 if (max == 0) ufvalue += 0.5;
00760 #endif
00761
00762
00763
00764
00765
00766 if (max > 16)
00767 max = 16;
00768
00769
00770
00771
00772
00773 temp = ufvalue;
00774 my_modf(temp, &intpart);
00775
00776 fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
00777
00778 if (fracpart >= POW10(max)) {
00779 intpart++;
00780 fracpart -= POW10(max);
00781 }
00782
00783
00784
00785 do {
00786 temp = intpart;
00787 my_modf(intpart*0.1, &intpart);
00788 temp = temp*0.1;
00789 index = (int) ((temp -intpart +0.05)* 10.0);
00790
00791
00792 iconvert[iplace++] =
00793 (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
00794 } while (intpart && (iplace < 311));
00795 if (iplace == 311) iplace--;
00796 iconvert[iplace] = 0;
00797
00798
00799 if (fracpart)
00800 {
00801 do {
00802 temp = fracpart;
00803 my_modf(fracpart*0.1, &fracpart);
00804 temp = temp*0.1;
00805 index = (int) ((temp -fracpart +0.05)* 10.0);
00806
00807
00808 fconvert[fplace++] =
00809 (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
00810 } while(fracpart && (fplace < 311));
00811 if (fplace == 311) fplace--;
00812 }
00813 fconvert[fplace] = 0;
00814
00815
00816 padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
00817 zpadlen = max - fplace;
00818 if (zpadlen < 0) zpadlen = 0;
00819 if (padlen < 0)
00820 padlen = 0;
00821 if (flags & DP_F_MINUS)
00822 padlen = -padlen;
00823
00824 if ((flags & DP_F_ZERO) && (padlen > 0)) {
00825 if (signvalue) {
00826 dopr_outch (buffer, currlen, maxlen, signvalue);
00827 --padlen;
00828 signvalue = 0;
00829 }
00830 while (padlen > 0) {
00831 dopr_outch (buffer, currlen, maxlen, '0');
00832 --padlen;
00833 }
00834 }
00835 while (padlen > 0) {
00836 dopr_outch (buffer, currlen, maxlen, ' ');
00837 --padlen;
00838 }
00839 if (signvalue)
00840 dopr_outch (buffer, currlen, maxlen, signvalue);
00841
00842 while (iplace > 0)
00843 dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
00844
00845 #ifdef DEBUG_SNPRINTF
00846 printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
00847 #endif
00848
00849
00850
00851
00852
00853 if (max > 0) {
00854 dopr_outch (buffer, currlen, maxlen, '.');
00855
00856 while (fplace > 0)
00857 dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
00858 }
00859
00860 while (zpadlen > 0) {
00861 dopr_outch (buffer, currlen, maxlen, '0');
00862 --zpadlen;
00863 }
00864
00865 while (padlen < 0) {
00866 dopr_outch (buffer, currlen, maxlen, ' ');
00867 ++padlen;
00868 }
00869 }
00870
00871 static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
00872 {
00873 if (*currlen < maxlen) {
00874 buffer[(*currlen)] = c;
00875 }
00876 (*currlen)++;
00877 }
00878
00879 int ht_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
00880 {
00881 if ((int)count < 0) count = 0;
00882 int res = dopr(str, count, fmt, args);
00883 if (count) count--;
00884 return str ? MIN(res, (int)count) : count;
00885 }
00886
00887 int ht_snprintf(char *str, size_t count, const char *fmt,...)
00888 {
00889 size_t ret;
00890 va_list ap;
00891
00892 va_start(ap, fmt);
00893 ret = ht_vsnprintf(str, count, fmt, ap);
00894 va_end(ap);
00895 return ret;
00896 }
00897
00898 int ht_vasprintf(char **ptr, const char *format, va_list ap)
00899 {
00900 int ret;
00901
00902 ret = dopr(NULL, 0, format, ap);
00903 if (ret <= 0) {
00904 *ptr = NULL;
00905 return 0;
00906 }
00907
00908 (*ptr) = (char *)malloc(ret+1);
00909 if (!*ptr) return 0;
00910 ret = ht_vsnprintf(*ptr, ret+1, format, ap);
00911
00912 return ret;
00913 }
00914
00915
00916 int ht_asprintf(char **ptr, const char *format, ...)
00917 {
00918 va_list ap;
00919 int ret;
00920
00921 va_start(ap, format);
00922 ret = ht_vasprintf(ptr, format, ap);
00923 va_end(ap);
00924
00925 return ret;
00926 }
00927
00928 int ht_vfprintf(FILE *file, const char *fmt, va_list args)
00929 {
00930 #if 0
00931 char *buf;
00932 int ret = ht_vasprintf(&buf, fmt, args);
00933 fputs(buf, file);
00934 free(buf);
00935 #else
00936 char buf[1024];
00937 int ret = ht_vsnprintf(buf, sizeof buf, fmt, args);
00938 fputs(buf, file);
00939 #endif
00940 return ret;
00941 }
00942
00943 int ht_fprintf(FILE *file, const char *fmt, ...)
00944 {
00945 va_list ap;
00946 int ret;
00947
00948 va_start(ap, fmt);
00949 ret = ht_vfprintf(file, fmt, ap);
00950 va_end(ap);
00951
00952 return ret;
00953 }
00954
00955
00956 int ht_vprintf(const char *fmt, va_list args)
00957 {
00958 return ht_vfprintf(stdout, fmt, args);
00959 }
00960
00961 int ht_printf(const char *fmt, ...)
00962 {
00963 va_list ap;
00964 int ret;
00965
00966 va_start(ap, fmt);
00967 ret = ht_vprintf(fmt, ap);
00968 va_end(ap);
00969
00970 return ret;
00971 }