1 /*
2 ** Copyright 2007 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5
6 /*
7 */
8
9 #include "cgi.h"
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <ctype.h>
14
do_cgi_select(const char * name,const char * optvalues,const char * optlabels,const char * default_value,size_t list_size,const char * flags,void (* output_func)(const char *,size_t,void *),void * output_arg)15 static void do_cgi_select(const char *name,
16 const char *optvalues,
17 const char *optlabels,
18 const char *default_value,
19 size_t list_size,
20 const char *flags,
21
22 void (*output_func)(const char *, size_t, void *),
23 void *output_arg)
24 {
25 (*output_func)("<select name='", 0, output_arg);
26 (*output_func)(name, 0, output_arg);
27 (*output_func)("'", 0, output_arg);
28
29 if (strchr(flags, 'm'))
30 (*output_func)(" multiple='multiple'", 0, output_arg);
31 if (strchr(flags, 'd'))
32 (*output_func)(" disabled='disabled'", 0, output_arg);
33
34 (*output_func)("'>", 0, output_arg);
35
36 if (!optvalues)
37 optvalues="";
38
39 while (*optlabels)
40 {
41 const char *label_start=optlabels;
42 const char *value_start=optvalues;
43
44 while (*optlabels)
45 {
46 if (*optlabels == '\n')
47 break;
48 ++optlabels;
49 }
50
51 while (*optvalues)
52 {
53 if (*optvalues == '\n')
54 break;
55 ++optvalues;
56 }
57
58 (*output_func)("<option", 0, output_arg);
59
60 if (*value_start)
61 {
62 if (default_value &&
63 optvalues - value_start == strlen(default_value) &&
64 strncmp(value_start, default_value,
65 optvalues-value_start) == 0)
66 {
67 (*output_func)(" selected='selected'", 0,
68 output_arg);
69 }
70
71 (*output_func)(" value='", 0, output_arg);
72 (*output_func)(value_start, optvalues-value_start,
73 output_arg);
74 (*output_func)("'", 0, output_arg);
75 }
76 (*output_func)(">", 0, output_arg);
77 (*output_func)(label_start, optlabels-label_start, output_arg);
78 (*output_func)("</option>", 0, output_arg);
79 if (*optlabels)
80 ++optlabels;
81 if (*optvalues)
82 ++optvalues;
83 }
84
85 (*output_func)("</select>", 0, output_arg);
86 }
87
cnt_bytes(const char * str,size_t cnt,void * arg)88 static void cnt_bytes(const char *str, size_t cnt, void *arg)
89 {
90 if (!cnt)
91 cnt=strlen(str);
92
93 *(size_t *)arg += cnt;
94 }
95
save_bytes(const char * str,size_t cnt,void * arg)96 static void save_bytes(const char *str, size_t cnt, void *arg)
97 {
98 char **p=(char **)arg;
99
100 if (!cnt)
101 cnt=strlen(str);
102
103 memcpy(*p, str, cnt);
104 *p += cnt;
105 }
106
cgi_select(const char * name,const char * optvalues,const char * optlabels,const char * default_value,size_t list_size,const char * flags)107 char *cgi_select(const char *name,
108 const char *optvalues,
109 const char *optlabels,
110 const char *default_value,
111 size_t list_size,
112 const char *flags)
113 {
114 size_t cnt=1;
115 char *buf;
116 char *ptr;
117
118 if (!flags)
119 flags="";
120
121 do_cgi_select(name, optvalues, optlabels, default_value,
122 list_size, flags, cnt_bytes, &cnt);
123
124 buf=malloc(cnt);
125
126 if (!buf)
127 return NULL;
128
129 ptr=buf;
130 do_cgi_select(name, optvalues, optlabels, default_value,
131 list_size, flags, save_bytes, &ptr);
132 *ptr=0;
133 return buf;
134 }
135