* C-style name quoting. * * (1) if sb and fp are both NULL, inspect the input name and counts the * number of bytes that are needed to hold c_style quoted version of name, * counting the double quotes around it but not terminating NUL, and * returns it. * However, if name does not need c_style quoting, it returns 0. * * (2) if sb or fp are not NULL, it emits the c_style quo
| 248 | * Return value is the same as in (1). |
| 249 | */ |
| 250 | static size_t quote_c_style_counted(const char *name, ssize_t maxlen, |
| 251 | struct strbuf *sb, FILE *fp, unsigned flags) |
| 252 | { |
| 253 | #undef EMIT |
| 254 | #define EMIT(c) \ |
| 255 | do { \ |
| 256 | if (sb) strbuf_addch(sb, (c)); \ |
| 257 | if (fp) fputc((c), fp); \ |
| 258 | count++; \ |
| 259 | } while (0) |
| 260 | #define EMITBUF(s, l) \ |
| 261 | do { \ |
| 262 | if (sb) strbuf_add(sb, (s), (l)); \ |
| 263 | if (fp) fwrite((s), (l), 1, fp); \ |
| 264 | count += (l); \ |
| 265 | } while (0) |
| 266 | |
| 267 | int no_dq = !!(flags & CQUOTE_NODQ); |
| 268 | size_t len, count = 0; |
| 269 | const char *p = name; |
| 270 | |
| 271 | for (;;) { |
| 272 | int ch; |
| 273 | |
| 274 | len = next_quote_pos(p, maxlen); |
| 275 | if (len == maxlen || (maxlen < 0 && !p[len])) |
| 276 | break; |
| 277 | |
| 278 | if (!no_dq && p == name) |
| 279 | EMIT('"'); |
| 280 | |
| 281 | EMITBUF(p, len); |
| 282 | EMIT('\\'); |
| 283 | p += len; |
| 284 | ch = (unsigned char)*p++; |
| 285 | if (maxlen >= 0) |
| 286 | maxlen -= len + 1; |
| 287 | if (cq_lookup[ch] >= ' ') { |
| 288 | EMIT(cq_lookup[ch]); |
| 289 | } else { |
| 290 | EMIT(((ch >> 6) & 03) + '0'); |
| 291 | EMIT(((ch >> 3) & 07) + '0'); |
| 292 | EMIT(((ch >> 0) & 07) + '0'); |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | EMITBUF(p, len); |
| 297 | if (p == name) /* no ending quote needed */ |
| 298 | return 0; |
| 299 | |
| 300 | if (!no_dq) |
| 301 | EMIT('"'); |
| 302 | return count; |
| 303 | } |
| 304 | |
| 305 | size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, unsigned flags) |
| 306 | { |
no test coverage detected