1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
9 * How many bytes of output UTF will be produced by quoting (if necessary) this string?
10 * How many runes? How much of the input will be consumed?
11 * The parameter q is filled in by __quotesetup.
12 * The string may be UTF or Runes (s or r).
13 * Return count does not include NUL.
14 * Terminate the scan at the first of:
16 * count exceeded in input
17 * count exceeded on output
18 * *ninp is set to number of input bytes accepted.
19 * nin may be <0 initially, to avoid checking input by count.
22 __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
32 if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
41 w = chartorune(&c, s);
50 if(q->nrunesout+1 > nout)
53 if(q->nbytesout+w > nout)
57 if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
60 if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
63 if(1+q->nbytesout+w+1 > nout) /* no room for quotes */
66 q->nrunesout += 2; /* include quotes */
67 q->nbytesout += 2; /* include quotes */
72 if(1+q->nrunesout+1 > nout) /* no room for quotes */
75 if(1+q->nbytesout+w > nout) /* no room for quotes */
79 q->nrunesout++; /* quotes reproduce as two characters */
96 /* ANSI requires precision in bytes, not Runes. */
97 nin-= w-1; /* and then n-- in the loop */
103 qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
106 char *t, *s, *m, *me;
112 me = m + q->nbytesin;
114 rme = rm + q->nrunesin;
121 if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
124 if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
132 FMTRCHAR(f, rt, rs, '\'');
134 FMTRUNE(f, t, s, '\'');
135 for(nc = q->nrunesin; nc > 0; nc--){
140 else if((me - m) >= UTFmax || fullrune(m, me-m))
141 m += chartorune(&r, m);
150 FMTRCHAR(f, rt, rs, r);
152 FMTRCHAR(f, rt, rs, r);
161 FMTRCHAR(f, rt, rs, '\'');
163 f->nfmt += rt - (Rune *)f->to;
165 if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
168 FMTRUNE(f, t, s, '\'');
170 f->nfmt += t - (char *)f->to;
172 if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
179 __quotestrfmt(int runesin, Fmt *f)
190 r = va_arg(f->args, Rune *);
193 s = va_arg(f->args, char *);
197 return __fmtcpy(f, (void*)"<nil>", 5, 5);
200 outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
202 outlen = (Rune*)f->stop - (Rune*)f->to;
204 outlen = (char*)f->stop - (char*)f->to;
206 __quotesetup(s, r, nin, outlen, &q, f->flags&FmtSharp, f->runes);
207 /*print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout); */
211 return __fmtrcpy(f, r, q.nrunesin);
212 return qstrfmt(nil, r, &q, f);
216 return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
217 return qstrfmt(s, nil, &q, f);
223 return __quotestrfmt(0, f);
227 quoterunestrfmt(Fmt *f)
229 return __quotestrfmt(1, f);
233 quotefmtinstall(void)
235 fmtinstall('q', quotestrfmt);
236 fmtinstall('Q', quoterunestrfmt);
240 __needsquotes(char *s, int *quotelenp)
244 __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
245 *quotelenp = q.nbytesout;
251 __runeneedsquotes(Rune *r, int *quotelenp)
255 __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
256 *quotelenp = q.nrunesout;