Blame


1 b2cfc4e2 2003-09-30 devnull /*
2 b2cfc4e2 2003-09-30 devnull * The authors of this software are Rob Pike and Ken Thompson.
3 b2cfc4e2 2003-09-30 devnull * Copyright (c) 2002 by Lucent Technologies.
4 b2cfc4e2 2003-09-30 devnull * Permission to use, copy, modify, and distribute this software for any
5 b2cfc4e2 2003-09-30 devnull * purpose without fee is hereby granted, provided that this entire notice
6 b2cfc4e2 2003-09-30 devnull * is included in all copies of any software which is or includes a copy
7 b2cfc4e2 2003-09-30 devnull * or modification of this software and in all copies of the supporting
8 b2cfc4e2 2003-09-30 devnull * documentation for such software.
9 b2cfc4e2 2003-09-30 devnull * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 b2cfc4e2 2003-09-30 devnull * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
11 b2cfc4e2 2003-09-30 devnull * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 b2cfc4e2 2003-09-30 devnull * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
13 b2cfc4e2 2003-09-30 devnull */
14 b2cfc4e2 2003-09-30 devnull #include <stdarg.h>
15 b2cfc4e2 2003-09-30 devnull #include <string.h>
16 b2cfc4e2 2003-09-30 devnull #include "utf.h"
17 b2cfc4e2 2003-09-30 devnull #include "fmt.h"
18 b2cfc4e2 2003-09-30 devnull #include "fmtdef.h"
19 b2cfc4e2 2003-09-30 devnull
20 b2cfc4e2 2003-09-30 devnull /*
21 b2cfc4e2 2003-09-30 devnull * How many bytes of output UTF will be produced by quoting (if necessary) this string?
22 b2cfc4e2 2003-09-30 devnull * How many runes? How much of the input will be consumed?
23 b2cfc4e2 2003-09-30 devnull * The parameter q is filled in by __quotesetup.
24 b2cfc4e2 2003-09-30 devnull * The string may be UTF or Runes (s or r).
25 b2cfc4e2 2003-09-30 devnull * Return count does not include NUL.
26 b2cfc4e2 2003-09-30 devnull * Terminate the scan at the first of:
27 b2cfc4e2 2003-09-30 devnull * NUL in input
28 b2cfc4e2 2003-09-30 devnull * count exceeded in input
29 b2cfc4e2 2003-09-30 devnull * count exceeded on output
30 b2cfc4e2 2003-09-30 devnull * *ninp is set to number of input bytes accepted.
31 b2cfc4e2 2003-09-30 devnull * nin may be <0 initially, to avoid checking input by count.
32 b2cfc4e2 2003-09-30 devnull */
33 b2cfc4e2 2003-09-30 devnull void
34 b2cfc4e2 2003-09-30 devnull __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
35 b2cfc4e2 2003-09-30 devnull {
36 b2cfc4e2 2003-09-30 devnull int w;
37 b2cfc4e2 2003-09-30 devnull Rune c;
38 b2cfc4e2 2003-09-30 devnull
39 b2cfc4e2 2003-09-30 devnull q->quoted = 0;
40 b2cfc4e2 2003-09-30 devnull q->nbytesout = 0;
41 b2cfc4e2 2003-09-30 devnull q->nrunesout = 0;
42 b2cfc4e2 2003-09-30 devnull q->nbytesin = 0;
43 b2cfc4e2 2003-09-30 devnull q->nrunesin = 0;
44 b2cfc4e2 2003-09-30 devnull if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
45 b2cfc4e2 2003-09-30 devnull if(nout < 2)
46 b2cfc4e2 2003-09-30 devnull return;
47 b2cfc4e2 2003-09-30 devnull q->quoted = 1;
48 b2cfc4e2 2003-09-30 devnull q->nbytesout = 2;
49 b2cfc4e2 2003-09-30 devnull q->nrunesout = 2;
50 b2cfc4e2 2003-09-30 devnull }
51 b2cfc4e2 2003-09-30 devnull for(; nin!=0; nin-=w){
52 b2cfc4e2 2003-09-30 devnull if(s)
53 b2cfc4e2 2003-09-30 devnull w = chartorune(&c, s);
54 b2cfc4e2 2003-09-30 devnull else{
55 b2cfc4e2 2003-09-30 devnull c = *r;
56 b2cfc4e2 2003-09-30 devnull w = runelen(c);
57 b2cfc4e2 2003-09-30 devnull }
58 b2cfc4e2 2003-09-30 devnull
59 b2cfc4e2 2003-09-30 devnull if(c == '\0')
60 b2cfc4e2 2003-09-30 devnull break;
61 b2cfc4e2 2003-09-30 devnull if(runesout){
62 b2cfc4e2 2003-09-30 devnull if(q->nrunesout+1 > nout)
63 b2cfc4e2 2003-09-30 devnull break;
64 b2cfc4e2 2003-09-30 devnull }else{
65 b2cfc4e2 2003-09-30 devnull if(q->nbytesout+w > nout)
66 b2cfc4e2 2003-09-30 devnull break;
67 b2cfc4e2 2003-09-30 devnull }
68 b2cfc4e2 2003-09-30 devnull
69 b2cfc4e2 2003-09-30 devnull if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
70 b2cfc4e2 2003-09-30 devnull if(!q->quoted){
71 b2cfc4e2 2003-09-30 devnull if(runesout){
72 b2cfc4e2 2003-09-30 devnull if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
73 b2cfc4e2 2003-09-30 devnull break;
74 b2cfc4e2 2003-09-30 devnull }else{
75 b2cfc4e2 2003-09-30 devnull if(1+q->nbytesout+w+1 > nout) /* no room for quotes */
76 b2cfc4e2 2003-09-30 devnull break;
77 b2cfc4e2 2003-09-30 devnull }
78 b2cfc4e2 2003-09-30 devnull q->nrunesout += 2; /* include quotes */
79 b2cfc4e2 2003-09-30 devnull q->nbytesout += 2; /* include quotes */
80 b2cfc4e2 2003-09-30 devnull q->quoted = 1;
81 b2cfc4e2 2003-09-30 devnull }
82 b2cfc4e2 2003-09-30 devnull if(c == '\'') {
83 b2cfc4e2 2003-09-30 devnull if(runesout){
84 b2cfc4e2 2003-09-30 devnull if(1+q->nrunesout+1 > nout) /* no room for quotes */
85 b2cfc4e2 2003-09-30 devnull break;
86 b2cfc4e2 2003-09-30 devnull }else{
87 b2cfc4e2 2003-09-30 devnull if(1+q->nbytesout+w > nout) /* no room for quotes */
88 b2cfc4e2 2003-09-30 devnull break;
89 b2cfc4e2 2003-09-30 devnull }
90 b2cfc4e2 2003-09-30 devnull q->nbytesout++;
91 b2cfc4e2 2003-09-30 devnull q->nrunesout++; /* quotes reproduce as two characters */
92 b2cfc4e2 2003-09-30 devnull }
93 b2cfc4e2 2003-09-30 devnull }
94 b2cfc4e2 2003-09-30 devnull
95 b2cfc4e2 2003-09-30 devnull /* advance input */
96 b2cfc4e2 2003-09-30 devnull if(s)
97 b2cfc4e2 2003-09-30 devnull s += w;
98 b2cfc4e2 2003-09-30 devnull else
99 b2cfc4e2 2003-09-30 devnull r++;
100 b2cfc4e2 2003-09-30 devnull q->nbytesin += w;
101 b2cfc4e2 2003-09-30 devnull q->nrunesin++;
102 b2cfc4e2 2003-09-30 devnull
103 b2cfc4e2 2003-09-30 devnull /* advance output */
104 b2cfc4e2 2003-09-30 devnull q->nbytesout += w;
105 b2cfc4e2 2003-09-30 devnull q->nrunesout++;
106 b2cfc4e2 2003-09-30 devnull }
107 b2cfc4e2 2003-09-30 devnull }
108 b2cfc4e2 2003-09-30 devnull
109 b2cfc4e2 2003-09-30 devnull static int
110 b2cfc4e2 2003-09-30 devnull qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
111 b2cfc4e2 2003-09-30 devnull {
112 b2cfc4e2 2003-09-30 devnull Rune r, *rm, *rme;
113 b2cfc4e2 2003-09-30 devnull char *t, *s, *m, *me;
114 b2cfc4e2 2003-09-30 devnull Rune *rt, *rs;
115 b2cfc4e2 2003-09-30 devnull ulong fl;
116 b2cfc4e2 2003-09-30 devnull int nc, w;
117 b2cfc4e2 2003-09-30 devnull
118 b2cfc4e2 2003-09-30 devnull m = sin;
119 b2cfc4e2 2003-09-30 devnull me = m + q->nbytesin;
120 b2cfc4e2 2003-09-30 devnull rm = rin;
121 b2cfc4e2 2003-09-30 devnull rme = rm + q->nrunesin;
122 b2cfc4e2 2003-09-30 devnull
123 b2cfc4e2 2003-09-30 devnull w = f->width;
124 b2cfc4e2 2003-09-30 devnull fl = f->flags;
125 b2cfc4e2 2003-09-30 devnull if(f->runes){
126 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
127 b2cfc4e2 2003-09-30 devnull return -1;
128 b2cfc4e2 2003-09-30 devnull }else{
129 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
130 b2cfc4e2 2003-09-30 devnull return -1;
131 b2cfc4e2 2003-09-30 devnull }
132 b2cfc4e2 2003-09-30 devnull t = (char*)f->to;
133 b2cfc4e2 2003-09-30 devnull s = (char*)f->stop;
134 b2cfc4e2 2003-09-30 devnull rt = (Rune*)f->to;
135 b2cfc4e2 2003-09-30 devnull rs = (Rune*)f->stop;
136 b2cfc4e2 2003-09-30 devnull if(f->runes)
137 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, '\'');
138 b2cfc4e2 2003-09-30 devnull else
139 b2cfc4e2 2003-09-30 devnull FMTRUNE(f, t, s, '\'');
140 b2cfc4e2 2003-09-30 devnull for(nc = q->nrunesin; nc > 0; nc--){
141 b2cfc4e2 2003-09-30 devnull if(sin){
142 b2cfc4e2 2003-09-30 devnull r = *(uchar*)m;
143 b2cfc4e2 2003-09-30 devnull if(r < Runeself)
144 b2cfc4e2 2003-09-30 devnull m++;
145 b2cfc4e2 2003-09-30 devnull else if((me - m) >= UTFmax || fullrune(m, me-m))
146 b2cfc4e2 2003-09-30 devnull m += chartorune(&r, m);
147 b2cfc4e2 2003-09-30 devnull else
148 b2cfc4e2 2003-09-30 devnull break;
149 b2cfc4e2 2003-09-30 devnull }else{
150 b2cfc4e2 2003-09-30 devnull if(rm >= rme)
151 b2cfc4e2 2003-09-30 devnull break;
152 b2cfc4e2 2003-09-30 devnull r = *(uchar*)rm++;
153 b2cfc4e2 2003-09-30 devnull }
154 b2cfc4e2 2003-09-30 devnull if(f->runes){
155 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, r);
156 b2cfc4e2 2003-09-30 devnull if(r == '\'')
157 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, r);
158 b2cfc4e2 2003-09-30 devnull }else{
159 b2cfc4e2 2003-09-30 devnull FMTRUNE(f, t, s, r);
160 b2cfc4e2 2003-09-30 devnull if(r == '\'')
161 b2cfc4e2 2003-09-30 devnull FMTRUNE(f, t, s, r);
162 b2cfc4e2 2003-09-30 devnull }
163 b2cfc4e2 2003-09-30 devnull }
164 b2cfc4e2 2003-09-30 devnull
165 b2cfc4e2 2003-09-30 devnull if(f->runes){
166 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, '\'');
167 b2cfc4e2 2003-09-30 devnull USED(rs);
168 b2cfc4e2 2003-09-30 devnull f->nfmt += rt - (Rune *)f->to;
169 b2cfc4e2 2003-09-30 devnull f->to = rt;
170 b2cfc4e2 2003-09-30 devnull if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
171 b2cfc4e2 2003-09-30 devnull return -1;
172 b2cfc4e2 2003-09-30 devnull }else{
173 b2cfc4e2 2003-09-30 devnull FMTRUNE(f, t, s, '\'');
174 b2cfc4e2 2003-09-30 devnull USED(s);
175 b2cfc4e2 2003-09-30 devnull f->nfmt += t - (char *)f->to;
176 b2cfc4e2 2003-09-30 devnull f->to = t;
177 b2cfc4e2 2003-09-30 devnull if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
178 b2cfc4e2 2003-09-30 devnull return -1;
179 b2cfc4e2 2003-09-30 devnull }
180 b2cfc4e2 2003-09-30 devnull return 0;
181 b2cfc4e2 2003-09-30 devnull }
182 b2cfc4e2 2003-09-30 devnull
183 b2cfc4e2 2003-09-30 devnull int
184 b2cfc4e2 2003-09-30 devnull __quotestrfmt(int runesin, Fmt *f)
185 b2cfc4e2 2003-09-30 devnull {
186 b2cfc4e2 2003-09-30 devnull int outlen;
187 b2cfc4e2 2003-09-30 devnull Rune *r;
188 b2cfc4e2 2003-09-30 devnull char *s;
189 b2cfc4e2 2003-09-30 devnull Quoteinfo q;
190 b2cfc4e2 2003-09-30 devnull
191 b2cfc4e2 2003-09-30 devnull f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable for %s %S in easy case */
192 b2cfc4e2 2003-09-30 devnull if(runesin){
193 b2cfc4e2 2003-09-30 devnull r = va_arg(f->args, Rune *);
194 b2cfc4e2 2003-09-30 devnull s = nil;
195 b2cfc4e2 2003-09-30 devnull }else{
196 b2cfc4e2 2003-09-30 devnull s = va_arg(f->args, char *);
197 b2cfc4e2 2003-09-30 devnull r = nil;
198 b2cfc4e2 2003-09-30 devnull }
199 b2cfc4e2 2003-09-30 devnull if(!s && !r)
200 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, (void*)"<nil>", 5, 5);
201 b2cfc4e2 2003-09-30 devnull
202 b2cfc4e2 2003-09-30 devnull if(f->flush)
203 b2cfc4e2 2003-09-30 devnull outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
204 b2cfc4e2 2003-09-30 devnull else if(f->runes)
205 b2cfc4e2 2003-09-30 devnull outlen = (Rune*)f->stop - (Rune*)f->to;
206 b2cfc4e2 2003-09-30 devnull else
207 b2cfc4e2 2003-09-30 devnull outlen = (char*)f->stop - (char*)f->to;
208 b2cfc4e2 2003-09-30 devnull
209 b2cfc4e2 2003-09-30 devnull __quotesetup(s, r, -1, outlen, &q, f->flags&FmtSharp, f->runes);
210 b2cfc4e2 2003-09-30 devnull //print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout);
211 b2cfc4e2 2003-09-30 devnull
212 b2cfc4e2 2003-09-30 devnull if(runesin){
213 b2cfc4e2 2003-09-30 devnull if(!q.quoted)
214 b2cfc4e2 2003-09-30 devnull return __fmtrcpy(f, r, q.nrunesin);
215 b2cfc4e2 2003-09-30 devnull return qstrfmt(nil, r, &q, f);
216 b2cfc4e2 2003-09-30 devnull }
217 b2cfc4e2 2003-09-30 devnull
218 b2cfc4e2 2003-09-30 devnull if(!q.quoted)
219 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
220 b2cfc4e2 2003-09-30 devnull return qstrfmt(s, nil, &q, f);
221 b2cfc4e2 2003-09-30 devnull }
222 b2cfc4e2 2003-09-30 devnull
223 b2cfc4e2 2003-09-30 devnull int
224 b2cfc4e2 2003-09-30 devnull quotestrfmt(Fmt *f)
225 b2cfc4e2 2003-09-30 devnull {
226 b2cfc4e2 2003-09-30 devnull return __quotestrfmt(0, f);
227 b2cfc4e2 2003-09-30 devnull }
228 b2cfc4e2 2003-09-30 devnull
229 b2cfc4e2 2003-09-30 devnull int
230 b2cfc4e2 2003-09-30 devnull quoterunestrfmt(Fmt *f)
231 b2cfc4e2 2003-09-30 devnull {
232 b2cfc4e2 2003-09-30 devnull return __quotestrfmt(1, f);
233 b2cfc4e2 2003-09-30 devnull }
234 b2cfc4e2 2003-09-30 devnull
235 b2cfc4e2 2003-09-30 devnull void
236 b2cfc4e2 2003-09-30 devnull quotefmtinstall(void)
237 b2cfc4e2 2003-09-30 devnull {
238 b2cfc4e2 2003-09-30 devnull fmtinstall('q', quotestrfmt);
239 b2cfc4e2 2003-09-30 devnull fmtinstall('Q', quoterunestrfmt);
240 b2cfc4e2 2003-09-30 devnull }
241 b2cfc4e2 2003-09-30 devnull
242 b2cfc4e2 2003-09-30 devnull int
243 b2cfc4e2 2003-09-30 devnull __needsquotes(char *s, int *quotelenp)
244 b2cfc4e2 2003-09-30 devnull {
245 b2cfc4e2 2003-09-30 devnull Quoteinfo q;
246 b2cfc4e2 2003-09-30 devnull
247 b2cfc4e2 2003-09-30 devnull __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
248 b2cfc4e2 2003-09-30 devnull *quotelenp = q.nbytesout;
249 b2cfc4e2 2003-09-30 devnull
250 b2cfc4e2 2003-09-30 devnull return q.quoted;
251 b2cfc4e2 2003-09-30 devnull }
252 b2cfc4e2 2003-09-30 devnull
253 b2cfc4e2 2003-09-30 devnull int
254 b2cfc4e2 2003-09-30 devnull __runeneedsquotes(Rune *r, int *quotelenp)
255 b2cfc4e2 2003-09-30 devnull {
256 b2cfc4e2 2003-09-30 devnull Quoteinfo q;
257 b2cfc4e2 2003-09-30 devnull
258 b2cfc4e2 2003-09-30 devnull __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
259 b2cfc4e2 2003-09-30 devnull *quotelenp = q.nrunesout;
260 b2cfc4e2 2003-09-30 devnull
261 b2cfc4e2 2003-09-30 devnull return q.quoted;
262 b2cfc4e2 2003-09-30 devnull }