xref: /unit/src/nxt_file_name.c (revision 0:a63ceefd6ab0)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 
9 
10 /*
11  * Supported formats:
12  *    %s     null-terminated string
13  *    %*s    length and string
14  *    %FN    nxt_file_name_t *
15  *    %V     nxt_str_t *
16  *    %Z     '\0', this null is not counted in file name lenght.
17  */
18 
19 nxt_int_t
20 nxt_file_name_create(nxt_mem_pool_t *mp, nxt_file_name_str_t *file_name,
21     const char *format, ...)
22 {
23     u_char           ch, *p;
24     size_t           len;
25     va_list          args;
26     nxt_str_t        *v;
27     nxt_bool_t       zero;
28     const char       *fmt;
29     nxt_file_name_t  *dst, *fn;
30 
31     va_start(args, format);
32     fmt = format;
33     zero = 0;
34     len = 0;
35 
36     for ( ;; ) {
37         ch = *fmt++;
38 
39         if (ch != '%') {
40 
41             if (ch != '\0') {
42                 len++;
43                 continue;
44             }
45 
46             break;
47         }
48 
49         ch = *fmt++;
50 
51         switch (ch) {
52 
53         case 'V':
54             v = va_arg(args, nxt_str_t *);
55 
56             if (nxt_fast_path(v != NULL)) {
57                 len += v->len;
58             }
59 
60             continue;
61 
62         case 's':
63             p = va_arg(args, u_char *);
64 
65             if (nxt_fast_path(p != NULL)) {
66                 while (*p != '\0') {
67                     p++;
68                     len++;
69                 }
70             }
71 
72             continue;
73 
74         case '*':
75             len += va_arg(args, u_int);
76             fmt++;
77 
78             continue;
79 
80         case 'F':
81             ch = *fmt++;
82 
83             if (nxt_fast_path(ch == 'N')) {
84                 fn = va_arg(args, nxt_file_name_t *);
85 
86                 if (nxt_fast_path(fn != NULL)) {
87                     while (*fn != '\0') {
88                         fn++;
89                         len += sizeof(nxt_file_name_t);
90                     }
91                 }
92             }
93 
94             continue;
95 
96         case 'Z':
97             zero = 1;
98             len++;
99             continue;
100 
101         default:
102             continue;
103         }
104     }
105 
106     va_end(args);
107 
108     if (len == 0) {
109         return NXT_ERROR;
110     }
111 
112     file_name->len = len - zero;
113 
114     fn = nxt_file_name_alloc(mp, len);
115     if (nxt_slow_path(fn == NULL)) {
116         return NXT_ERROR;
117     }
118 
119     file_name->start = fn;
120     dst = fn;
121 
122     va_start(args, format);
123     fmt = format;
124 
125     for ( ;; ) {
126         ch = *fmt++;
127 
128         if (ch != '%') {
129 
130             if (ch != '\0') {
131                 *dst++ = (nxt_file_name_t) ch;
132                 continue;
133             }
134 
135             break;
136         }
137 
138         ch = *fmt++;
139 
140         switch (ch) {
141 
142         case 'V':
143             v = va_arg(args, nxt_str_t *);
144 
145             if (nxt_fast_path(v != NULL)) {
146                 dst = nxt_file_name_add(dst, v->data, v->len);
147             }
148 
149             continue;
150 
151         case 's':
152             p = va_arg(args, u_char *);
153 
154             if (nxt_fast_path(p != NULL)) {
155                 while (*p != '\0') {
156                     *dst++ = (nxt_file_name_t) (*p++);
157                 }
158             }
159 
160             continue;
161 
162         case '*':
163             len += va_arg(args, u_int);
164 
165             ch = *fmt++;
166 
167             if (nxt_fast_path(ch == 's')) {
168                 p = va_arg(args, u_char *);
169                 dst = nxt_file_name_add(dst, p, len);
170             }
171 
172             continue;
173 
174         case 'F':
175             ch = *fmt++;
176 
177             if (nxt_fast_path(ch == 'N')) {
178                 fn = va_arg(args, nxt_file_name_t *);
179 
180                 if (nxt_fast_path(fn != NULL)) {
181                     while (*fn != '\0') {
182                         *dst++ = *fn++;
183                     }
184                 }
185             }
186 
187             continue;
188 
189         case 'Z':
190             *dst++ = '\0';
191             continue;
192 
193         default:
194             continue;
195         }
196     }
197 
198     va_end(args);
199 
200     return NXT_OK;
201 }
202