xref: /unit/src/nxt_file_name.c (revision 65:10688b89aa16)
10Sigor@sysoev.ru 
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru  */
60Sigor@sysoev.ru 
70Sigor@sysoev.ru #include <nxt_main.h>
80Sigor@sysoev.ru 
90Sigor@sysoev.ru 
100Sigor@sysoev.ru /*
110Sigor@sysoev.ru  * Supported formats:
120Sigor@sysoev.ru  *    %s     null-terminated string
130Sigor@sysoev.ru  *    %*s    length and string
140Sigor@sysoev.ru  *    %FN    nxt_file_name_t *
150Sigor@sysoev.ru  *    %V     nxt_str_t *
160Sigor@sysoev.ru  *    %Z     '\0', this null is not counted in file name lenght.
170Sigor@sysoev.ru  */
180Sigor@sysoev.ru 
190Sigor@sysoev.ru nxt_int_t
nxt_file_name_create(nxt_mp_t * mp,nxt_file_name_str_t * file_name,const char * format,...)20*65Sigor@sysoev.ru nxt_file_name_create(nxt_mp_t *mp, nxt_file_name_str_t *file_name,
210Sigor@sysoev.ru     const char *format, ...)
220Sigor@sysoev.ru {
230Sigor@sysoev.ru     u_char           ch, *p;
2410Sigor@sysoev.ru     size_t           length;
250Sigor@sysoev.ru     va_list          args;
260Sigor@sysoev.ru     nxt_str_t        *v;
270Sigor@sysoev.ru     nxt_bool_t       zero;
280Sigor@sysoev.ru     const char       *fmt;
290Sigor@sysoev.ru     nxt_file_name_t  *dst, *fn;
300Sigor@sysoev.ru 
310Sigor@sysoev.ru     va_start(args, format);
320Sigor@sysoev.ru     fmt = format;
330Sigor@sysoev.ru     zero = 0;
3410Sigor@sysoev.ru     length = 0;
350Sigor@sysoev.ru 
360Sigor@sysoev.ru     for ( ;; ) {
370Sigor@sysoev.ru         ch = *fmt++;
380Sigor@sysoev.ru 
390Sigor@sysoev.ru         if (ch != '%') {
400Sigor@sysoev.ru 
410Sigor@sysoev.ru             if (ch != '\0') {
4210Sigor@sysoev.ru                 length++;
430Sigor@sysoev.ru                 continue;
440Sigor@sysoev.ru             }
450Sigor@sysoev.ru 
460Sigor@sysoev.ru             break;
470Sigor@sysoev.ru         }
480Sigor@sysoev.ru 
490Sigor@sysoev.ru         ch = *fmt++;
500Sigor@sysoev.ru 
510Sigor@sysoev.ru         switch (ch) {
520Sigor@sysoev.ru 
530Sigor@sysoev.ru         case 'V':
540Sigor@sysoev.ru             v = va_arg(args, nxt_str_t *);
550Sigor@sysoev.ru 
560Sigor@sysoev.ru             if (nxt_fast_path(v != NULL)) {
5710Sigor@sysoev.ru                 length += v->length;
580Sigor@sysoev.ru             }
590Sigor@sysoev.ru 
600Sigor@sysoev.ru             continue;
610Sigor@sysoev.ru 
620Sigor@sysoev.ru         case 's':
630Sigor@sysoev.ru             p = va_arg(args, u_char *);
640Sigor@sysoev.ru 
650Sigor@sysoev.ru             if (nxt_fast_path(p != NULL)) {
660Sigor@sysoev.ru                 while (*p != '\0') {
670Sigor@sysoev.ru                     p++;
6810Sigor@sysoev.ru                     length++;
690Sigor@sysoev.ru                 }
700Sigor@sysoev.ru             }
710Sigor@sysoev.ru 
720Sigor@sysoev.ru             continue;
730Sigor@sysoev.ru 
740Sigor@sysoev.ru         case '*':
7510Sigor@sysoev.ru             length += va_arg(args, u_int);
760Sigor@sysoev.ru             fmt++;
770Sigor@sysoev.ru 
780Sigor@sysoev.ru             continue;
790Sigor@sysoev.ru 
800Sigor@sysoev.ru         case 'F':
810Sigor@sysoev.ru             ch = *fmt++;
820Sigor@sysoev.ru 
830Sigor@sysoev.ru             if (nxt_fast_path(ch == 'N')) {
840Sigor@sysoev.ru                 fn = va_arg(args, nxt_file_name_t *);
850Sigor@sysoev.ru 
860Sigor@sysoev.ru                 if (nxt_fast_path(fn != NULL)) {
870Sigor@sysoev.ru                     while (*fn != '\0') {
880Sigor@sysoev.ru                         fn++;
8910Sigor@sysoev.ru                         length += sizeof(nxt_file_name_t);
900Sigor@sysoev.ru                     }
910Sigor@sysoev.ru                 }
920Sigor@sysoev.ru             }
930Sigor@sysoev.ru 
940Sigor@sysoev.ru             continue;
950Sigor@sysoev.ru 
960Sigor@sysoev.ru         case 'Z':
970Sigor@sysoev.ru             zero = 1;
9810Sigor@sysoev.ru             length++;
990Sigor@sysoev.ru             continue;
1000Sigor@sysoev.ru 
1010Sigor@sysoev.ru         default:
1020Sigor@sysoev.ru             continue;
1030Sigor@sysoev.ru         }
1040Sigor@sysoev.ru     }
1050Sigor@sysoev.ru 
1060Sigor@sysoev.ru     va_end(args);
1070Sigor@sysoev.ru 
10810Sigor@sysoev.ru     if (length == 0) {
1090Sigor@sysoev.ru         return NXT_ERROR;
1100Sigor@sysoev.ru     }
1110Sigor@sysoev.ru 
11210Sigor@sysoev.ru     file_name->len = length - zero;
1130Sigor@sysoev.ru 
11410Sigor@sysoev.ru     fn = nxt_file_name_alloc(mp, length);
1150Sigor@sysoev.ru     if (nxt_slow_path(fn == NULL)) {
1160Sigor@sysoev.ru         return NXT_ERROR;
1170Sigor@sysoev.ru     }
1180Sigor@sysoev.ru 
1190Sigor@sysoev.ru     file_name->start = fn;
1200Sigor@sysoev.ru     dst = fn;
1210Sigor@sysoev.ru 
1220Sigor@sysoev.ru     va_start(args, format);
1230Sigor@sysoev.ru     fmt = format;
1240Sigor@sysoev.ru 
1250Sigor@sysoev.ru     for ( ;; ) {
1260Sigor@sysoev.ru         ch = *fmt++;
1270Sigor@sysoev.ru 
1280Sigor@sysoev.ru         if (ch != '%') {
1290Sigor@sysoev.ru 
1300Sigor@sysoev.ru             if (ch != '\0') {
1310Sigor@sysoev.ru                 *dst++ = (nxt_file_name_t) ch;
1320Sigor@sysoev.ru                 continue;
1330Sigor@sysoev.ru             }
1340Sigor@sysoev.ru 
1350Sigor@sysoev.ru             break;
1360Sigor@sysoev.ru         }
1370Sigor@sysoev.ru 
1380Sigor@sysoev.ru         ch = *fmt++;
1390Sigor@sysoev.ru 
1400Sigor@sysoev.ru         switch (ch) {
1410Sigor@sysoev.ru 
1420Sigor@sysoev.ru         case 'V':
1430Sigor@sysoev.ru             v = va_arg(args, nxt_str_t *);
1440Sigor@sysoev.ru 
1450Sigor@sysoev.ru             if (nxt_fast_path(v != NULL)) {
14610Sigor@sysoev.ru                 dst = nxt_file_name_add(dst, v->start, v->length);
1470Sigor@sysoev.ru             }
1480Sigor@sysoev.ru 
1490Sigor@sysoev.ru             continue;
1500Sigor@sysoev.ru 
1510Sigor@sysoev.ru         case 's':
1520Sigor@sysoev.ru             p = va_arg(args, u_char *);
1530Sigor@sysoev.ru 
1540Sigor@sysoev.ru             if (nxt_fast_path(p != NULL)) {
1550Sigor@sysoev.ru                 while (*p != '\0') {
1560Sigor@sysoev.ru                     *dst++ = (nxt_file_name_t) (*p++);
1570Sigor@sysoev.ru                 }
1580Sigor@sysoev.ru             }
1590Sigor@sysoev.ru 
1600Sigor@sysoev.ru             continue;
1610Sigor@sysoev.ru 
1620Sigor@sysoev.ru         case '*':
16310Sigor@sysoev.ru             length += va_arg(args, u_int);
1640Sigor@sysoev.ru 
1650Sigor@sysoev.ru             ch = *fmt++;
1660Sigor@sysoev.ru 
1670Sigor@sysoev.ru             if (nxt_fast_path(ch == 's')) {
1680Sigor@sysoev.ru                 p = va_arg(args, u_char *);
16910Sigor@sysoev.ru                 dst = nxt_file_name_add(dst, p, length);
1700Sigor@sysoev.ru             }
1710Sigor@sysoev.ru 
1720Sigor@sysoev.ru             continue;
1730Sigor@sysoev.ru 
1740Sigor@sysoev.ru         case 'F':
1750Sigor@sysoev.ru             ch = *fmt++;
1760Sigor@sysoev.ru 
1770Sigor@sysoev.ru             if (nxt_fast_path(ch == 'N')) {
1780Sigor@sysoev.ru                 fn = va_arg(args, nxt_file_name_t *);
1790Sigor@sysoev.ru 
1800Sigor@sysoev.ru                 if (nxt_fast_path(fn != NULL)) {
1810Sigor@sysoev.ru                     while (*fn != '\0') {
1820Sigor@sysoev.ru                         *dst++ = *fn++;
1830Sigor@sysoev.ru                     }
1840Sigor@sysoev.ru                 }
1850Sigor@sysoev.ru             }
1860Sigor@sysoev.ru 
1870Sigor@sysoev.ru             continue;
1880Sigor@sysoev.ru 
1890Sigor@sysoev.ru         case 'Z':
1900Sigor@sysoev.ru             *dst++ = '\0';
1910Sigor@sysoev.ru             continue;
1920Sigor@sysoev.ru 
1930Sigor@sysoev.ru         default:
1940Sigor@sysoev.ru             continue;
1950Sigor@sysoev.ru         }
1960Sigor@sysoev.ru     }
1970Sigor@sysoev.ru 
1980Sigor@sysoev.ru     va_end(args);
1990Sigor@sysoev.ru 
2000Sigor@sysoev.ru     return NXT_OK;
2010Sigor@sysoev.ru }
202