Exemple #1
0
void write_name_quotedpfx(const char *pfx, size_t pfxlen,
			  const char *name, FILE *fp, int terminator)
{
	int needquote = 0;

	if (terminator) {
		needquote = next_quote_pos(pfx, pfxlen) < pfxlen
			|| name[next_quote_pos(name, -1)];
	}
	if (needquote) {
		fputc('"', fp);
		quote_c_style_counted(pfx, pfxlen, NULL, fp, 1);
		quote_c_style(name, NULL, fp, 1);
		fputc('"', fp);
	} else {
		fwrite(pfx, pfxlen, 1, fp);
		fputs(name, fp);
	}
	fputc(terminator, fp);
}
Exemple #2
0
/*
 * 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 quoted version
 *     of name, enclosed with double quotes if asked and needed only.
 *     Return value is the same as in (1).
 */
static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
				    struct strbuf *sb, FILE *fp, int no_dq)
{
#undef EMIT
#define EMIT(c)                                 \
	do {                                        \
		if (sb) strbuf_addch(sb, (c));          \
		if (fp) fputc((c), fp);                 \
		count++;                                \
	} while (0)
#define EMITBUF(s, l)                           \
	do {                                        \
		if (sb) strbuf_add(sb, (s), (l));       \
		if (fp) fwrite((s), (l), 1, fp);        \
		count += (l);                           \
	} while (0)

	size_t len, count = 0;
	const char *p = name;

	for (;;) {
		int ch;

		len = next_quote_pos(p, maxlen);
		if (len == maxlen || (maxlen < 0 && !p[len]))
			break;

		if (!no_dq && p == name)
			EMIT('"');

		EMITBUF(p, len);
		EMIT('\\');
		p += len;
		ch = (unsigned char)*p++;
		if (maxlen >= 0)
			maxlen -= len + 1;
		if (sq_lookup[ch] >= ' ') {
			EMIT(sq_lookup[ch]);
		} else {
			EMIT(((ch >> 6) & 03) + '0');
			EMIT(((ch >> 3) & 07) + '0');
			EMIT(((ch >> 0) & 07) + '0');
		}
	}

	EMITBUF(p, len);
	if (p == name)   /* no ending quote needed */
		return 0;

	if (!no_dq)
		EMIT('"');
	return count;
}
Exemple #3
0
/* quote path as relative to the given prefix */
char *quote_path_relative(const char *in, int len,
			  struct strbuf *out, const char *prefix)
{
	int needquote;

	if (len < 0)
		len = strlen(in);

	/* "../" prefix itself does not need quoting, but "in" might. */
	needquote = (next_quote_pos(in, len) < len);
	strbuf_setlen(out, 0);
	strbuf_grow(out, len);

	if (needquote)
		strbuf_addch(out, '"');
	if (prefix) {
		int off = 0;
		while (prefix[off] && off < len && prefix[off] == in[off])
			if (prefix[off] == '/') {
				prefix += off + 1;
				in += off + 1;
				len -= off + 1;
				off = 0;
			} else
				off++;

		for (; *prefix; prefix++)
			if (*prefix == '/')
				strbuf_addstr(out, "../");
	}

	quote_c_style_counted (in, len, out, NULL, 1);

	if (needquote)
		strbuf_addch(out, '"');
	if (!out->len)
		strbuf_addstr(out, "./");

	return out->buf;
}