1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyevstatic u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64,
13e18a033bSKonstantin Ananyev    u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width);
14e18a033bSKonstantin Ananyevstatic void ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
15e18a033bSKonstantin Ananyev    const u_char *basis, ngx_uint_t padding);
16e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
17e18a033bSKonstantin Ananyev    const u_char *basis);
18e18a033bSKonstantin Ananyev
19e18a033bSKonstantin Ananyev
20e18a033bSKonstantin Ananyevvoid
21e18a033bSKonstantin Ananyevngx_strlow(u_char *dst, u_char *src, size_t n)
22e18a033bSKonstantin Ananyev{
23e18a033bSKonstantin Ananyev    while (n) {
24e18a033bSKonstantin Ananyev        *dst = ngx_tolower(*src);
25e18a033bSKonstantin Ananyev        dst++;
26e18a033bSKonstantin Ananyev        src++;
27e18a033bSKonstantin Ananyev        n--;
28e18a033bSKonstantin Ananyev    }
29e18a033bSKonstantin Ananyev}
30e18a033bSKonstantin Ananyev
31e18a033bSKonstantin Ananyev
32e18a033bSKonstantin Ananyevu_char *
33e18a033bSKonstantin Ananyevngx_cpystrn(u_char *dst, u_char *src, size_t n)
34e18a033bSKonstantin Ananyev{
35e18a033bSKonstantin Ananyev    if (n == 0) {
36e18a033bSKonstantin Ananyev        return dst;
37e18a033bSKonstantin Ananyev    }
38e18a033bSKonstantin Ananyev
39e18a033bSKonstantin Ananyev    while (--n) {
40e18a033bSKonstantin Ananyev        *dst = *src;
41e18a033bSKonstantin Ananyev
42e18a033bSKonstantin Ananyev        if (*dst == '\0') {
43e18a033bSKonstantin Ananyev            return dst;
44e18a033bSKonstantin Ananyev        }
45e18a033bSKonstantin Ananyev
46e18a033bSKonstantin Ananyev        dst++;
47e18a033bSKonstantin Ananyev        src++;
48e18a033bSKonstantin Ananyev    }
49e18a033bSKonstantin Ananyev
50e18a033bSKonstantin Ananyev    *dst = '\0';
51e18a033bSKonstantin Ananyev
52e18a033bSKonstantin Ananyev    return dst;
53e18a033bSKonstantin Ananyev}
54e18a033bSKonstantin Ananyev
55e18a033bSKonstantin Ananyev
56e18a033bSKonstantin Ananyevu_char *
57e18a033bSKonstantin Ananyevngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
58e18a033bSKonstantin Ananyev{
59e18a033bSKonstantin Ananyev    u_char  *dst;
60e18a033bSKonstantin Ananyev
61e18a033bSKonstantin Ananyev    dst = ngx_pnalloc(pool, src->len);
62e18a033bSKonstantin Ananyev    if (dst == NULL) {
63e18a033bSKonstantin Ananyev        return NULL;
64e18a033bSKonstantin Ananyev    }
65e18a033bSKonstantin Ananyev
66e18a033bSKonstantin Ananyev    ngx_memcpy(dst, src->data, src->len);
67e18a033bSKonstantin Ananyev
68e18a033bSKonstantin Ananyev    return dst;
69e18a033bSKonstantin Ananyev}
70e18a033bSKonstantin Ananyev
71e18a033bSKonstantin Ananyev
72e18a033bSKonstantin Ananyev/*
73e18a033bSKonstantin Ananyev * supported formats:
74e18a033bSKonstantin Ananyev *    %[0][width][x][X]O        off_t
75e18a033bSKonstantin Ananyev *    %[0][width]T              time_t
76e18a033bSKonstantin Ananyev *    %[0][width][u][x|X]z      ssize_t/size_t
77e18a033bSKonstantin Ananyev *    %[0][width][u][x|X]d      int/u_int
78e18a033bSKonstantin Ananyev *    %[0][width][u][x|X]l      long
79e18a033bSKonstantin Ananyev *    %[0][width|m][u][x|X]i    ngx_int_t/ngx_uint_t
80e18a033bSKonstantin Ananyev *    %[0][width][u][x|X]D      int32_t/uint32_t
81e18a033bSKonstantin Ananyev *    %[0][width][u][x|X]L      int64_t/uint64_t
82e18a033bSKonstantin Ananyev *    %[0][width|m][u][x|X]A    ngx_atomic_int_t/ngx_atomic_uint_t
83e18a033bSKonstantin Ananyev *    %[0][width][.width]f      double, max valid number fits to %18.15f
84e18a033bSKonstantin Ananyev *    %P                        ngx_pid_t
85e18a033bSKonstantin Ananyev *    %M                        ngx_msec_t
86e18a033bSKonstantin Ananyev *    %r                        rlim_t
87e18a033bSKonstantin Ananyev *    %p                        void *
88e18a033bSKonstantin Ananyev *    %V                        ngx_str_t *
89e18a033bSKonstantin Ananyev *    %v                        ngx_variable_value_t *
90e18a033bSKonstantin Ananyev *    %s                        null-terminated string
91e18a033bSKonstantin Ananyev *    %*s                       length and string
92e18a033bSKonstantin Ananyev *    %Z                        '\0'
93e18a033bSKonstantin Ananyev *    %N                        '\n'
94e18a033bSKonstantin Ananyev *    %c                        char
95e18a033bSKonstantin Ananyev *    %%                        %
96e18a033bSKonstantin Ananyev *
97e18a033bSKonstantin Ananyev *  reserved:
98e18a033bSKonstantin Ananyev *    %t                        ptrdiff_t
99e18a033bSKonstantin Ananyev *    %S                        null-terminated wchar string
100e18a033bSKonstantin Ananyev *    %C                        wchar
101e18a033bSKonstantin Ananyev */
102e18a033bSKonstantin Ananyev
103e18a033bSKonstantin Ananyev
104e18a033bSKonstantin Ananyevu_char * ngx_cdecl
105e18a033bSKonstantin Ananyevngx_sprintf(u_char *buf, const char *fmt, ...)
106e18a033bSKonstantin Ananyev{
107e18a033bSKonstantin Ananyev    u_char   *p;
108e18a033bSKonstantin Ananyev    va_list   args;
109e18a033bSKonstantin Ananyev
110e18a033bSKonstantin Ananyev    va_start(args, fmt);
111e18a033bSKonstantin Ananyev    p = ngx_vslprintf(buf, (void *) -1, fmt, args);
112e18a033bSKonstantin Ananyev    va_end(args);
113e18a033bSKonstantin Ananyev
114e18a033bSKonstantin Ananyev    return p;
115e18a033bSKonstantin Ananyev}
116e18a033bSKonstantin Ananyev
117e18a033bSKonstantin Ananyev
118e18a033bSKonstantin Ananyevu_char * ngx_cdecl
119e18a033bSKonstantin Ananyevngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
120e18a033bSKonstantin Ananyev{
121e18a033bSKonstantin Ananyev    u_char   *p;
122e18a033bSKonstantin Ananyev    va_list   args;
123e18a033bSKonstantin Ananyev
124e18a033bSKonstantin Ananyev    va_start(args, fmt);
125e18a033bSKonstantin Ananyev    p = ngx_vslprintf(buf, buf + max, fmt, args);
126e18a033bSKonstantin Ananyev    va_end(args);
127e18a033bSKonstantin Ananyev
128e18a033bSKonstantin Ananyev    return p;
129e18a033bSKonstantin Ananyev}
130e18a033bSKonstantin Ananyev
131e18a033bSKonstantin Ananyev
132e18a033bSKonstantin Ananyevu_char * ngx_cdecl
133e18a033bSKonstantin Ananyevngx_slprintf(u_char *buf, u_char *last, const char *fmt, ...)
134e18a033bSKonstantin Ananyev{
135e18a033bSKonstantin Ananyev    u_char   *p;
136e18a033bSKonstantin Ananyev    va_list   args;
137e18a033bSKonstantin Ananyev
138e18a033bSKonstantin Ananyev    va_start(args, fmt);
139e18a033bSKonstantin Ananyev    p = ngx_vslprintf(buf, last, fmt, args);
140e18a033bSKonstantin Ananyev    va_end(args);
141e18a033bSKonstantin Ananyev
142e18a033bSKonstantin Ananyev    return p;
143e18a033bSKonstantin Ananyev}
144e18a033bSKonstantin Ananyev
145e18a033bSKonstantin Ananyev
146e18a033bSKonstantin Ananyevu_char *
147e18a033bSKonstantin Ananyevngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args)
148e18a033bSKonstantin Ananyev{
149e18a033bSKonstantin Ananyev    u_char                *p, zero;
150e18a033bSKonstantin Ananyev    int                    d;
151e18a033bSKonstantin Ananyev    double                 f;
152e18a033bSKonstantin Ananyev    size_t                 len, slen;
153e18a033bSKonstantin Ananyev    int64_t                i64;
154e18a033bSKonstantin Ananyev    uint64_t               ui64, frac;
155e18a033bSKonstantin Ananyev    ngx_msec_t             ms;
156e18a033bSKonstantin Ananyev    ngx_uint_t             width, sign, hex, max_width, frac_width, scale, n;
157e18a033bSKonstantin Ananyev    ngx_str_t             *v;
158e18a033bSKonstantin Ananyev    ngx_variable_value_t  *vv;
159e18a033bSKonstantin Ananyev
160e18a033bSKonstantin Ananyev    while (*fmt && buf < last) {
161e18a033bSKonstantin Ananyev
162e18a033bSKonstantin Ananyev        /*
163e18a033bSKonstantin Ananyev         * "buf < last" means that we could copy at least one character:
164e18a033bSKonstantin Ananyev         * the plain character, "%%", "%c", and minus without the checking
165e18a033bSKonstantin Ananyev         */
166e18a033bSKonstantin Ananyev
167e18a033bSKonstantin Ananyev        if (*fmt == '%') {
168e18a033bSKonstantin Ananyev
169e18a033bSKonstantin Ananyev            i64 = 0;
170e18a033bSKonstantin Ananyev            ui64 = 0;
171e18a033bSKonstantin Ananyev
172e18a033bSKonstantin Ananyev            zero = (u_char) ((*++fmt == '0') ? '0' : ' ');
173e18a033bSKonstantin Ananyev            width = 0;
174e18a033bSKonstantin Ananyev            sign = 1;
175e18a033bSKonstantin Ananyev            hex = 0;
176e18a033bSKonstantin Ananyev            max_width = 0;
177e18a033bSKonstantin Ananyev            frac_width = 0;
178e18a033bSKonstantin Ananyev            slen = (size_t) -1;
179e18a033bSKonstantin Ananyev
180e18a033bSKonstantin Ananyev            while (*fmt >= '0' && *fmt <= '9') {
181e18a033bSKonstantin Ananyev                width = width * 10 + *fmt++ - '0';
182e18a033bSKonstantin Ananyev            }
183e18a033bSKonstantin Ananyev
184e18a033bSKonstantin Ananyev
185e18a033bSKonstantin Ananyev            for ( ;; ) {
186e18a033bSKonstantin Ananyev                switch (*fmt) {
187e18a033bSKonstantin Ananyev
188e18a033bSKonstantin Ananyev                case 'u':
189e18a033bSKonstantin Ananyev                    sign = 0;
190e18a033bSKonstantin Ananyev                    fmt++;
191e18a033bSKonstantin Ananyev                    continue;
192e18a033bSKonstantin Ananyev
193e18a033bSKonstantin Ananyev                case 'm':
194e18a033bSKonstantin Ananyev                    max_width = 1;
195e18a033bSKonstantin Ananyev                    fmt++;
196e18a033bSKonstantin Ananyev                    continue;
197e18a033bSKonstantin Ananyev
198e18a033bSKonstantin Ananyev                case 'X':
199e18a033bSKonstantin Ananyev                    hex = 2;
200e18a033bSKonstantin Ananyev                    sign = 0;
201e18a033bSKonstantin Ananyev                    fmt++;
202e18a033bSKonstantin Ananyev                    continue;
203e18a033bSKonstantin Ananyev
204e18a033bSKonstantin Ananyev                case 'x':
205e18a033bSKonstantin Ananyev                    hex = 1;
206e18a033bSKonstantin Ananyev                    sign = 0;
207e18a033bSKonstantin Ananyev                    fmt++;
208e18a033bSKonstantin Ananyev                    continue;
209e18a033bSKonstantin Ananyev
210e18a033bSKonstantin Ananyev                case '.':
211e18a033bSKonstantin Ananyev                    fmt++;
212e18a033bSKonstantin Ananyev
213e18a033bSKonstantin Ananyev                    while (*fmt >= '0' && *fmt <= '9') {
214e18a033bSKonstantin Ananyev                        frac_width = frac_width * 10 + *fmt++ - '0';
215e18a033bSKonstantin Ananyev                    }
216e18a033bSKonstantin Ananyev
217e18a033bSKonstantin Ananyev                    break;
218e18a033bSKonstantin Ananyev
219e18a033bSKonstantin Ananyev                case '*':
220e18a033bSKonstantin Ananyev                    slen = va_arg(args, size_t);
221e18a033bSKonstantin Ananyev                    fmt++;
222e18a033bSKonstantin Ananyev                    continue;
223e18a033bSKonstantin Ananyev
224e18a033bSKonstantin Ananyev                default:
225e18a033bSKonstantin Ananyev                    break;
226e18a033bSKonstantin Ananyev                }
227e18a033bSKonstantin Ananyev
228e18a033bSKonstantin Ananyev                break;
229e18a033bSKonstantin Ananyev            }
230e18a033bSKonstantin Ananyev
231e18a033bSKonstantin Ananyev
232e18a033bSKonstantin Ananyev            switch (*fmt) {
233e18a033bSKonstantin Ananyev
234e18a033bSKonstantin Ananyev            case 'V':
235e18a033bSKonstantin Ananyev                v = va_arg(args, ngx_str_t *);
236e18a033bSKonstantin Ananyev
237e18a033bSKonstantin Ananyev                len = ngx_min(((size_t) (last - buf)), v->len);
238e18a033bSKonstantin Ananyev                buf = ngx_cpymem(buf, v->data, len);
239e18a033bSKonstantin Ananyev                fmt++;
240e18a033bSKonstantin Ananyev
241e18a033bSKonstantin Ananyev                continue;
242e18a033bSKonstantin Ananyev
243e18a033bSKonstantin Ananyev            case 'v':
244e18a033bSKonstantin Ananyev                vv = va_arg(args, ngx_variable_value_t *);
245e18a033bSKonstantin Ananyev
246e18a033bSKonstantin Ananyev                len = ngx_min(((size_t) (last - buf)), vv->len);
247e18a033bSKonstantin Ananyev                buf = ngx_cpymem(buf, vv->data, len);
248e18a033bSKonstantin Ananyev                fmt++;
249e18a033bSKonstantin Ananyev
250e18a033bSKonstantin Ananyev                continue;
251e18a033bSKonstantin Ananyev
252e18a033bSKonstantin Ananyev            case 's':
253e18a033bSKonstantin Ananyev                p = va_arg(args, u_char *);
254e18a033bSKonstantin Ananyev
255e18a033bSKonstantin Ananyev                if (slen == (size_t) -1) {
256e18a033bSKonstantin Ananyev                    while (*p && buf < last) {
257e18a033bSKonstantin Ananyev                        *buf++ = *p++;
258e18a033bSKonstantin Ananyev                    }
259e18a033bSKonstantin Ananyev
260e18a033bSKonstantin Ananyev                } else {
261e18a033bSKonstantin Ananyev                    len = ngx_min(((size_t) (last - buf)), slen);
262e18a033bSKonstantin Ananyev                    buf = ngx_cpymem(buf, p, len);
263e18a033bSKonstantin Ananyev                }
264e18a033bSKonstantin Ananyev
265e18a033bSKonstantin Ananyev                fmt++;
266e18a033bSKonstantin Ananyev
267e18a033bSKonstantin Ananyev                continue;
268e18a033bSKonstantin Ananyev
269e18a033bSKonstantin Ananyev            case 'O':
270e18a033bSKonstantin Ananyev                i64 = (int64_t) va_arg(args, off_t);
271e18a033bSKonstantin Ananyev                sign = 1;
272e18a033bSKonstantin Ananyev                break;
273e18a033bSKonstantin Ananyev
274e18a033bSKonstantin Ananyev            case 'P':
275e18a033bSKonstantin Ananyev                i64 = (int64_t) va_arg(args, ngx_pid_t);
276e18a033bSKonstantin Ananyev                sign = 1;
277e18a033bSKonstantin Ananyev                break;
278e18a033bSKonstantin Ananyev
279e18a033bSKonstantin Ananyev            case 'T':
280e18a033bSKonstantin Ananyev                i64 = (int64_t) va_arg(args, time_t);
281e18a033bSKonstantin Ananyev                sign = 1;
282e18a033bSKonstantin Ananyev                break;
283e18a033bSKonstantin Ananyev
284e18a033bSKonstantin Ananyev            case 'M':
285e18a033bSKonstantin Ananyev                ms = (ngx_msec_t) va_arg(args, ngx_msec_t);
286e18a033bSKonstantin Ananyev                if ((ngx_msec_int_t) ms == -1) {
287e18a033bSKonstantin Ananyev                    sign = 1;
288e18a033bSKonstantin Ananyev                    i64 = -1;
289e18a033bSKonstantin Ananyev                } else {
290e18a033bSKonstantin Ananyev                    sign = 0;
291e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) ms;
292e18a033bSKonstantin Ananyev                }
293e18a033bSKonstantin Ananyev                break;
294e18a033bSKonstantin Ananyev
295e18a033bSKonstantin Ananyev            case 'z':
296e18a033bSKonstantin Ananyev                if (sign) {
297e18a033bSKonstantin Ananyev                    i64 = (int64_t) va_arg(args, ssize_t);
298e18a033bSKonstantin Ananyev                } else {
299e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) va_arg(args, size_t);
300e18a033bSKonstantin Ananyev                }
301e18a033bSKonstantin Ananyev                break;
302e18a033bSKonstantin Ananyev
303e18a033bSKonstantin Ananyev            case 'i':
304e18a033bSKonstantin Ananyev                if (sign) {
305e18a033bSKonstantin Ananyev                    i64 = (int64_t) va_arg(args, ngx_int_t);
306e18a033bSKonstantin Ananyev                } else {
307e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) va_arg(args, ngx_uint_t);
308e18a033bSKonstantin Ananyev                }
309e18a033bSKonstantin Ananyev
310e18a033bSKonstantin Ananyev                if (max_width) {
311e18a033bSKonstantin Ananyev                    width = NGX_INT_T_LEN;
312e18a033bSKonstantin Ananyev                }
313e18a033bSKonstantin Ananyev
314e18a033bSKonstantin Ananyev                break;
315e18a033bSKonstantin Ananyev
316e18a033bSKonstantin Ananyev            case 'd':
317e18a033bSKonstantin Ananyev                if (sign) {
318e18a033bSKonstantin Ananyev                    i64 = (int64_t) va_arg(args, int);
319e18a033bSKonstantin Ananyev                } else {
320e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) va_arg(args, u_int);
321e18a033bSKonstantin Ananyev                }
322e18a033bSKonstantin Ananyev                break;
323e18a033bSKonstantin Ananyev
324e18a033bSKonstantin Ananyev            case 'l':
325e18a033bSKonstantin Ananyev                if (sign) {
326e18a033bSKonstantin Ananyev                    i64 = (int64_t) va_arg(args, long);
327e18a033bSKonstantin Ananyev                } else {
328e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) va_arg(args, u_long);
329e18a033bSKonstantin Ananyev                }
330e18a033bSKonstantin Ananyev                break;
331e18a033bSKonstantin Ananyev
332e18a033bSKonstantin Ananyev            case 'D':
333e18a033bSKonstantin Ananyev                if (sign) {
334e18a033bSKonstantin Ananyev                    i64 = (int64_t) va_arg(args, int32_t);
335e18a033bSKonstantin Ananyev                } else {
336e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) va_arg(args, uint32_t);
337e18a033bSKonstantin Ananyev                }
338e18a033bSKonstantin Ananyev                break;
339e18a033bSKonstantin Ananyev
340e18a033bSKonstantin Ananyev            case 'L':
341e18a033bSKonstantin Ananyev                if (sign) {
342e18a033bSKonstantin Ananyev                    i64 = va_arg(args, int64_t);
343e18a033bSKonstantin Ananyev                } else {
344e18a033bSKonstantin Ananyev                    ui64 = va_arg(args, uint64_t);
345e18a033bSKonstantin Ananyev                }
346e18a033bSKonstantin Ananyev                break;
347e18a033bSKonstantin Ananyev
348e18a033bSKonstantin Ananyev            case 'A':
349e18a033bSKonstantin Ananyev                if (sign) {
350e18a033bSKonstantin Ananyev                    i64 = (int64_t) va_arg(args, ngx_atomic_int_t);
351e18a033bSKonstantin Ananyev                } else {
352e18a033bSKonstantin Ananyev                    ui64 = (uint64_t) va_arg(args, ngx_atomic_uint_t);
353e18a033bSKonstantin Ananyev                }
354e18a033bSKonstantin Ananyev
355e18a033bSKonstantin Ananyev                if (max_width) {
356e18a033bSKonstantin Ananyev                    width = NGX_ATOMIC_T_LEN;
357e18a033bSKonstantin Ananyev                }
358e18a033bSKonstantin Ananyev
359e18a033bSKonstantin Ananyev                break;
360e18a033bSKonstantin Ananyev
361e18a033bSKonstantin Ananyev            case 'f':
362e18a033bSKonstantin Ananyev                f = va_arg(args, double);
363e18a033bSKonstantin Ananyev
364e18a033bSKonstantin Ananyev                if (f < 0) {
365e18a033bSKonstantin Ananyev                    *buf++ = '-';
366e18a033bSKonstantin Ananyev                    f = -f;
367e18a033bSKonstantin Ananyev                }
368e18a033bSKonstantin Ananyev
369e18a033bSKonstantin Ananyev                ui64 = (int64_t) f;
370e18a033bSKonstantin Ananyev                frac = 0;
371e18a033bSKonstantin Ananyev
372e18a033bSKonstantin Ananyev                if (frac_width) {
373e18a033bSKonstantin Ananyev
374e18a033bSKonstantin Ananyev                    scale = 1;
375e18a033bSKonstantin Ananyev                    for (n = frac_width; n; n--) {
376e18a033bSKonstantin Ananyev                        scale *= 10;
377e18a033bSKonstantin Ananyev                    }
378e18a033bSKonstantin Ananyev
379e18a033bSKonstantin Ananyev                    frac = (uint64_t) ((f - (double) ui64) * scale + 0.5);
380e18a033bSKonstantin Ananyev
381e18a033bSKonstantin Ananyev                    if (frac == scale) {
382e18a033bSKonstantin Ananyev                        ui64++;
383e18a033bSKonstantin Ananyev                        frac = 0;
384e18a033bSKonstantin Ananyev                    }
385e18a033bSKonstantin Ananyev                }
386e18a033bSKonstantin Ananyev
387e18a033bSKonstantin Ananyev                buf = ngx_sprintf_num(buf, last, ui64, zero, 0, width);
388e18a033bSKonstantin Ananyev
389e18a033bSKonstantin Ananyev                if (frac_width) {
390e18a033bSKonstantin Ananyev                    if (buf < last) {
391e18a033bSKonstantin Ananyev                        *buf++ = '.';
392e18a033bSKonstantin Ananyev                    }
393e18a033bSKonstantin Ananyev
394e18a033bSKonstantin Ananyev                    buf = ngx_sprintf_num(buf, last, frac, '0', 0, frac_width);
395e18a033bSKonstantin Ananyev                }
396e18a033bSKonstantin Ananyev
397e18a033bSKonstantin Ananyev                fmt++;
398e18a033bSKonstantin Ananyev
399e18a033bSKonstantin Ananyev                continue;
400e18a033bSKonstantin Ananyev
401e18a033bSKonstantin Ananyev#if !(NGX_WIN32)
402e18a033bSKonstantin Ananyev            case 'r':
403e18a033bSKonstantin Ananyev                i64 = (int64_t) va_arg(args, rlim_t);
404e18a033bSKonstantin Ananyev                sign = 1;
405e18a033bSKonstantin Ananyev                break;
406e18a033bSKonstantin Ananyev#endif
407e18a033bSKonstantin Ananyev
408e18a033bSKonstantin Ananyev            case 'p':
409e18a033bSKonstantin Ananyev                ui64 = (uintptr_t) va_arg(args, void *);
410e18a033bSKonstantin Ananyev                hex = 2;
411e18a033bSKonstantin Ananyev                sign = 0;
412e18a033bSKonstantin Ananyev                zero = '0';
413e18a033bSKonstantin Ananyev                width = 2 * sizeof(void *);
414e18a033bSKonstantin Ananyev                break;
415e18a033bSKonstantin Ananyev
416e18a033bSKonstantin Ananyev            case 'c':
417e18a033bSKonstantin Ananyev                d = va_arg(args, int);
418e18a033bSKonstantin Ananyev                *buf++ = (u_char) (d & 0xff);
419e18a033bSKonstantin Ananyev                fmt++;
420e18a033bSKonstantin Ananyev
421e18a033bSKonstantin Ananyev                continue;
422e18a033bSKonstantin Ananyev
423