1154815Sphk/*-
2154815Sphk * Copyright (c) 2005 Poul-Henning Kamp
3154815Sphk * All rights reserved.
4154815Sphk *
5154815Sphk * Redistribution and use in source and binary forms, with or without
6154815Sphk * modification, are permitted provided that the following conditions
7154815Sphk * are met:
8154815Sphk * 1. Redistributions of source code must retain the above copyright
9154815Sphk *    notice, this list of conditions and the following disclaimer.
10154815Sphk * 2. Redistributions in binary form must reproduce the above copyright
11154815Sphk *    notice, this list of conditions and the following disclaimer in the
12154815Sphk *    documentation and/or other materials provided with the distribution.
13154815Sphk *
14154815Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15154815Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16154815Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17154815Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18154815Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19154815Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20154815Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21154815Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22154815Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23154815Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24154815Sphk * SUCH DAMAGE.
25154815Sphk *
26154815Sphk * $FreeBSD$
27154815Sphk */
28154815Sphk
29154815Sphk#include <namespace.h>
30154815Sphk#include <stdio.h>
31154815Sphk#include <string.h>
32154815Sphk#include <stdlib.h>
33154815Sphk#include <ctype.h>
34154815Sphk#include <wchar.h>
35154815Sphk#include <vis.h>
36154815Sphk#include <assert.h>
37154815Sphk#include <sys/time.h>
38154815Sphk#include "printf.h"
39154815Sphk
40154815Sphkint
41154815Sphk__printf_arginfo_quote(const struct printf_info *pi __unused, size_t n, int *argt)
42154815Sphk{
43154815Sphk
44154815Sphk	assert(n >= 1);
45154815Sphk	argt[0] = PA_POINTER;
46154815Sphk	return (1);
47154815Sphk}
48154815Sphk
49154815Sphkint
50154815Sphk__printf_render_quote(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg)
51154815Sphk{
52154815Sphk	const char *str, *p, *t, *o;
53156207Sphk	char r[5];
54154815Sphk	int i, ret;
55154815Sphk
56154815Sphk	str = *((const char *const *)arg[0]);
57154815Sphk	if (str == NULL)
58154815Sphk		return (__printf_out(io, pi, "\"(null)\"", 8));
59154815Sphk	if (*str == '\0')
60156207Sphk		return (__printf_out(io, pi, "\"\"", 2));
61156207Sphk
62156207Sphk	for (i = 0, p = str; *p; p++)
63156207Sphk		if (isspace(*p) || *p == '\\' || *p == '"')
64156207Sphk			i++;
65154815Sphk	if (!i)
66154815Sphk		return (__printf_out(io, pi, str, strlen(str)));
67154815Sphk
68154815Sphk	ret = __printf_out(io, pi, "\"", 1);
69156207Sphk	for (t = p = str; *p; p++) {
70154815Sphk		o = NULL;
71154815Sphk		if (*p == '\\')
72154815Sphk			o = "\\\\";
73154815Sphk		else if (*p == '\n')
74154815Sphk			o = "\\n";
75154815Sphk		else if (*p == '\r')
76154815Sphk			o = "\\r";
77154815Sphk		else if (*p == '\t')
78154815Sphk			o = "\\t";
79154815Sphk		else if (*p == ' ')
80154815Sphk			o = " ";
81154815Sphk		else if (*p == '"')
82154815Sphk			o = "\\\"";
83154815Sphk		else if (isspace(*p)) {
84154815Sphk			sprintf(r, "\\%03o", *p);
85154815Sphk			o = r;
86154815Sphk		} else
87154815Sphk			continue;
88156207Sphk		if (p != t)
89154815Sphk			ret += __printf_out(io, pi, t, p - t);
90154815Sphk		ret += __printf_out(io, pi, o, strlen(o));
91156207Sphk		t = p + 1;
92154815Sphk	}
93154815Sphk	if (p != t)
94154815Sphk		ret += __printf_out(io, pi, t, p - t);
95154815Sphk	ret += __printf_out(io, pi, "\"", 1);
96154815Sphk	__printf_flush(io);
97154815Sphk	return(ret);
98154815Sphk}
99