Blame


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