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 ANY
11 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
19 extern int (*doquote)(int);
22 * How many bytes of output UTF will be produced by quoting (if necessary) this string?
23 * How many runes? How much of the input will be consumed?
24 * The parameter q is filled in by _quotesetup.
25 * The string may be UTF or Runes (s or r).
26 * Return count does not include NUL.
27 * Terminate the scan at the first of:
29 * count exceeded in input
30 * count exceeded on output
31 * *ninp is set to number of input bytes accepted.
32 * nin may be <0 initially, to avoid checking input by count.
35 __quotesetup(char *s, int nin, int nout, Quoteinfo *q, int sharp)
44 if(sharp || nin==0 || *s=='\0'){
51 for(; nin!=0; nin-=1){
56 if(q->nrunesout+1 > nout)
59 if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquote(c))){
61 if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
63 q->nrunesout += 2; /* include quotes */
64 q->nbytesout += 2; /* include quotes */
69 q->nrunesout++; /* quotes reproduce as two characters */
85 qstrfmt(char *sin, Quoteinfo *q, Fmt *f)
97 if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
101 FMTCHAR(f, t, s, '\'');
102 for(nc = q->nrunesin; nc > 0; nc--){
109 FMTCHAR(f, t, s, '\'');
110 f->nfmt += t - (char *)f->to;
112 if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
118 __quotestrfmt(int runesin, Fmt *f)
124 f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable for %s %S in easy case */
125 s = va_arg(f->args, char *);
127 return __fmtcpy(f, "<nil>", 5, 5);
130 outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
132 outlen = (char*)f->stop - (char*)f->to;
134 __quotesetup(s, -1, outlen, &q, f->flags&FmtSharp);
137 return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
138 return qstrfmt(s, &q, f);
144 return __quotestrfmt(0, f);
148 quotefmtinstall(void)
150 fmtinstall('q', quotestrfmt);
154 __needsquotes(char *s, int *quotelenp)
158 __quotesetup(s, -1, 0x7FFFFFFF, &q, 0);
159 *quotelenp = q.nbytesout;