quote.c: separate quoting and relative path generation
This is in preparation of relative path support for ls-files, which quotes a path only if the line terminator is not the NUL character. Signed-off-by: Clemens Buchacher <drizzd@aon.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Clemens Buchacher committed
Jun 3, 2010 at 15:36 UTC
b167cffb6b38a092e8f9e0e396c1931ee1dc8b7d
2 files changed
+65
-29
quote.c
+61
-28
@@ -295,42 +295,75 @@ void write_name_quotedpfx(const char *pfx, size_t pfxlen,
295
fputc(terminator, fp);
296
}
297
298
-/* quote path as relative to the given prefix */
299
-char *quote_path_relative(const char *in, int len,
300
- struct strbuf *out, const char *prefix)
298
+static const char *path_relative(const char *in, int len,
299
+ struct strbuf *sb, const char *prefix,
300
+ int prefix_len);
301
+
302
+void write_name_quoted_relative(const char *name, size_t len,
303
+ const char *prefix, size_t prefix_len,
304
+ FILE *fp, int terminator)
305
{
302
- int needquote;
306
+ struct strbuf sb = STRBUF_INIT;
307
+
308
+ name = path_relative(name, len, &sb, prefix, prefix_len);
309
+ write_name_quoted(name, fp, terminator);
310
+
311
+ strbuf_release(&sb);
312
+}
313
+
314
+/*
315
+ * Give path as relative to prefix.
316
+ *
317
+ * The strbuf may or may not be used, so do not assume it contains the
318
+ * returned path.
319
+ */
320
+static const char *path_relative(const char *in, int len,
321
+ struct strbuf *sb, const char *prefix,
322
+ int prefix_len)
323
+{
324
+ int off, i;
325
326
if (len < 0)
327
len = strlen(in);
328
+ if (prefix && prefix_len < 0)
329
+ prefix_len = strlen(prefix);
330
+
331
+ off = 0;
332
+ i = 0;
333
+ while (i < prefix_len && i < len && prefix[i] == in[i]) {
334
+ if (prefix[i] == '/')
335
+ off = i + 1;
336
+ i++;
337
+ }
338
+ in += off;
339
+ len -= off;
340
+
341
+ if (i >= prefix_len)
342
+ return in;
343
307
- /* "../" prefix itself does not need quoting, but "in" might. */
308
- needquote = next_quote_pos(in, len) < len;
309
- strbuf_setlen(out, 0);
310
- strbuf_grow(out, len);
311
-
312
- if (needquote)
313
- strbuf_addch(out, '"');
314
- if (prefix) {
315
- int off = 0;
316
- while (prefix[off] && off < len && prefix[off] == in[off])
317
- if (prefix[off] == '/') {
318
- prefix += off + 1;
319
- in += off + 1;
320
- len -= off + 1;
321
- off = 0;
322
- } else
323
- off++;
324
-
325
- for (; *prefix; prefix++)
326
- if (*prefix == '/')
327
- strbuf_addstr(out, "../");
344
+ strbuf_reset(sb);
345
+ strbuf_grow(sb, len);
346
+
347
+ while (i < prefix_len) {
348
+ if (prefix[i] == '/')
349
+ strbuf_addstr(sb, "../");
350
+ i++;
351
}
352
+ strbuf_add(sb, in, len);
353
+
354
+ return sb->buf;
355
+}
356
330
- quote_c_style_counted (in, len, out, NULL, 1);
357
+/* quote path as relative to the given prefix */
358
+char *quote_path_relative(const char *in, int len,
359
+ struct strbuf *out, const char *prefix)
360
+{
361
+ struct strbuf sb = STRBUF_INIT;
362
+ const char *rel = path_relative(in, len, &sb, prefix, -1);
363
+ strbuf_reset(out);
364
+ quote_c_style_counted(rel, strlen(rel), out, NULL, 0);
365
+ strbuf_release(&sb);
366
332
- if (needquote)
333
- strbuf_addch(out, '"');
367
if (!out->len)
368
strbuf_addstr(out, "./");
369
quote.h
+4
-1
@@ -54,9 +54,12 @@ extern void quote_two_c_style(struct strbuf *, const char *, const char *, int);
54
extern void write_name_quoted(const char *name, FILE *, int terminator);
55
extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
56
const char *name, FILE *, int terminator);
57
+extern void write_name_quoted_relative(const char *name, size_t len,
58
+ const char *prefix, size_t prefix_len,
59
+ FILE *fp, int terminator);
60
61
/* quote path as relative to the given prefix */
59
-char *quote_path_relative(const char *in, int len,
62
+extern char *quote_path_relative(const char *in, int len,
63
struct strbuf *out, const char *prefix);
64
65
/* quoting as a string literal for other languages */