6 * How many bytes of output UTF will be produced by quoting (if necessary) this string?
7 * How many runes? How much of the input will be consumed?
8 * The parameter q is filled in by _quotesetup.
9 * The string may be UTF or Runes (s or r).
10 * Return count does not include NUL.
11 * Terminate the scan at the first of:
13 * count exceeded in input
14 * count exceeded on output
15 * *ninp is set to number of input bytes accepted.
16 * nin may be <0 initially, to avoid checking input by count.
19 _quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
29 if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
38 w = chartorune(&c, s);
47 if(q->nrunesout+1 > nout)
50 if(q->nbytesout+w > nout)
54 if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquote(c))){
57 if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
60 if(1+q->nbytesout+w+1 > nout) /* no room for quotes */
63 q->nrunesout += 2; /* include quotes */
64 q->nbytesout += 2; /* include quotes */
69 if(1+q->nrunesout+1 > nout) /* no room for quotes */
72 if(1+q->nbytesout+w > nout) /* no room for quotes */
76 q->nrunesout++; /* quotes reproduce as two characters */
95 qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
104 me = m + q->nbytesin;
106 rme = rm + q->nrunesin;
111 if(!(fl & FmtLeft) && _rfmtpad(f, w - q->nrunesout) < 0)
114 if(!(fl & FmtLeft) && _fmtpad(f, w - q->nbytesout) < 0)
122 FMTRCHAR(f, rt, rs, '\'');
124 FMTRUNE(f, t, s, '\'');
125 for(nc = q->nrunesin; nc > 0; nc--){
130 else if((me - m) >= UTFmax || fullrune(m, me-m))
131 m += chartorune(&r, m);
140 FMTRCHAR(f, rt, rs, r);
142 FMTRCHAR(f, rt, rs, r);
151 FMTRCHAR(f, rt, rs, '\'');
153 f->nfmt += rt - (Rune *)f->to;
155 if(fl & FmtLeft && _rfmtpad(f, w - q->nrunesout) < 0)
158 FMTRUNE(f, t, s, '\'');
160 f->nfmt += t - (char *)f->to;
162 if(fl & FmtLeft && _fmtpad(f, w - q->nbytesout) < 0)
169 _quotestrfmt(int runesin, Fmt *f)
180 r = va_arg(f->args, Rune *);
183 s = va_arg(f->args, char *);
187 return _fmtcpy(f, "<nil>", 5, 5);
190 outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
192 outlen = (Rune*)f->stop - (Rune*)f->to;
194 outlen = (char*)f->stop - (char*)f->to;
196 _quotesetup(s, r, nin, outlen, &q, f->flags&FmtSharp, f->runes);
197 //print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout);
201 return _fmtrcpy(f, r, q.nrunesin);
202 return qstrfmt(nil, r, &q, f);
206 return _fmtcpy(f, s, q.nrunesin, q.nbytesin);
207 return qstrfmt(s, nil, &q, f);
213 return _quotestrfmt(0, f);
217 quoterunestrfmt(Fmt *f)
219 return _quotestrfmt(1, f);
223 quotefmtinstall(void)
225 fmtinstall('q', quotestrfmt);
226 fmtinstall('Q', quoterunestrfmt);
230 _needsquotes(char *s, int *quotelenp)
234 _quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
235 *quotelenp = q.nbytesout;
241 _runeneedsquotes(Rune *r, int *quotelenp)
245 _quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
246 *quotelenp = q.nrunesout;