summaryrefslogtreecommitdiffstats
path: root/cgi/cgitextarea.c
blob: 750b2eed7f09b79594fe3d684993c09c9337b1a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
** Copyright 2007 Double Precision, Inc.
** See COPYING for distribution information.
*/

/*
*/

#include	"cgi.h"
#include	<stdio.h>
#include	<string.h>
#include	<stdlib.h>
#include	<ctype.h>

extern void cgi_output_unicode_escapes(const char32_t *value,
				       const char *escapes,
				       void (*output_func)(const char *,
							   size_t,
							   void *),
				       void *output_arg);

static void do_cgi_textarea(const char *name,
			    int rows,
			    int cols,
			    const char32_t *value,
			    const char *opts,
			    const char *wrap,
			    void (*output_func)(const char *, size_t,
						void *),
			    void *output_arg)
{
	(*output_func)("<textarea name='", 0, output_arg);
	(*output_func)(name, 0, output_arg);
	(*output_func)("'", 0, output_arg);

	if (strchr(opts, 'r'))
		(*output_func)(" readonly='readonly'", 0, output_arg);
	if (strchr(opts, 'd'))
		(*output_func)(" disabled='disabled'", 0, output_arg);

	(*output_func)("'", 0, output_arg);

	if (rows)
	{
		char buf[100];

		sprintf(buf, " rows='%d'", rows);

		(*output_func)(buf, 0, output_arg);
	}

	if (cols)
	{
		char buf[100];

		sprintf(buf, " cols='%d'", cols);

		(*output_func)(buf, 0, output_arg);
	}

	if (wrap)
	{
		(*output_func)(" wrap='", 0, output_arg);
		(*output_func)(wrap, 0, output_arg);
		(*output_func)("'", 0, output_arg);
	}

	(*output_func)(">", 0, output_arg);

	cgi_output_unicode_escapes(value, "<>'&", output_func, output_arg);

	(*output_func)("</textarea>", 0, output_arg);
}

static void cnt_bytes(const char *str, size_t cnt, void *arg)
{
	if (!cnt)
		cnt=strlen(str);

	*(size_t *)arg += cnt;
}

static void save_bytes(const char *str, size_t cnt, void *arg)
{
	char **p=(char **)arg;

	if (!cnt)
		cnt=strlen(str);

	memcpy(*p, str, cnt);

	*p += cnt;
}

char *cgi_textarea(const char *name,
		   int rows,
		   int cols,
		   const char32_t *value,
		   const char *wrap,
		   const char *opts)
{
	size_t cnt=1;
	char *buf;
	char *ptr;

	if (!opts)
		opts="";

	do_cgi_textarea(name, rows, cols, value, opts, wrap, cnt_bytes, &cnt);

	buf=malloc(cnt);

	if (!buf)
		return NULL;

	ptr=buf;
	do_cgi_textarea(name, rows, cols, value, opts, wrap, save_bytes, &ptr);
	*ptr=0;
	return buf;
}