📄 snprintf.cc
字号:
}}/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags){#define MAX_CONVERT_PLACES 40 int signvalue = 0; unsigned long uvalue; char convert[MAX_CONVERT_PLACES]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; uvalue = -value; } else { if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[uvalue % (unsigned)base]; uvalue = (uvalue / (unsigned)base ); } while (uvalue && (place < MAX_CONVERT_PLACES)); if (place == MAX_CONVERT_PLACES) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */#ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place);#endif /* Spaces */ while (spadlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) dopr_outch(buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++spadlen; }}static void fmtqword(char *buffer, size_t *currlen, size_t maxlen, sint64 value, int base, int min, int max, int flags){#undef MAX_CONVERT_PLACES#define MAX_CONVERT_PLACES 80 int signvalue = 0; uint64 uvalue; char convert[MAX_CONVERT_PLACES]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; uvalue = -uvalue; } else { if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { uint64 uv = uvalue % (uint64)base; convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[uv]; uvalue = (uvalue / (uint64)base); } while ((uvalue != 0) && (place < MAX_CONVERT_PLACES)); if (place == MAX_CONVERT_PLACES) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */#ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place);#endif /* Spaces */ while (spadlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) dopr_outch(buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++spadlen; }}static LDOUBLE abs_val(LDOUBLE value){ return (value < 0) ? -value : value;}static LDOUBLE POW10(int exp){ LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result;}static LLONG ROUND(LDOUBLE value){ LLONG intpart; intpart = (LLONG)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart;}/* a replacement for modf that doesn't need the math library. Should be portable, but slow */static double my_modf(double x0, double *iptr){ int i; long l; double x = x0; double f = 1.0; for (i=0;i<100;i++) { l = (long)x; if (l <= (x+1) && l >= (x-1)) break; x *= 0.1; f *= 10.0; } if (i == 100) { /* yikes! the number is beyond what we can handle. What do we do? */ (*iptr) = 0; return 0; } if (i != 0) { double i2; double ret; ret = my_modf(x0-l*f, &i2); (*iptr) = l*f + i2; return ret; } (*iptr) = l; return x - (*iptr);}static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags){ int signvalue = 0; double ufvalue; char iconvert[311]; char fconvert[311]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int caps = 0; int index; double intpart; double fracpart; double temp; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val (fvalue); if (fvalue < 0) { signvalue = '-'; } else { if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ signvalue = '+'; } else { if (flags & DP_F_SPACE) signvalue = ' '; } }#if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */#endif#if 0 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */#endif /* * Sorry, we only support 16 digits past the decimal because of our * conversion method */ if (max > 16) max = 16; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ temp = ufvalue; my_modf(temp, &intpart); fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); if (fracpart >= POW10(max)) { intpart++; fracpart -= POW10(max); } /* Convert integer part */ do { temp = intpart; my_modf(intpart*0.1, &intpart); temp = temp*0.1; index = (int) ((temp -intpart +0.05)* 10.0); /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ /* printf ("%llf, %f, %x\n", temp, intpart, index); */ iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; } while (intpart && (iplace < 311)); if (iplace == 311) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ if (fracpart) { do { temp = fracpart; my_modf(fracpart*0.1, &fracpart); temp = temp*0.1; index = (int) ((temp -fracpart +0.05)* 10.0); /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */ /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */ fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; } while(fracpart && (fplace < 311)); if (fplace == 311) fplace--; } fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch(buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) dopr_outch(buffer, currlen, maxlen, signvalue); while (iplace > 0) dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);#ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);#endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch(buffer, currlen, maxlen, '.'); while (fplace > 0) dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); } while (zpadlen > 0) { dopr_outch(buffer, currlen, maxlen, '0'); --zpadlen; } while (padlen < 0) { dopr_outch(buffer, currlen, maxlen, ' '); ++padlen; }}static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c){ if (*currlen < maxlen) { buffer[(*currlen)] = c; } (*currlen)++;}int ht_vsnprintf (char *str, size_t count, const char *fmt, va_list args){ if ((int)count < 0) count = 0; int res = dopr(str, count, fmt, args); if (count) count--; return str ? MIN(res, (int)count) : count;}int ht_snprintf(char *str, size_t count, const char *fmt,...){ int ret; va_list ap; va_start(ap, fmt); ret = ht_vsnprintf(str, count, fmt, ap); va_end(ap); return ret;}int ht_vasprintf(char **ptr, const char *format, va_list ap){ int ret; ret = dopr(NULL, 0, format, ap); if (ret <= 0) { *ptr = NULL; return 0; } (*ptr) = ht_malloc(ret+1); if (!*ptr) return 0; ret = ht_vsnprintf(*ptr, ret+1, format, ap); return ret;}int ht_asprintf(char **ptr, const char *format, ...){ va_list ap; int ret; va_start(ap, format); ret = ht_vasprintf(ptr, format, ap); va_end(ap); return ret;}int ht_vfprintf(FILE *file, const char *fmt, va_list args){#if 0 char *buf; int ret = ht_vasprintf(&buf, fmt, args); fputs(buf, file); free(buf);#else char buf[10024]; int ret = ht_vsnprintf(buf, sizeof buf, fmt, args); fputs(buf, file);#endif return ret;}int ht_fprintf(FILE *file, const char *fmt, ...){ va_list ap; int ret; va_start(ap, fmt); ret = ht_vfprintf(file, fmt, ap); va_end(ap); return ret;}int ht_vprintf(const char *fmt, va_list args){ return ht_vfprintf(stdout, fmt, args);}int ht_printf(const char *fmt, ...){ va_list ap; int ret; va_start(ap, fmt); ret = ht_vprintf(fmt, ap); va_end(ap); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -