📄 apr_snprintf.c
字号:
*len = buf_end - p; return (p);}static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len){ unsigned addr = ntohl(ia->s_addr); char *p = buf_end; bool_int is_negative; int sub_len; p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len); *--p = '.'; p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len); *--p = '.'; p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len); *--p = '.'; p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len); *len = buf_end - p; return (p);}static char *conv_apr_sockaddr(apr_sockaddr_t *sa, char *buf_end, int *len){ char *p = buf_end; bool_int is_negative; int sub_len; char *ipaddr_str; p = conv_10(sa->port, TRUE, &is_negative, p, &sub_len); *--p = ':'; apr_sockaddr_ip_get(&ipaddr_str, sa); sub_len = strlen(ipaddr_str);#if APR_HAVE_IPV6 if (sa->family == APR_INET6 && !IN6_IS_ADDR_V4MAPPED(&sa->sa.sin6.sin6_addr)) { *(p - 1) = ']'; p -= sub_len + 2; *p = '['; memcpy(p + 1, ipaddr_str, sub_len); } else#endif { p -= sub_len; memcpy(p, ipaddr_str, sub_len); } *len = buf_end - p; return (p);}#if APR_HAS_THREADSstatic char *conv_os_thread_t(apr_os_thread_t *tid, char *buf_end, int *len){ union { apr_os_thread_t tid; apr_uint64_t alignme; } u; int is_negative; u.tid = *tid; switch(sizeof(u.tid)) { case sizeof(apr_int32_t): return conv_10(*(apr_uint32_t *)&u.tid, TRUE, &is_negative, buf_end, len); case sizeof(apr_int64_t): return conv_10_quad(*(apr_uint64_t *)&u.tid, TRUE, &is_negative, buf_end, len); default: /* not implemented; stick 0 in the buffer */ return conv_10(0, TRUE, &is_negative, buf_end, len); }}#endif/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */static char *conv_fp(register char format, register double num, boolean_e add_dp, int precision, bool_int *is_negative, char *buf, int *len){ register char *s = buf; register char *p; int decimal_point; char buf1[NDIG]; if (format == 'f') p = apr_fcvt(num, precision, &decimal_point, is_negative, buf1); else /* either e or E format */ p = apr_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); /* * Check for Infinity and NaN */ if (apr_isalpha(*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); *is_negative = FALSE; return (buf); } if (format == 'f') { if (decimal_point <= 0) { *s++ = '0'; if (precision > 0) { *s++ = '.'; while (decimal_point++ < 0) *s++ = '0'; } else if (add_dp) *s++ = '.'; } else { while (decimal_point-- > 0) *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } } else { *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } /* * copy the rest of p, the NUL is NOT copied */ while (*p) *s++ = *p++; if (format != 'f') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ int t_len; bool_int exponent_is_negative; *s++ = format; /* either e or E */ decimal_point--; if (decimal_point != 0) { p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; /* * Make sure the exponent has at least 2 digits */ if (t_len == 1) *s++ = '0'; while (t_len--) *s++ = *p++; } else { *s++ = '+'; *s++ = '0'; *s++ = '0'; } } *len = s - buf; return (buf);}/* * Convert num to a base X number where X is a power of 2. nbits determines X. * For example, if nbits is 3, we do base 8 conversion * Return value: * a pointer to a string containing the number * * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) * * As with conv_10, we have a faster version which is used when * the number isn't quad size. */static char *conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register int *len){ register int mask = (1 << nbits) - 1; register char *p = buf_end; static const char low_digits[] = "0123456789abcdef"; static const char upper_digits[] = "0123456789ABCDEF"; register const char *digits = (format == 'X') ? upper_digits : low_digits; do { *--p = digits[num & mask]; num >>= nbits; } while (num); *len = buf_end - p; return (p);}static char *conv_p2_quad(u_widest_int num, register int nbits, char format, char *buf_end, register int *len){ register int mask = (1 << nbits) - 1; register char *p = buf_end; static const char low_digits[] = "0123456789abcdef"; static const char upper_digits[] = "0123456789ABCDEF"; register const char *digits = (format == 'X') ? upper_digits : low_digits; if (num <= ULONG_MAX) return(conv_p2((u_wide_int)num, nbits, format, buf_end, len)); do { *--p = digits[num & mask]; num >>= nbits; } while (num); *len = buf_end - p; return (p);}/* * Do format conversion placing the output in buffer */APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), apr_vformatter_buff_t *vbuff, const char *fmt, va_list ap){ register char *sp; register char *bep; register int cc = 0; register int i; register char *s = NULL; char *q; int s_len; register int min_width = 0; int precision = 0; enum { LEFT, RIGHT } adjust; char pad_char; char prefix_char; double fp_num; widest_int i_quad = (widest_int) 0; u_widest_int ui_quad; wide_int i_num = (wide_int) 0; u_wide_int ui_num; char num_buf[NUM_BUF_SIZE]; char char_buf[2]; /* for printing %% and %<unknown> */ enum var_type_enum { IS_QUAD, IS_LONG, IS_SHORT, IS_INT }; enum var_type_enum var_type = IS_INT; /* * Flag variables */ boolean_e alternate_form; boolean_e print_sign; boolean_e print_blank; boolean_e adjust_precision; boolean_e adjust_width; bool_int is_negative; sp = vbuff->curpos; bep = vbuff->endpos; while (*fmt) { if (*fmt != '%') { INS_CHAR(*fmt, sp, bep, cc); } else { /* * Default variable settings */ boolean_e print_something = YES; adjust = RIGHT; alternate_form = print_sign = print_blank = NO; pad_char = ' '; prefix_char = NUL; fmt++; /* * Try to avoid checking for flags, width or precision */ if (!apr_islower(*fmt)) { /* * Recognize flags: -, #, BLANK, + */ for (;; fmt++) { if (*fmt == '-') adjust = LEFT; else if (*fmt == '+') print_sign = YES; else if (*fmt == '#') alternate_form = YES; else if (*fmt == ' ') print_blank = YES; else if (*fmt == '0') pad_char = '0'; else break; } /* * Check if a width was specified */ if (apr_isdigit(*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = YES; } else if (*fmt == '*') { min_width = va_arg(ap, int); fmt++; adjust_width = YES; if (min_width < 0) { adjust = LEFT; min_width = -min_width; } } else adjust_width = NO; /* * Check if a precision was specified */ if (*fmt == '.') { adjust_precision = YES; fmt++; if (apr_isdigit(*fmt)) { STR_TO_DEC(fmt, precision); } else if (*fmt == '*') { precision = va_arg(ap, int); fmt++; if (precision < 0) precision = 0; } else precision = 0; } else adjust_precision = NO; } else adjust_precision = adjust_width = NO; /* * Modifier check */#if defined(APR_INT64_T_FMT_LEN) && (APR_INT64_T_FMT_LEN == 3) if ((*fmt == APR_INT64_T_FMT[0]) && (fmt[1] == APR_INT64_T_FMT[1])) {#elif defined(APR_INT64_T_FMT_LEN) && (APR_INT64_T_FMT_LEN == 2) if (*fmt == APR_INT64_T_FMT[0]) {#else if (strncmp(fmt, APR_INT64_T_FMT, sizeof(APR_INT64_T_FMT) - 2) == 0) {#endif /* Need to account for trailing 'd' and null in sizeof() */ var_type = IS_QUAD; fmt += (sizeof(APR_INT64_T_FMT) - 2); } else if (*fmt == 'q') { var_type = IS_QUAD; fmt++; } else if (*fmt == 'l') { var_type = IS_LONG; fmt++; } else if (*fmt == 'h') { var_type = IS_SHORT; fmt++; } else { var_type = IS_INT; } /* * Argument extraction and printing. * First we determine the argument type. * Then, we convert the argument to a string. * On exit from the switch, s points to the string that * must be printed, s_len has the length of the string * The precision requirements, if any, are reflected in s_len. * * NOTE: pad_char may be set to '0' because of the 0 flag. * It is reset to ' ' by non-numeric formats */ switch (*fmt) { case 'u': if (var_type == IS_QUAD) { i_quad = va_arg(ap, u_widest_int); s = conv_10_quad(i_quad, 1, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } else { if (var_type == IS_LONG) i_num = (wide_int) va_arg(ap, u_wide_int); else if (var_type == IS_SHORT) i_num = (wide_int) (unsigned short) va_arg(ap, unsigned int); else i_num = (wide_int) va_arg(ap, unsigned int); s = conv_10(i_num, 1, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } FIX_PRECISION(adjust_precision, precision, s, s_len); break; case 'd': case 'i': if (var_type == IS_QUAD) { i_quad = va_arg(ap, widest_int); s = conv_10_quad(i_quad, 0, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } else { if (var_type == IS_LONG) i_num = (wide_int) va_arg(ap, wide_int); else if (var_type == IS_SHORT) i_num = (wide_int) (short) va_arg(ap, int);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -