2 * The authors of this software are Rob Pike and Ken Thompson.
3 * Copyright (c) 2002 by Lucent Technologies.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose without fee is hereby granted, provided that this entire notice
6 * is included in all copies of any software which is or includes a copy
7 * or modification of this software and in all copies of the supporting
8 * documentation for such software.
9 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
11 * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
21 * How many bytes of output UTF will be produced by quoting (if necessary) this string?
22 * How many runes? How much of the input will be consumed?
23 * The parameter q is filled in by __quotesetup.
24 * The string may be UTF or Runes (s or r).
25 * Return count does not include NUL.
26 * Terminate the scan at the first of:
28 * count exceeded in input
29 * count exceeded on output
30 * *ninp is set to number of input bytes accepted.
31 * nin may be <0 initially, to avoid checking input by count.
34 __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
44 if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
53 w = chartorune(&c, s);
62 if(q->nrunesout+1 > nout)
65 if(q->nbytesout+w > nout)
69 if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
72 if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
75 if(1+q->nbytesout+w+1 > nout) /* no room for quotes */
78 q->nrunesout += 2; /* include quotes */
79 q->nbytesout += 2; /* include quotes */
84 if(1+q->nrunesout+1 > nout) /* no room for quotes */
87 if(1+q->nbytesout+w > nout) /* no room for quotes */
91 q->nrunesout++; /* quotes reproduce as two characters */
110 qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
113 char *t, *s, *m, *me;
119 me = m + q->nbytesin;
121 rme = rm + q->nrunesin;
126 if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
129 if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
137 FMTRCHAR(f, rt, rs, '\'');
139 FMTRUNE(f, t, s, '\'');
140 for(nc = q->nrunesin; nc > 0; nc--){
145 else if((me - m) >= UTFmax || fullrune(m, me-m))
146 m += chartorune(&r, m);
155 FMTRCHAR(f, rt, rs, r);
157 FMTRCHAR(f, rt, rs, r);
166 FMTRCHAR(f, rt, rs, '\'');
168 f->nfmt += rt - (Rune *)f->to;
170 if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
173 FMTRUNE(f, t, s, '\'');
175 f->nfmt += t - (char *)f->to;
177 if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
184 __quotestrfmt(int runesin, Fmt *f)
195 r = va_arg(f->args, Rune *);
198 s = va_arg(f->args, char *);
202 return __fmtcpy(f, (void*)"<nil>", 5, 5);
205 outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
207 outlen = (Rune*)f->stop - (Rune*)f->to;
209 outlen = (char*)f->stop - (char*)f->to;
211 __quotesetup(s, r, nin, outlen, &q, f->flags&FmtSharp, f->runes);
212 //print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout);
216 return __fmtrcpy(f, r, q.nrunesin);
217 return qstrfmt(nil, r, &q, f);
221 return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
222 return qstrfmt(s, nil, &q, f);
228 return __quotestrfmt(0, f);
232 quoterunestrfmt(Fmt *f)
234 return __quotestrfmt(1, f);
238 quotefmtinstall(void)
240 fmtinstall('q', quotestrfmt);
241 fmtinstall('Q', quoterunestrfmt);
245 __needsquotes(char *s, int *quotelenp)
249 __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
250 *quotelenp = q.nbytesout;
256 __runeneedsquotes(Rune *r, int *quotelenp)
260 __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
261 *quotelenp = q.nrunesout;