apr  1.7.0
About: APR (Apache Portable Runtime) project offers software libraries that provide a predictable and consistent interface to underlying platform-specific implementations (APR core library).
  Fossies Dox: apr-1.7.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

apr_snprintf.c
Go to the documentation of this file.
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements. See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "apr.h"
18 #include "apr_private.h"
19 
20 #include "apr_lib.h"
21 #include "apr_strings.h"
22 #include "apr_network_io.h"
23 #include "apr_portable.h"
24 #include "apr_errno.h"
25 #include <math.h>
26 #if APR_HAVE_CTYPE_H
27 #include <ctype.h>
28 #endif
29 #if APR_HAVE_NETINET_IN_H
30 #include <netinet/in.h>
31 #endif
32 #if APR_HAVE_SYS_SOCKET_H
33 #include <sys/socket.h>
34 #endif
35 #if APR_HAVE_ARPA_INET_H
36 #include <arpa/inet.h>
37 #endif
38 #if APR_HAVE_LIMITS_H
39 #include <limits.h>
40 #endif
41 #if APR_HAVE_STRING_H
42 #include <string.h>
43 #endif
44 
45 typedef enum {
46  NO = 0, YES = 1
47 } boolean_e;
48 
49 #ifndef FALSE
50 #define FALSE 0
51 #endif
52 #ifndef TRUE
53 #define TRUE 1
54 #endif
55 #define NUL '\0'
56 
57 static const char null_string[] = "(null)";
58 #define S_NULL ((char *)null_string)
59 #define S_NULL_LEN 6
60 
61 #define FLOAT_DIGITS 6
62 #define EXPONENT_LENGTH 10
63 
64 /*
65  * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
66  *
67  * NOTICE: this is a magic number; do not decrease it
68  */
69 #define NUM_BUF_SIZE 512
70 
71 /*
72  * cvt - IEEE floating point formatting routines.
73  * Derived from UNIX V7, Copyright(C) Caldera International Inc.
74  */
75 
76 /*
77  * apr_ecvt converts to decimal
78  * the number of digits is specified by ndigit
79  * decpt is set to the position of the decimal point
80  * sign is set to 0 for positive, 1 for negative
81  */
82 
83 #define NDIG 80
84 
85 /* buf must have at least NDIG bytes */
86 static char *apr_cvt(double arg, int ndigits, int *decpt, int *sign,
87  int eflag, char *buf)
88 {
89  register int r2;
90  double fi, fj;
91  register char *p, *p1;
92 
93  if (ndigits >= NDIG - 1)
94  ndigits = NDIG - 2;
95  r2 = 0;
96  *sign = 0;
97  p = &buf[0];
98  if (arg < 0) {
99  *sign = 1;
100  arg = -arg;
101  }
102  arg = modf(arg, &fi);
103  /*
104  * Do integer part
105  */
106  if (fi != 0) {
107  p1 = &buf[NDIG];
108  while (p1 > &buf[0] && fi != 0) {
109  fj = modf(fi / 10, &fi);
110  *--p1 = (int) ((fj + .03) * 10) + '0';
111  r2++;
112  }
113  while (p1 < &buf[NDIG])
114  *p++ = *p1++;
115  }
116  else if (arg > 0) {
117  while ((fj = arg * 10) < 1) {
118  arg = fj;
119  r2--;
120  }
121  }
122  p1 = &buf[ndigits];
123  if (eflag == 0)
124  p1 += r2;
125  if (p1 < &buf[0]) {
126  *decpt = -ndigits;
127  buf[0] = '\0';
128  return (buf);
129  }
130  *decpt = r2;
131  while (p <= p1 && p < &buf[NDIG]) {
132  arg *= 10;
133  arg = modf(arg, &fj);
134  *p++ = (int) fj + '0';
135  }
136  if (p1 >= &buf[NDIG]) {
137  buf[NDIG - 1] = '\0';
138  return (buf);
139  }
140  p = p1;
141  *p1 += 5;
142  while (*p1 > '9') {
143  *p1 = '0';
144  if (p1 > buf)
145  ++ * --p1;
146  else {
147  *p1 = '1';
148  (*decpt)++;
149  if (eflag == 0) {
150  if (p > buf)
151  *p = '0';
152  p++;
153  }
154  }
155  }
156  *p = '\0';
157  return (buf);
158 }
159 
160 static char *apr_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
161 {
162  return (apr_cvt(arg, ndigits, decpt, sign, 1, buf));
163 }
164 
165 static char *apr_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
166 {
167  return (apr_cvt(arg, ndigits, decpt, sign, 0, buf));
168 }
169 
170 /*
171  * apr_gcvt - Floating output conversion to
172  * minimal length string
173  */
174 
175 static char *apr_gcvt(double number, int ndigit, char *buf, boolean_e altform)
176 {
177  int sign, decpt;
178  register char *p1, *p2;
179  register int i;
180  char buf1[NDIG];
181 
182  p1 = apr_ecvt(number, ndigit, &decpt, &sign, buf1);
183  p2 = buf;
184  if (sign)
185  *p2++ = '-';
186  for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
187  ndigit--;
188  if ((decpt >= 0 && decpt - ndigit > 4)
189  || (decpt < 0 && decpt < -3)) { /* use E-style */
190  decpt--;
191  *p2++ = *p1++;
192  *p2++ = '.';
193  for (i = 1; i < ndigit; i++)
194  *p2++ = *p1++;
195  *p2++ = 'e';
196  if (decpt < 0) {
197  decpt = -decpt;
198  *p2++ = '-';
199  }
200  else
201  *p2++ = '+';
202  if (decpt / 100 > 0)
203  *p2++ = decpt / 100 + '0';
204  if (decpt / 10 > 0)
205  *p2++ = (decpt % 100) / 10 + '0';
206  *p2++ = decpt % 10 + '0';
207  }
208  else {
209  if (decpt <= 0) {
210  if (*p1 != '0')
211  *p2++ = '.';
212  while (decpt < 0) {
213  decpt++;
214  *p2++ = '0';
215  }
216  }
217  for (i = 1; i <= ndigit; i++) {
218  *p2++ = *p1++;
219  if (i == decpt)
220  *p2++ = '.';
221  }
222  if (ndigit < decpt) {
223  while (ndigit++ < decpt)
224  *p2++ = '0';
225  *p2++ = '.';
226  }
227  }
228  if (p2[-1] == '.' && !altform)
229  p2--;
230  *p2 = '\0';
231  return (buf);
232 }
233 
234 /*
235  * The INS_CHAR macro inserts a character in the buffer and writes
236  * the buffer back to disk if necessary
237  * It uses the char pointers sp and bep:
238  * sp points to the next available character in the buffer
239  * bep points to the end-of-buffer+1
240  * While using this macro, note that the nextb pointer is NOT updated.
241  *
242  * NOTE: Evaluation of the c argument should not have any side-effects
243  */
244 #define INS_CHAR(c, sp, bep, cc) \
245 { \
246  if (sp) { \
247  if (sp >= bep) { \
248  vbuff->curpos = sp; \
249  if (flush_func(vbuff)) \
250  return -1; \
251  sp = vbuff->curpos; \
252  bep = vbuff->endpos; \
253  } \
254  *sp++ = (c); \
255  } \
256  cc++; \
257 }
258 
259 #define NUM(c) (c - '0')
260 
261 #define STR_TO_DEC(str, num) \
262  num = NUM(*str++); \
263  while (apr_isdigit(*str)) \
264  { \
265  num *= 10 ; \
266  num += NUM(*str++); \
267  }
268 
269 /*
270  * This macro does zero padding so that the precision
271  * requirement is satisfied. The padding is done by
272  * adding '0's to the left of the string that is going
273  * to be printed. We don't allow precision to be large
274  * enough that we continue past the start of s.
275  *
276  * NOTE: this makes use of the magic info that s is
277  * always based on num_buf with a size of NUM_BUF_SIZE.
278  */
279 #define FIX_PRECISION(adjust, precision, s, s_len) \
280  if (adjust) { \
281  apr_size_t p = (precision + 1 < NUM_BUF_SIZE) \
282  ? precision : NUM_BUF_SIZE - 1; \
283  while (s_len < p) \
284  { \
285  *--s = '0'; \
286  s_len++; \
287  } \
288  }
289 
290 /*
291  * Macro that does padding. The padding is done by printing
292  * the character ch.
293  */
294 #define PAD(width, len, ch) \
295 do \
296 { \
297  INS_CHAR(ch, sp, bep, cc); \
298  width--; \
299 } \
300 while (width > len)
301 
302 /*
303  * Prefix the character ch to the string str
304  * Increase length
305  * Set the has_prefix flag
306  */
307 #define PREFIX(str, length, ch) \
308  *--str = ch; \
309  length++; \
310  has_prefix=YES;
311 
312 
313 /*
314  * Convert num to its decimal format.
315  * Return value:
316  * - a pointer to a string containing the number (no sign)
317  * - len contains the length of the string
318  * - is_negative is set to TRUE or FALSE depending on the sign
319  * of the number (always set to FALSE if is_unsigned is TRUE)
320  *
321  * The caller provides a buffer for the string: that is the buf_end argument
322  * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
323  * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
324  *
325  * Note: we have 2 versions. One is used when we need to use quads
326  * (conv_10_quad), the other when we don't (conv_10). We're assuming the
327  * latter is faster.
328  */
329 static char *conv_10(register apr_int32_t num, register int is_unsigned,
330  register int *is_negative, char *buf_end,
331  register apr_size_t *len)
332 {
333  register char *p = buf_end;
334  register apr_uint32_t magnitude = num;
335 
336  if (is_unsigned) {
337  *is_negative = FALSE;
338  }
339  else {
340  *is_negative = (num < 0);
341 
342  /*
343  * On a 2's complement machine, negating the most negative integer
344  * results in a number that cannot be represented as a signed integer.
345  * Here is what we do to obtain the number's magnitude:
346  * a. add 1 to the number
347  * b. negate it (becomes positive)
348  * c. convert it to unsigned
349  * d. add 1
350  */
351  if (*is_negative) {
352  apr_int32_t t = num + 1;
353  magnitude = ((apr_uint32_t) -t) + 1;
354  }
355  }
356 
357  /*
358  * We use a do-while loop so that we write at least 1 digit
359  */
360  do {
361  register apr_uint32_t new_magnitude = magnitude / 10;
362 
363  *--p = (char) (magnitude - new_magnitude * 10 + '0');
364  magnitude = new_magnitude;
365  }
366  while (magnitude);
367 
368  *len = buf_end - p;
369  return (p);
370 }
371 
372 static char *conv_10_quad(apr_int64_t num, register int is_unsigned,
373  register int *is_negative, char *buf_end,
374  register apr_size_t *len)
375 {
376  register char *p = buf_end;
377  apr_uint64_t magnitude = num;
378 
379  /*
380  * We see if we can use the faster non-quad version by checking the
381  * number against the largest long value it can be. If <=, we
382  * punt to the quicker version.
383  */
384  if ((magnitude <= APR_UINT32_MAX && is_unsigned)
385  || (num <= APR_INT32_MAX && num >= APR_INT32_MIN && !is_unsigned))
386  return(conv_10((apr_int32_t)num, is_unsigned, is_negative, buf_end, len));
387 
388  if (is_unsigned) {
389  *is_negative = FALSE;
390  }
391  else {
392  *is_negative = (num < 0);
393 
394  /*
395  * On a 2's complement machine, negating the most negative integer
396  * results in a number that cannot be represented as a signed integer.
397  * Here is what we do to obtain the number's magnitude:
398  * a. add 1 to the number
399  * b. negate it (becomes positive)
400  * c. convert it to unsigned
401  * d. add 1
402  */
403  if (*is_negative) {
404  apr_int64_t t = num + 1;
405  magnitude = ((apr_uint64_t) -t) + 1;
406  }
407  }
408 
409  /*
410  * We use a do-while loop so that we write at least 1 digit
411  */
412  do {
413  apr_uint64_t new_magnitude = magnitude / 10;
414 
415  *--p = (char) (magnitude - new_magnitude * 10 + '0');
416  magnitude = new_magnitude;
417  }
418  while (magnitude);
419 
420  *len = buf_end - p;
421  return (p);
422 }
423 
424 static char *conv_in_addr(struct in_addr *ia, char *buf_end, apr_size_t *len)
425 {
426  unsigned addr = ntohl(ia->s_addr);
427  char *p = buf_end;
428  int is_negative;
429  apr_size_t sub_len;
430 
431  p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len);
432  *--p = '.';
433  p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len);
434  *--p = '.';
435  p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len);
436  *--p = '.';
437  p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len);
438 
439  *len = buf_end - p;
440  return (p);
441 }
442 
443 
444 /* Must be passed a buffer of size NUM_BUF_SIZE where buf_end points
445  * to 1 byte past the end of the buffer. */
446 static char *conv_apr_sockaddr(apr_sockaddr_t *sa, char *buf_end, apr_size_t *len)
447 {
448  char *p = buf_end;
449  int is_negative;
450  apr_size_t sub_len;
451  char *ipaddr_str;
452 
453  p = conv_10(sa->port, TRUE, &is_negative, p, &sub_len);
454  *--p = ':';
455  ipaddr_str = buf_end - NUM_BUF_SIZE;
456  if (apr_sockaddr_ip_getbuf(ipaddr_str, sa->addr_str_len, sa)) {
457  /* Should only fail if the buffer is too small, which it
458  * should not be; but fail safe anyway: */
459  *--p = '?';
460  *len = buf_end - p;
461  return p;
462  }
463  sub_len = strlen(ipaddr_str);
464 #if APR_HAVE_IPV6
465  if (sa->family == APR_INET6 &&
466  !IN6_IS_ADDR_V4MAPPED(&sa->sa.sin6.sin6_addr)) {
467  *(p - 1) = ']';
468  p -= sub_len + 2;
469  *p = '[';
470  memcpy(p + 1, ipaddr_str, sub_len);
471  }
472  else
473 #endif
474  {
475  p -= sub_len;
476  memcpy(p, ipaddr_str, sub_len);
477  }
478 
479  *len = buf_end - p;
480  return (p);
481 }
482 
483 
484 
485 #if APR_HAS_THREADS
486 static char *conv_os_thread_t(apr_os_thread_t *tid, char *buf_end, apr_size_t *len)
487 {
488  union {
489  apr_os_thread_t tid;
490  apr_uint64_t u64;
491  apr_uint32_t u32;
492  } u;
493  int is_negative;
494 
495  u.tid = *tid;
496  switch(sizeof(u.tid)) {
497  case sizeof(apr_int32_t):
498  return conv_10(u.u32, TRUE, &is_negative, buf_end, len);
499  case sizeof(apr_int64_t):
500  return conv_10_quad(u.u64, TRUE, &is_negative, buf_end, len);
501  default:
502  /* not implemented; stick 0 in the buffer */
503  return conv_10(0, TRUE, &is_negative, buf_end, len);
504  }
505 }
506 #endif
507 
508 
509 
510 /*
511  * Convert a floating point number to a string formats 'f', 'e' or 'E'.
512  * The result is placed in buf, and len denotes the length of the string
513  * The sign is returned in the is_negative argument (and is not placed
514  * in buf).
515  */
516 static char *conv_fp(register char format, register double num,
517  boolean_e add_dp, int precision, int *is_negative,
518  char *buf, apr_size_t *len)
519 {
520  register char *s = buf;
521  register char *p;
522  int decimal_point;
523  char buf1[NDIG];
524 
525  if (format == 'f')
526  p = apr_fcvt(num, precision, &decimal_point, is_negative, buf1);
527  else /* either e or E format */
528  p = apr_ecvt(num, precision + 1, &decimal_point, is_negative, buf1);
529 
530  /*
531  * Check for Infinity and NaN
532  */
533  if (apr_isalpha(*p)) {
534  *len = strlen(p);
535  memcpy(buf, p, *len + 1);
536  *is_negative = FALSE;
537  return (buf);
538  }
539 
540  if (format == 'f') {
541  if (decimal_point <= 0) {
542  *s++ = '0';
543  if (precision > 0) {
544  *s++ = '.';
545  while (decimal_point++ < 0)
546  *s++ = '0';
547  }
548  else if (add_dp)
549  *s++ = '.';
550  }
551  else {
552  while (decimal_point-- > 0)
553  *s++ = *p++;
554  if (precision > 0 || add_dp)
555  *s++ = '.';
556  }
557  }
558  else {
559  *s++ = *p++;
560  if (precision > 0 || add_dp)
561  *s++ = '.';
562  }
563 
564  /*
565  * copy the rest of p, the NUL is NOT copied
566  */
567  while (*p)
568  *s++ = *p++;
569 
570  if (format != 'f') {
571  char temp[EXPONENT_LENGTH]; /* for exponent conversion */
572  apr_size_t t_len;
573  int exponent_is_negative;
574 
575  *s++ = format; /* either e or E */
576  decimal_point--;
577  if (decimal_point != 0) {
578  p = conv_10((apr_int32_t) decimal_point, FALSE, &exponent_is_negative,
579  &temp[EXPONENT_LENGTH], &t_len);
580  *s++ = exponent_is_negative ? '-' : '+';
581 
582  /*
583  * Make sure the exponent has at least 2 digits
584  */
585  if (t_len == 1)
586  *s++ = '0';
587  while (t_len--)
588  *s++ = *p++;
589  }
590  else {
591  *s++ = '+';
592  *s++ = '0';
593  *s++ = '0';
594  }
595  }
596 
597  *len = s - buf;
598  return (buf);
599 }
600 
601 
602 /*
603  * Convert num to a base X number where X is a power of 2. nbits determines X.
604  * For example, if nbits is 3, we do base 8 conversion
605  * Return value:
606  * a pointer to a string containing the number
607  *
608  * The caller provides a buffer for the string: that is the buf_end argument
609  * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
610  * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
611  *
612  * As with conv_10, we have a faster version which is used when
613  * the number isn't quad size.
614  */
615 static char *conv_p2(register apr_uint32_t num, register int nbits,
616  char format, char *buf_end, register apr_size_t *len)
617 {
618  register int mask = (1 << nbits) - 1;
619  register char *p = buf_end;
620  static const char low_digits[] = "0123456789abcdef";
621  static const char upper_digits[] = "0123456789ABCDEF";
622  register const char *digits = (format == 'X') ? upper_digits : low_digits;
623 
624  do {
625  *--p = digits[num & mask];
626  num >>= nbits;
627  }
628  while (num);
629 
630  *len = buf_end - p;
631  return (p);
632 }
633 
634 static char *conv_p2_quad(apr_uint64_t num, register int nbits,
635  char format, char *buf_end, register apr_size_t *len)
636 {
637  register int mask = (1 << nbits) - 1;
638  register char *p = buf_end;
639  static const char low_digits[] = "0123456789abcdef";
640  static const char upper_digits[] = "0123456789ABCDEF";
641  register const char *digits = (format == 'X') ? upper_digits : low_digits;
642 
643  if (num <= APR_UINT32_MAX)
644  return(conv_p2((apr_uint32_t)num, nbits, format, buf_end, len));
645 
646  do {
647  *--p = digits[num & mask];
648  num >>= nbits;
649  }
650  while (num);
651 
652  *len = buf_end - p;
653  return (p);
654 }
655 
656 #if APR_HAS_THREADS
657 static char *conv_os_thread_t_hex(apr_os_thread_t *tid, char *buf_end, apr_size_t *len)
658 {
659  union {
660  apr_os_thread_t tid;
661  apr_uint64_t u64;
662  apr_uint32_t u32;
663  } u;
664  int is_negative;
665 
666  u.tid = *tid;
667  switch(sizeof(u.tid)) {
668  case sizeof(apr_int32_t):
669  return conv_p2(u.u32, 4, 'x', buf_end, len);
670  case sizeof(apr_int64_t):
671  return conv_p2_quad(u.u64, 4, 'x', buf_end, len);
672  default:
673  /* not implemented; stick 0 in the buffer */
674  return conv_10(0, TRUE, &is_negative, buf_end, len);
675  }
676 }
677 #endif
678 
679 /*
680  * Do format conversion placing the output in buffer
681  */
682 APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *),
683  apr_vformatter_buff_t *vbuff, const char *fmt, va_list ap)
684 {
685  register char *sp;
686  register char *bep;
687  register int cc = 0;
688  register apr_size_t i;
689 
690  register char *s = NULL;
691  char *q;
692  apr_size_t s_len = 0;
693 
694  register apr_size_t min_width = 0;
695  apr_size_t precision = 0;
696  enum {
697  LEFT, RIGHT
698  } adjust;
699  char pad_char;
700  char prefix_char;
701 
702  double fp_num;
703  apr_int64_t i_quad = 0;
704  apr_uint64_t ui_quad;
705  apr_int32_t i_num = 0;
706  apr_uint32_t ui_num = 0;
707 
708  char num_buf[NUM_BUF_SIZE];
709  char char_buf[2]; /* for printing %% and %<unknown> */
710 
711  enum var_type_enum {
712  IS_QUAD, IS_LONG, IS_SHORT, IS_INT
713  };
714  enum var_type_enum var_type = IS_INT;
715 
716  /*
717  * Flag variables
718  */
719  boolean_e alternate_form;
720  boolean_e print_sign;
721  boolean_e print_blank;
722  boolean_e adjust_precision;
723  boolean_e adjust_width;
724  int is_negative;
725 
726  sp = vbuff->curpos;
727  bep = vbuff->endpos;
728 
729  while (*fmt) {
730  if (*fmt != '%') {
731  INS_CHAR(*fmt, sp, bep, cc);
732  }
733  else {
734  /*
735  * Default variable settings
736  */
737  boolean_e print_something = YES;
738  adjust = RIGHT;
739  alternate_form = print_sign = print_blank = NO;
740  pad_char = ' ';
741  prefix_char = NUL;
742 
743  fmt++;
744 
745  /*
746  * Try to avoid checking for flags, width or precision
747  */
748  if (!apr_islower(*fmt)) {
749  /*
750  * Recognize flags: -, #, BLANK, +
751  */
752  for (;; fmt++) {
753  if (*fmt == '-')
754  adjust = LEFT;
755  else if (*fmt == '+')
756  print_sign = YES;
757  else if (*fmt == '#')
758  alternate_form = YES;
759  else if (*fmt == ' ')
760  print_blank = YES;
761  else if (*fmt == '0')
762  pad_char = '0';
763  else
764  break;
765  }
766 
767  /*
768  * Check if a width was specified
769  */
770  if (apr_isdigit(*fmt)) {
771  STR_TO_DEC(fmt, min_width);
772  adjust_width = YES;
773  }
774  else if (*fmt == '*') {
775  int v = va_arg(ap, int);
776  fmt++;
777  adjust_width = YES;
778  if (v < 0) {
779  adjust = LEFT;
780  min_width = (apr_size_t)(-v);
781  }
782  else
783  min_width = (apr_size_t)v;
784  }
785  else
786  adjust_width = NO;
787 
788  /*
789  * Check if a precision was specified
790  */
791  if (*fmt == '.') {
792  adjust_precision = YES;
793  fmt++;
794  if (apr_isdigit(*fmt)) {
795  STR_TO_DEC(fmt, precision);
796  }
797  else if (*fmt == '*') {
798  int v = va_arg(ap, int);
799  fmt++;
800  precision = (v < 0) ? 0 : (apr_size_t)v;
801  }
802  else
803  precision = 0;
804  }
805  else
806  adjust_precision = NO;
807  }
808  else
809  adjust_precision = adjust_width = NO;
810 
811  /*
812  * Modifier check. In same cases, APR_OFF_T_FMT can be
813  * "lld" and APR_INT64_T_FMT can be "ld" (that is, off_t is
814  * "larger" than int64). Check that case 1st.
815  * Note that if APR_OFF_T_FMT is "d",
816  * the first if condition is never true. If APR_INT64_T_FMT
817  * is "d' then the second if condition is never true.
818  */
819  if ((sizeof(APR_OFF_T_FMT) > sizeof(APR_INT64_T_FMT)) &&
820  ((sizeof(APR_OFF_T_FMT) == 4 &&
821  fmt[0] == APR_OFF_T_FMT[0] &&
822  fmt[1] == APR_OFF_T_FMT[1]) ||
823  (sizeof(APR_OFF_T_FMT) == 3 &&
824  fmt[0] == APR_OFF_T_FMT[0]) ||
825  (sizeof(APR_OFF_T_FMT) > 4 &&
826  strncmp(fmt, APR_OFF_T_FMT,
827  sizeof(APR_OFF_T_FMT) - 2) == 0))) {
828  /* Need to account for trailing 'd' and null in sizeof() */
829  var_type = IS_QUAD;
830  fmt += (sizeof(APR_OFF_T_FMT) - 2);
831  }
832  else if ((sizeof(APR_INT64_T_FMT) == 4 &&
833  fmt[0] == APR_INT64_T_FMT[0] &&
834  fmt[1] == APR_INT64_T_FMT[1]) ||
835  (sizeof(APR_INT64_T_FMT) == 3 &&
836  fmt[0] == APR_INT64_T_FMT[0]) ||
837  (sizeof(APR_INT64_T_FMT) > 4 &&
838  strncmp(fmt, APR_INT64_T_FMT,
839  sizeof(APR_INT64_T_FMT) - 2) == 0)) {
840  /* Need to account for trailing 'd' and null in sizeof() */
841  var_type = IS_QUAD;
842  fmt += (sizeof(APR_INT64_T_FMT) - 2);
843  }
844  else if (*fmt == 'q') {
845  var_type = IS_QUAD;
846  fmt++;
847  }
848  else if (*fmt == 'l') {
849  var_type = IS_LONG;
850  fmt++;
851  }
852  else if (*fmt == 'h') {
853  var_type = IS_SHORT;
854  fmt++;
855  }
856  else {
857  var_type = IS_INT;
858  }
859 
860  /*
861  * Argument extraction and printing.
862  * First we determine the argument type.
863  * Then, we convert the argument to a string.
864  * On exit from the switch, s points to the string that
865  * must be printed, s_len has the length of the string
866  * The precision requirements, if any, are reflected in s_len.
867  *
868  * NOTE: pad_char may be set to '0' because of the 0 flag.
869  * It is reset to ' ' by non-numeric formats
870  */
871  switch (*fmt) {
872  case 'u':
873  if (var_type == IS_QUAD) {
874  i_quad = va_arg(ap, apr_uint64_t);
875  s = conv_10_quad(i_quad, 1, &is_negative,
876  &num_buf[NUM_BUF_SIZE], &s_len);
877  }
878  else {
879  if (var_type == IS_LONG)
880  i_num = (apr_int32_t) va_arg(ap, apr_uint32_t);
881  else if (var_type == IS_SHORT)
882  i_num = (apr_int32_t) (unsigned short) va_arg(ap, unsigned int);
883  else
884  i_num = (apr_int32_t) va_arg(ap, unsigned int);
885  s = conv_10(i_num, 1, &is_negative,
886  &num_buf[NUM_BUF_SIZE], &s_len);
887  }
888  FIX_PRECISION(adjust_precision, precision, s, s_len);
889  break;
890 
891  case 'd':
892  case 'i':
893  if (var_type == IS_QUAD) {
894  i_quad = va_arg(ap, apr_int64_t);
895  s = conv_10_quad(i_quad, 0, &is_negative,
896  &num_buf[NUM_BUF_SIZE], &s_len);
897  }
898  else {
899  if (var_type == IS_LONG)
900  i_num = va_arg(ap, apr_int32_t);
901  else if (var_type == IS_SHORT)
902  i_num = (short) va_arg(ap, int);
903  else
904  i_num = va_arg(ap, int);
905  s = conv_10(i_num, 0, &is_negative,
906  &num_buf[NUM_BUF_SIZE], &s_len);
907  }
908  FIX_PRECISION(adjust_precision, precision, s, s_len);
909 
910  if (is_negative)
911  prefix_char = '-';
912  else if (print_sign)
913  prefix_char = '+';
914  else if (print_blank)
915  prefix_char = ' ';
916  break;
917 
918 
919  case 'o':
920  if (var_type == IS_QUAD) {
921  ui_quad = va_arg(ap, apr_uint64_t);
922  s = conv_p2_quad(ui_quad, 3, *fmt,
923  &num_buf[NUM_BUF_SIZE], &s_len);
924  }
925  else {
926  if (var_type == IS_LONG)
927  ui_num = va_arg(ap, apr_uint32_t);
928  else if (var_type == IS_SHORT)
929  ui_num = (unsigned short) va_arg(ap, unsigned int);
930  else
931  ui_num = va_arg(ap, unsigned int);
932  s = conv_p2(ui_num, 3, *fmt,
933  &num_buf[NUM_BUF_SIZE], &s_len);
934  }
935  FIX_PRECISION(adjust_precision, precision, s, s_len);
936  if (alternate_form && *s != '0') {
937  *--s = '0';
938  s_len++;
939  }
940  break;
941 
942 
943  case 'x':
944  case 'X':
945  if (var_type == IS_QUAD) {
946  ui_quad = va_arg(ap, apr_uint64_t);
947  s = conv_p2_quad(ui_quad, 4, *fmt,
948  &num_buf[NUM_BUF_SIZE], &s_len);
949  }
950  else {
951  if (var_type == IS_LONG)
952  ui_num = va_arg(ap, apr_uint32_t);
953  else if (var_type == IS_SHORT)
954  ui_num = (unsigned short) va_arg(ap, unsigned int);
955  else
956  ui_num = va_arg(ap, unsigned int);
957  s = conv_p2(ui_num, 4, *fmt,
958  &num_buf[NUM_BUF_SIZE], &s_len);
959  }
960  FIX_PRECISION(adjust_precision, precision, s, s_len);
961  if (alternate_form && ui_num != 0) {
962  *--s = *fmt; /* 'x' or 'X' */
963  *--s = '0';
964  s_len += 2;
965  }
966  break;
967 
968 
969  case 's':
970  s = va_arg(ap, char *);
971  if (s != NULL) {
972  if (!adjust_precision) {
973  s_len = strlen(s);
974  }
975  else {
976  /* From the C library standard in section 7.9.6.1:
977  * ...if the precision is specified, no more then
978  * that many characters are written. If the
979  * precision is not specified or is greater
980  * than the size of the array, the array shall
981  * contain a null character.
982  *
983  * My reading is is precision is specified and
984  * is less then or equal to the size of the
985  * array, no null character is required. So
986  * we can't do a strlen.
987  *
988  * This figures out the length of the string
989  * up to the precision. Once it's long enough
990  * for the specified precision, we don't care
991  * anymore.
992  *
993  * NOTE: you must do the length comparison
994  * before the check for the null character.
995  * Otherwise, you'll check one beyond the
996  * last valid character.
997  */
998  const char *walk;
999 
1000  for (walk = s, s_len = 0;
1001  (s_len < precision) && (*walk != '\0');
1002  ++walk, ++s_len);
1003  }
1004  }
1005  else {
1006  s = S_NULL;
1007  s_len = S_NULL_LEN;
1008  }
1009  pad_char = ' ';
1010  break;
1011 
1012 
1013  case 'f':
1014  case 'e':
1015  case 'E':
1016  fp_num = va_arg(ap, double);
1017  /*
1018  * We use &num_buf[ 1 ], so that we have room for the sign
1019  */
1020  s = NULL;
1021 #ifdef HAVE_ISNAN
1022  if (isnan(fp_num)) {
1023  s = "nan";
1024  s_len = 3;
1025  }
1026 #endif
1027 #ifdef HAVE_ISINF
1028  if (!s && isinf(fp_num)) {
1029  s = "inf";
1030  s_len = 3;
1031  }
1032 #endif
1033  if (!s) {
1034  s = conv_fp(*fmt, fp_num, alternate_form,
1035  (int)((adjust_precision == NO) ? FLOAT_DIGITS : precision),
1036  &is_negative, &num_buf[1], &s_len);
1037  if (is_negative)
1038  prefix_char = '-';
1039  else if (print_sign)
1040  prefix_char = '+';
1041  else if (print_blank)
1042  prefix_char = ' ';
1043  }
1044  break;
1045 
1046 
1047  case 'g':
1048  case 'G':
1049  if (adjust_precision == NO)
1050  precision = FLOAT_DIGITS;
1051  else if (precision == 0)
1052  precision = 1;
1053  /*
1054  * * We use &num_buf[ 1 ], so that we have room for the sign
1055  */
1056  s = apr_gcvt(va_arg(ap, double), (int) precision, &num_buf[1],
1057  alternate_form);
1058  if (*s == '-')
1059  prefix_char = *s++;
1060  else if (print_sign)
1061  prefix_char = '+';
1062  else if (print_blank)
1063  prefix_char = ' ';
1064 
1065  s_len = strlen(s);
1066 
1067  if (alternate_form && (q = strchr(s, '.')) == NULL) {
1068  s[s_len++] = '.';
1069  s[s_len] = '\0'; /* delimit for following strchr() */
1070  }
1071  if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
1072  *q = 'E';
1073  break;
1074 
1075 
1076  case 'c':
1077  char_buf[0] = (char) (va_arg(ap, int));
1078  s = &char_buf[0];
1079  s_len = 1;
1080  pad_char = ' ';
1081  break;
1082 
1083 
1084  case '%':
1085  char_buf[0] = '%';
1086  s = &char_buf[0];
1087  s_len = 1;
1088  pad_char = ' ';
1089  break;
1090 
1091 
1092  case 'n':
1093  if (var_type == IS_QUAD)
1094  *(va_arg(ap, apr_int64_t *)) = cc;
1095  else if (var_type == IS_LONG)
1096  *(va_arg(ap, long *)) = cc;
1097  else if (var_type == IS_SHORT)
1098  *(va_arg(ap, short *)) = cc;
1099  else
1100  *(va_arg(ap, int *)) = cc;
1101  print_something = NO;
1102  break;
1103 
1104  /*
1105  * This is where we extend the printf format, with a second
1106  * type specifier
1107  */
1108  case 'p':
1109  switch(*++fmt) {
1110  /*
1111  * If the pointer size is equal to or smaller than the size
1112  * of the largest unsigned int, we convert the pointer to a
1113  * hex number, otherwise we print "%p" to indicate that we
1114  * don't handle "%p".
1115  */
1116  case 'p':
1117 #if APR_SIZEOF_VOIDP == 8
1118  if (sizeof(void *) <= sizeof(apr_uint64_t)) {
1119  ui_quad = (apr_uint64_t) va_arg(ap, void *);
1120  s = conv_p2_quad(ui_quad, 4, 'x',
1121  &num_buf[NUM_BUF_SIZE], &s_len);
1122  }
1123 #else
1124  if (sizeof(void *) <= sizeof(apr_uint32_t)) {
1125  ui_num = (apr_uint32_t) va_arg(ap, void *);
1126  s = conv_p2(ui_num, 4, 'x',
1127  &num_buf[NUM_BUF_SIZE], &s_len);
1128  }
1129 #endif
1130  else {
1131  s = "%p";
1132  s_len = 2;
1133  prefix_char = NUL;
1134  }
1135  pad_char = ' ';
1136  break;
1137 
1138  /* print an apr_sockaddr_t as a.b.c.d:port */
1139  case 'I':
1140  {
1141  apr_sockaddr_t *sa;
1142 
1143  sa = va_arg(ap, apr_sockaddr_t *);
1144  if (sa != NULL) {
1145  s = conv_apr_sockaddr(sa, &num_buf[NUM_BUF_SIZE], &s_len);
1146  if (adjust_precision && precision < s_len)
1147  s_len = precision;
1148  }
1149  else {
1150  s = S_NULL;
1151  s_len = S_NULL_LEN;
1152  }
1153  pad_char = ' ';
1154  }
1155  break;
1156 
1157  /* print a struct in_addr as a.b.c.d */
1158  case 'A':
1159  {
1160  struct in_addr *ia;
1161 
1162  ia = va_arg(ap, struct in_addr *);
1163  if (ia != NULL) {
1164  s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len);
1165  if (adjust_precision && precision < s_len)
1166  s_len = precision;
1167  }
1168  else {
1169  s = S_NULL;
1170  s_len = S_NULL_LEN;
1171  }
1172  pad_char = ' ';
1173  }
1174  break;
1175 
1176  /* print the error for an apr_status_t */
1177  case 'm':
1178  {
1179  apr_status_t *mrv;
1180 
1181  mrv = va_arg(ap, apr_status_t *);
1182  if (mrv != NULL) {
1183  s = apr_strerror(*mrv, num_buf, NUM_BUF_SIZE-1);
1184  s_len = strlen(s);
1185  }
1186  else {
1187  s = S_NULL;
1188  s_len = S_NULL_LEN;
1189  }
1190  pad_char = ' ';
1191  }
1192  break;
1193 
1194  case 'T':
1195 #if APR_HAS_THREADS
1196  {
1197  apr_os_thread_t *tid;
1198 
1199  tid = va_arg(ap, apr_os_thread_t *);
1200  if (tid != NULL) {
1201  s = conv_os_thread_t(tid, &num_buf[NUM_BUF_SIZE], &s_len);
1202  if (adjust_precision && precision < s_len)
1203  s_len = precision;
1204  }
1205  else {
1206  s = S_NULL;
1207  s_len = S_NULL_LEN;
1208  }
1209  pad_char = ' ';
1210  }
1211 #else
1212  char_buf[0] = '0';
1213  s = &char_buf[0];
1214  s_len = 1;
1215  pad_char = ' ';
1216 #endif
1217  break;
1218 
1219  case 't':
1220 #if APR_HAS_THREADS
1221  {
1222  apr_os_thread_t *tid;
1223 
1224  tid = va_arg(ap, apr_os_thread_t *);
1225  if (tid != NULL) {
1226  s = conv_os_thread_t_hex(tid, &num_buf[NUM_BUF_SIZE], &s_len);
1227  if (adjust_precision && precision < s_len)
1228  s_len = precision;
1229  }
1230  else {
1231  s = S_NULL;
1232  s_len = S_NULL_LEN;
1233  }
1234  pad_char = ' ';
1235  }
1236 #else
1237  char_buf[0] = '0';
1238  s = &char_buf[0];
1239  s_len = 1;
1240  pad_char = ' ';
1241 #endif
1242  break;
1243 
1244  case 'B':
1245  case 'F':
1246  case 'S':
1247  {
1248  char buf[5];
1249  apr_off_t size = 0;
1250 
1251  if (*fmt == 'B') {
1252  apr_uint32_t *arg = va_arg(ap, apr_uint32_t *);
1253  size = (arg) ? *arg : 0;
1254  }
1255  else if (*fmt == 'F') {
1256  apr_off_t *arg = va_arg(ap, apr_off_t *);
1257  size = (arg) ? *arg : 0;
1258  }
1259  else {
1260  apr_size_t *arg = va_arg(ap, apr_size_t *);
1261  size = (arg) ? *arg : 0;
1262  }
1263 
1264  s = apr_strfsize(size, buf);
1265  s_len = strlen(s);
1266  pad_char = ' ';
1267  }
1268  break;
1269 
1270  case NUL:
1271  /* if %p ends the string, oh well ignore it */
1272  continue;
1273 
1274  default:
1275  s = "bogus %p";
1276  s_len = 8;
1277  prefix_char = NUL;
1278  (void)va_arg(ap, void *); /* skip the bogus argument on the stack */
1279  break;
1280  }
1281  break;
1282 
1283  case NUL:
1284  /*
1285  * The last character of the format string was %.
1286  * We ignore it.
1287  */
1288  continue;
1289 
1290 
1291  /*
1292  * The default case is for unrecognized %'s.
1293  * We print %<char> to help the user identify what
1294  * option is not understood.
1295  * This is also useful in case the user wants to pass
1296  * the output of format_converter to another function
1297  * that understands some other %<char> (like syslog).
1298  * Note that we can't point s inside fmt because the
1299  * unknown <char> could be preceded by width etc.
1300  */
1301  default:
1302  char_buf[0] = '%';
1303  char_buf[1] = *fmt;
1304  s = char_buf;
1305  s_len = 2;
1306  pad_char = ' ';
1307  break;
1308  }
1309 
1310  if (prefix_char != NUL && s != S_NULL && s != char_buf) {
1311  *--s = prefix_char;
1312  s_len++;
1313  }
1314 
1315  if (adjust_width && adjust == RIGHT && min_width > s_len) {
1316  if (pad_char == '0' && prefix_char != NUL) {
1317  INS_CHAR(*s, sp, bep, cc);
1318  s++;
1319  s_len--;
1320  min_width--;
1321  }
1322  PAD(min_width, s_len, pad_char);
1323  }
1324 
1325  /*
1326  * Print the string s.
1327  */
1328  if (print_something == YES) {
1329  for (i = s_len; i != 0; i--) {
1330  INS_CHAR(*s, sp, bep, cc);
1331  s++;
1332  }
1333  }
1334 
1335  if (adjust_width && adjust == LEFT && min_width > s_len)
1336  PAD(min_width, s_len, pad_char);
1337  }
1338  fmt++;
1339  }
1340  vbuff->curpos = sp;
1341 
1342  return cc;
1343 }
1344 
1345 
1347 {
1348  /* if the buffer fills we have to abort immediately, there is no way
1349  * to "flush" an apr_snprintf... there's nowhere to flush it to.
1350  */
1351  return -1;
1352 }
1353 
1354 
1355 APR_DECLARE_NONSTD(int) apr_snprintf(char *buf, apr_size_t len,
1356  const char *format, ...)
1357 {
1358  int cc;
1359  va_list ap;
1360  apr_vformatter_buff_t vbuff;
1361 
1362  if (len == 0) {
1363  /* NOTE: This is a special case; we just want to return the number
1364  * of chars that would be written (minus \0) if the buffer
1365  * size was infinite. We leverage the fact that INS_CHAR
1366  * just does actual inserts iff the buffer pointer is non-NULL.
1367  * In this case, we don't care what buf is; it can be NULL, since
1368  * we don't touch it at all.
1369  */
1370  vbuff.curpos = NULL;
1371  vbuff.endpos = NULL;
1372  } else {
1373  /* save one byte for nul terminator */
1374  vbuff.curpos = buf;
1375  vbuff.endpos = buf + len - 1;
1376  }
1377  va_start(ap, format);
1378  cc = apr_vformatter(snprintf_flush, &vbuff, format, ap);
1379  va_end(ap);
1380  if (len != 0) {
1381  *vbuff.curpos = '\0';
1382  }
1383  return (cc == -1) ? (int)len - 1 : cc;
1384 }
1385 
1386 
1387 APR_DECLARE(int) apr_vsnprintf(char *buf, apr_size_t len, const char *format,
1388  va_list ap)
1389 {
1390  int cc;
1391  apr_vformatter_buff_t vbuff;
1392 
1393  if (len == 0) {
1394  /* See above note */
1395  vbuff.curpos = NULL;
1396  vbuff.endpos = NULL;
1397  } else {
1398  /* save one byte for nul terminator */
1399  vbuff.curpos = buf;
1400  vbuff.endpos = buf + len - 1;
1401  }
1402  cc = apr_vformatter(snprintf_flush, &vbuff, format, ap);
1403  if (len != 0) {
1404  *vbuff.curpos = '\0';
1405  }
1406  return (cc == -1) ? (int)len - 1 : cc;
1407 }
NO
Definition: apr_snprintf.c:46
FIX_PRECISION
#define FIX_PRECISION(adjust, precision, s, s_len)
Definition: apr_snprintf.c:279
t
apr_interval_time_t t
Definition: apr_network_io.h:735
apr_errno.h
APR Error Codes.
conv_in_addr
static char * conv_in_addr(struct in_addr *ia, char *buf_end, apr_size_t *len)
Definition: apr_snprintf.c:424
conv_p2
static char * conv_p2(register apr_uint32_t num, register int nbits, char format, char *buf_end, register apr_size_t *len)
Definition: apr_snprintf.c:615
apr_isdigit
#define apr_isdigit(c)
Definition: apr_lib.h:209
NDIG
#define NDIG
Definition: apr_snprintf.c:83
p
const char apr_int32_t apr_pool_t * p
Definition: apr_file_info.h:337
apr_strings.h
APR Strings library.
conv_10
static char * conv_10(register apr_int32_t num, register int is_unsigned, register int *is_negative, char *buf_end, register apr_size_t *len)
Definition: apr_snprintf.c:329
S_NULL
#define S_NULL
Definition: apr_snprintf.c:58
apr_portable.h
APR Portability Routines.
conv_fp
static char * conv_fp(register char format, register double num, boolean_e add_dp, int precision, int *is_negative, char *buf, apr_size_t *len)
Definition: apr_snprintf.c:516
apr_sockaddr_t::family
apr_int32_t family
Definition: apr_network_io.h:276
APR_DECLARE
APR_DECLARE(int)
Definition: apr_snprintf.c:682
S_NULL_LEN
#define S_NULL_LEN
Definition: apr_snprintf.c:59
apr_vformatter_buff_t
Definition: apr_lib.h:64
snprintf_flush
static int snprintf_flush(apr_vformatter_buff_t *vbuff)
Definition: apr_snprintf.c:1346
ap
apr_vformatter_buff_t const char va_list ap
Definition: apr_lib.h:175
in_addr::s_addr
apr_uint32_t s_addr
Definition: apr_network_io.h:157
apr_sockaddr_t::addr_str_len
int addr_str_len
Definition: apr_network_io.h:283
apr_fcvt
static char * apr_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
Definition: apr_snprintf.c:165
len
const char apr_ssize_t int apr_size_t * len
Definition: apr_encode.h:162
in_addr
Definition: apr_network_io.h:156
apr_network_io.h
APR Network library.
format
const char * format
Definition: apr_file_io.h:873
null_string
static const char null_string[]
Definition: apr_snprintf.c:57
buf
char * buf
Definition: apr_errno.h:52
apr_isalpha
#define apr_isalpha(c)
Definition: apr_lib.h:205
size
apr_size_t size
Definition: apr_allocator.h:115
apr_lib.h
APR general purpose library routines.
int
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray
s
const char * s
Definition: apr_strings.h:95
apr_sockaddr_t::sa
union apr_sockaddr_t::@1 sa
apr_vformatter_buff_t::curpos
char * curpos
Definition: apr_lib.h:66
apr_islower
#define apr_islower(c)
Definition: apr_lib.h:213
apr_vformatter_buff_t::endpos
char * endpos
Definition: apr_lib.h:68
EXPONENT_LENGTH
#define EXPONENT_LENGTH
Definition: apr_snprintf.c:62
TRUE
#define TRUE
Definition: apr_snprintf.c:53
conv_apr_sockaddr
static char * conv_apr_sockaddr(apr_sockaddr_t *sa, char *buf_end, apr_size_t *len)
Definition: apr_snprintf.c:446
YES
Definition: apr_snprintf.c:46
STR_TO_DEC
#define STR_TO_DEC(str, num)
Definition: apr_snprintf.c:261
FLOAT_DIGITS
#define FLOAT_DIGITS
Definition: apr_snprintf.c:61
APR_DECLARE_NONSTD
APR_DECLARE_NONSTD(int)
Definition: apr_snprintf.c:1355
fmt
apr_vformatter_buff_t const char * fmt
Definition: apr_lib.h:175
apr_gcvt
static char * apr_gcvt(double number, int ndigit, char *buf, boolean_e altform)
Definition: apr_snprintf.c:175
apr_ecvt
static char * apr_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
Definition: apr_snprintf.c:160
conv_p2_quad
static char * conv_p2_quad(apr_uint64_t num, register int nbits, char format, char *buf_end, register apr_size_t *len)
Definition: apr_snprintf.c:634
apr_status_t
int apr_status_t
Definition: apr_errno.h:44
NUL
#define NUL
Definition: apr_snprintf.c:55
boolean_e
boolean_e
Definition: apr_snprintf.c:45
INS_CHAR
#define INS_CHAR(c, sp, bep, cc)
Definition: apr_snprintf.c:244
num
apr_interval_time_t apr_int32_t * num
Definition: apr_poll.h:281
conv_10_quad
static char * conv_10_quad(apr_int64_t num, register int is_unsigned, register int *is_negative, char *buf_end, register apr_size_t *len)
Definition: apr_snprintf.c:372
apr_sockaddr_t::port
apr_port_t port
Definition: apr_network_io.h:274
apr_cvt
static char * apr_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf)
Definition: apr_snprintf.c:86
PAD
#define PAD(width, len, ch)
Definition: apr_snprintf.c:294
FALSE
#define FALSE
Definition: apr_snprintf.c:50
apr_sockaddr_t
Definition: apr_network_io.h:266
addr
apr_sockaddr_t * addr
Definition: apr_network_io.h:938
sa
apr_sockaddr_t * sa
Definition: apr_network_io.h:379
NUM_BUF_SIZE
#define NUM_BUF_SIZE
Definition: apr_snprintf.c:69