Blame


1 f08fdedc 2003-11-23 devnull /*
2 f08fdedc 2003-11-23 devnull * The authors of this software are Rob Pike and Ken Thompson.
3 f08fdedc 2003-11-23 devnull * Copyright (c) 2002 by Lucent Technologies.
4 f08fdedc 2003-11-23 devnull * Permission to use, copy, modify, and distribute this software for any
5 f08fdedc 2003-11-23 devnull * purpose without fee is hereby granted, provided that this entire notice
6 f08fdedc 2003-11-23 devnull * is included in all copies of any software which is or includes a copy
7 f08fdedc 2003-11-23 devnull * or modification of this software and in all copies of the supporting
8 f08fdedc 2003-11-23 devnull * documentation for such software.
9 f08fdedc 2003-11-23 devnull * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 f08fdedc 2003-11-23 devnull * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
11 f08fdedc 2003-11-23 devnull * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 f08fdedc 2003-11-23 devnull * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
13 f08fdedc 2003-11-23 devnull */
14 f08fdedc 2003-11-23 devnull #include <u.h>
15 f08fdedc 2003-11-23 devnull #include <libc.h>
16 f08fdedc 2003-11-23 devnull #include "fmt.h"
17 f08fdedc 2003-11-23 devnull #include "fmtdef.h"
18 f08fdedc 2003-11-23 devnull
19 f08fdedc 2003-11-23 devnull extern int (*doquote)(int);
20 f08fdedc 2003-11-23 devnull
21 f08fdedc 2003-11-23 devnull /*
22 f08fdedc 2003-11-23 devnull * How many bytes of output UTF will be produced by quoting (if necessary) this string?
23 f08fdedc 2003-11-23 devnull * How many runes? How much of the input will be consumed?
24 f08fdedc 2003-11-23 devnull * The parameter q is filled in by _quotesetup.
25 f08fdedc 2003-11-23 devnull * The string may be UTF or Runes (s or r).
26 f08fdedc 2003-11-23 devnull * Return count does not include NUL.
27 f08fdedc 2003-11-23 devnull * Terminate the scan at the first of:
28 f08fdedc 2003-11-23 devnull * NUL in input
29 f08fdedc 2003-11-23 devnull * count exceeded in input
30 f08fdedc 2003-11-23 devnull * count exceeded on output
31 f08fdedc 2003-11-23 devnull * *ninp is set to number of input bytes accepted.
32 f08fdedc 2003-11-23 devnull * nin may be <0 initially, to avoid checking input by count.
33 f08fdedc 2003-11-23 devnull */
34 f08fdedc 2003-11-23 devnull void
35 f08fdedc 2003-11-23 devnull __quotesetup(char *s, int nin, int nout, Quoteinfo *q, int sharp)
36 f08fdedc 2003-11-23 devnull {
37 f08fdedc 2003-11-23 devnull int c;
38 f08fdedc 2003-11-23 devnull
39 f08fdedc 2003-11-23 devnull q->quoted = 0;
40 f08fdedc 2003-11-23 devnull q->nbytesout = 0;
41 f08fdedc 2003-11-23 devnull q->nrunesout = 0;
42 f08fdedc 2003-11-23 devnull q->nbytesin = 0;
43 f08fdedc 2003-11-23 devnull q->nrunesin = 0;
44 f08fdedc 2003-11-23 devnull if(sharp || nin==0 || *s=='\0'){
45 f08fdedc 2003-11-23 devnull if(nout < 2)
46 f08fdedc 2003-11-23 devnull return;
47 f08fdedc 2003-11-23 devnull q->quoted = 1;
48 f08fdedc 2003-11-23 devnull q->nbytesout = 2;
49 f08fdedc 2003-11-23 devnull q->nrunesout = 2;
50 f08fdedc 2003-11-23 devnull }
51 f08fdedc 2003-11-23 devnull for(; nin!=0; nin-=1){
52 f08fdedc 2003-11-23 devnull c = *s;
53 f08fdedc 2003-11-23 devnull
54 f08fdedc 2003-11-23 devnull if(c == '\0')
55 f08fdedc 2003-11-23 devnull break;
56 f08fdedc 2003-11-23 devnull if(q->nrunesout+1 > nout)
57 f08fdedc 2003-11-23 devnull break;
58 f08fdedc 2003-11-23 devnull
59 f08fdedc 2003-11-23 devnull if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquote(c))){
60 f08fdedc 2003-11-23 devnull if(!q->quoted){
61 f08fdedc 2003-11-23 devnull if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
62 f08fdedc 2003-11-23 devnull break;
63 f08fdedc 2003-11-23 devnull q->nrunesout += 2; /* include quotes */
64 f08fdedc 2003-11-23 devnull q->nbytesout += 2; /* include quotes */
65 f08fdedc 2003-11-23 devnull q->quoted = 1;
66 f08fdedc 2003-11-23 devnull }
67 f08fdedc 2003-11-23 devnull if(c == '\'') {
68 f08fdedc 2003-11-23 devnull q->nbytesout++;
69 f08fdedc 2003-11-23 devnull q->nrunesout++; /* quotes reproduce as two characters */
70 f08fdedc 2003-11-23 devnull }
71 f08fdedc 2003-11-23 devnull }
72 f08fdedc 2003-11-23 devnull
73 f08fdedc 2003-11-23 devnull /* advance input */
74 f08fdedc 2003-11-23 devnull s++;
75 f08fdedc 2003-11-23 devnull q->nbytesin++;
76 f08fdedc 2003-11-23 devnull q->nrunesin++;
77 f08fdedc 2003-11-23 devnull
78 f08fdedc 2003-11-23 devnull /* advance output */
79 f08fdedc 2003-11-23 devnull q->nbytesout++;
80 f08fdedc 2003-11-23 devnull q->nrunesout++;
81 f08fdedc 2003-11-23 devnull }
82 f08fdedc 2003-11-23 devnull }
83 f08fdedc 2003-11-23 devnull
84 f08fdedc 2003-11-23 devnull static int
85 f08fdedc 2003-11-23 devnull qstrfmt(char *sin, Quoteinfo *q, Fmt *f)
86 f08fdedc 2003-11-23 devnull {
87 f08fdedc 2003-11-23 devnull int r;
88 f08fdedc 2003-11-23 devnull char *t, *s, *m, *me;
89 f08fdedc 2003-11-23 devnull ulong fl;
90 f08fdedc 2003-11-23 devnull int nc, w;
91 f08fdedc 2003-11-23 devnull
92 f08fdedc 2003-11-23 devnull m = sin;
93 f08fdedc 2003-11-23 devnull me = m + q->nbytesin;
94 f08fdedc 2003-11-23 devnull
95 f08fdedc 2003-11-23 devnull w = f->width;
96 f08fdedc 2003-11-23 devnull fl = f->flags;
97 f08fdedc 2003-11-23 devnull if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
98 f08fdedc 2003-11-23 devnull return -1;
99 f08fdedc 2003-11-23 devnull t = f->to;
100 f08fdedc 2003-11-23 devnull s = f->stop;
101 f08fdedc 2003-11-23 devnull FMTCHAR(f, t, s, '\'');
102 f08fdedc 2003-11-23 devnull for(nc = q->nrunesin; nc > 0; nc--){
103 f08fdedc 2003-11-23 devnull r = *(uchar*)m++;
104 f08fdedc 2003-11-23 devnull FMTCHAR(f, t, s, r);
105 f08fdedc 2003-11-23 devnull if(r == '\'')
106 f08fdedc 2003-11-23 devnull FMTCHAR(f, t, s, r);
107 f08fdedc 2003-11-23 devnull }
108 f08fdedc 2003-11-23 devnull
109 f08fdedc 2003-11-23 devnull FMTCHAR(f, t, s, '\'');
110 f08fdedc 2003-11-23 devnull f->nfmt += t - (char *)f->to;
111 f08fdedc 2003-11-23 devnull f->to = t;
112 f08fdedc 2003-11-23 devnull if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
113 f08fdedc 2003-11-23 devnull return -1;
114 f08fdedc 2003-11-23 devnull return 0;
115 f08fdedc 2003-11-23 devnull }
116 f08fdedc 2003-11-23 devnull
117 f08fdedc 2003-11-23 devnull int
118 f08fdedc 2003-11-23 devnull __quotestrfmt(int runesin, Fmt *f)
119 f08fdedc 2003-11-23 devnull {
120 f08fdedc 2003-11-23 devnull int outlen;
121 f08fdedc 2003-11-23 devnull char *s;
122 f08fdedc 2003-11-23 devnull Quoteinfo q;
123 f08fdedc 2003-11-23 devnull
124 f08fdedc 2003-11-23 devnull f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable for %s %S in easy case */
125 f08fdedc 2003-11-23 devnull s = va_arg(f->args, char *);
126 f08fdedc 2003-11-23 devnull if(!s)
127 f08fdedc 2003-11-23 devnull return __fmtcpy(f, "<nil>", 5, 5);
128 f08fdedc 2003-11-23 devnull
129 f08fdedc 2003-11-23 devnull if(f->flush)
130 f08fdedc 2003-11-23 devnull outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
131 f08fdedc 2003-11-23 devnull else
132 f08fdedc 2003-11-23 devnull outlen = (char*)f->stop - (char*)f->to;
133 f08fdedc 2003-11-23 devnull
134 f08fdedc 2003-11-23 devnull __quotesetup(s, -1, outlen, &q, f->flags&FmtSharp);
135 f08fdedc 2003-11-23 devnull
136 f08fdedc 2003-11-23 devnull if(!q.quoted)
137 f08fdedc 2003-11-23 devnull return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
138 f08fdedc 2003-11-23 devnull return qstrfmt(s, &q, f);
139 f08fdedc 2003-11-23 devnull }
140 f08fdedc 2003-11-23 devnull
141 f08fdedc 2003-11-23 devnull int
142 f08fdedc 2003-11-23 devnull quotestrfmt(Fmt *f)
143 f08fdedc 2003-11-23 devnull {
144 f08fdedc 2003-11-23 devnull return __quotestrfmt(0, f);
145 f08fdedc 2003-11-23 devnull }
146 f08fdedc 2003-11-23 devnull
147 f08fdedc 2003-11-23 devnull void
148 f08fdedc 2003-11-23 devnull quotefmtinstall(void)
149 f08fdedc 2003-11-23 devnull {
150 f08fdedc 2003-11-23 devnull fmtinstall('q', quotestrfmt);
151 f08fdedc 2003-11-23 devnull }
152 f08fdedc 2003-11-23 devnull
153 f08fdedc 2003-11-23 devnull int
154 f08fdedc 2003-11-23 devnull __needsquotes(char *s, int *quotelenp)
155 f08fdedc 2003-11-23 devnull {
156 f08fdedc 2003-11-23 devnull Quoteinfo q;
157 f08fdedc 2003-11-23 devnull
158 f08fdedc 2003-11-23 devnull __quotesetup(s, -1, 0x7FFFFFFF, &q, 0);
159 f08fdedc 2003-11-23 devnull *quotelenp = q.nbytesout;
160 f08fdedc 2003-11-23 devnull
161 f08fdedc 2003-11-23 devnull return q.quoted;
162 f08fdedc 2003-11-23 devnull }