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