fmtquote.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
fmtquote.c (5023B) | |
--- | |
1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */ | |
2 #include <stdarg.h> | |
3 #include <string.h> | |
4 #include "plan9.h" | |
5 #include "fmt.h" | |
6 #include "fmtdef.h" | |
7 | |
8 /* | |
9 * How many bytes of output UTF will be produced by quoting (if necessar… | |
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: | |
15 * NUL in input | |
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. | |
20 */ | |
21 void | |
22 __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int shar… | |
23 { | |
24 int w; | |
25 Rune c; | |
26 | |
27 q->quoted = 0; | |
28 q->nbytesout = 0; | |
29 q->nrunesout = 0; | |
30 q->nbytesin = 0; | |
31 q->nrunesin = 0; | |
32 if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){ | |
33 if(nout < 2) | |
34 return; | |
35 q->quoted = 1; | |
36 q->nbytesout = 2; | |
37 q->nrunesout = 2; | |
38 } | |
39 for(; nin!=0; nin--){ | |
40 if(s) | |
41 w = chartorune(&c, s); | |
42 else{ | |
43 c = *r; | |
44 w = runelen(c); | |
45 } | |
46 | |
47 if(c == '\0') | |
48 break; | |
49 if(runesout){ | |
50 if(q->nrunesout+1 > nout) | |
51 break; | |
52 }else{ | |
53 if(q->nbytesout+w > nout) | |
54 break; | |
55 } | |
56 | |
57 if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fm… | |
58 if(!q->quoted){ | |
59 if(runesout){ | |
60 if(1+q->nrunesout+1+1 > nout) … | |
61 break; | |
62 }else{ | |
63 if(1+q->nbytesout+w+1 > nout) … | |
64 break; | |
65 } | |
66 q->nrunesout += 2; /* include quo… | |
67 q->nbytesout += 2; /* include quo… | |
68 q->quoted = 1; | |
69 } | |
70 if(c == '\'') { | |
71 if(runesout){ | |
72 if(1+q->nrunesout+1 > nout) … | |
73 break; | |
74 }else{ | |
75 if(1+q->nbytesout+w > nout) … | |
76 break; | |
77 } | |
78 q->nbytesout++; | |
79 q->nrunesout++; /* quotes reprodu… | |
80 } | |
81 } | |
82 | |
83 /* advance input */ | |
84 if(s) | |
85 s += w; | |
86 else | |
87 r++; | |
88 q->nbytesin += w; | |
89 q->nrunesin++; | |
90 | |
91 /* advance output */ | |
92 q->nbytesout += w; | |
93 q->nrunesout++; | |
94 | |
95 #ifndef PLAN9PORT | |
96 /* ANSI requires precision in bytes, not Runes. */ | |
97 nin-= w-1; /* and then n-- in the loop */ | |
98 #endif | |
99 } | |
100 } | |
101 | |
102 static int | |
103 qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f) | |
104 { | |
105 Rune r, *rm, *rme; | |
106 char *t, *s, *m, *me; | |
107 Rune *rt, *rs; | |
108 ulong fl; | |
109 int nc, w; | |
110 | |
111 m = sin; | |
112 me = m + q->nbytesin; | |
113 rm = rin; | |
114 rme = rm + q->nrunesin; | |
115 | |
116 fl = f->flags; | |
117 w = 0; | |
118 if(fl & FmtWidth) | |
119 w = f->width; | |
120 if(f->runes){ | |
121 if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0) | |
122 return -1; | |
123 }else{ | |
124 if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0) | |
125 return -1; | |
126 } | |
127 t = (char*)f->to; | |
128 s = (char*)f->stop; | |
129 rt = (Rune*)f->to; | |
130 rs = (Rune*)f->stop; | |
131 if(f->runes) | |
132 FMTRCHAR(f, rt, rs, '\''); | |
133 else | |
134 FMTRUNE(f, t, s, '\''); | |
135 for(nc = q->nrunesin; nc > 0; nc--){ | |
136 if(sin){ | |
137 r = *(uchar*)m; | |
138 if(r < Runeself) | |
139 m++; | |
140 else if((me - m) >= UTFmax || fullrune(m, me-m)) | |
141 m += chartorune(&r, m); | |
142 else | |
143 break; | |
144 }else{ | |
145 if(rm >= rme) | |
146 break; | |
147 r = *(uchar*)rm++; | |
148 } | |
149 if(f->runes){ | |
150 FMTRCHAR(f, rt, rs, r); | |
151 if(r == '\'') | |
152 FMTRCHAR(f, rt, rs, r); | |
153 }else{ | |
154 FMTRUNE(f, t, s, r); | |
155 if(r == '\'') | |
156 FMTRUNE(f, t, s, r); | |
157 } | |
158 } | |
159 | |
160 if(f->runes){ | |
161 FMTRCHAR(f, rt, rs, '\''); | |
162 USED(rs); | |
163 f->nfmt += rt - (Rune *)f->to; | |
164 f->to = rt; | |
165 if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0) | |
166 return -1; | |
167 }else{ | |
168 FMTRUNE(f, t, s, '\''); | |
169 USED(s); | |
170 f->nfmt += t - (char *)f->to; | |
171 f->to = t; | |
172 if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0) | |
173 return -1; | |
174 } | |
175 return 0; | |
176 } | |
177 | |
178 int | |
179 __quotestrfmt(int runesin, Fmt *f) | |
180 { | |
181 int nin, outlen; | |
182 Rune *r; | |
183 char *s; | |
184 Quoteinfo q; | |
185 | |
186 nin = -1; | |
187 if(f->flags&FmtPrec) | |
188 nin = f->prec; | |
189 if(runesin){ | |
190 r = va_arg(f->args, Rune *); | |
191 s = nil; | |
192 }else{ | |
193 s = va_arg(f->args, char *); | |
194 r = nil; | |
195 } | |
196 if(!s && !r) | |
197 return __fmtcpy(f, (void*)"<nil>", 5, 5); | |
198 | |
199 if(f->flush) | |
200 outlen = 0x7FFFFFFF; /* if we can flush, no outpu… | |
201 else if(f->runes) | |
202 outlen = (Rune*)f->stop - (Rune*)f->to; | |
203 else | |
204 outlen = (char*)f->stop - (char*)f->to; | |
205 | |
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… | |
208 | |
209 if(runesin){ | |
210 if(!q.quoted) | |
211 return __fmtrcpy(f, r, q.nrunesin); | |
212 return qstrfmt(nil, r, &q, f); | |
213 } | |
214 | |
215 if(!q.quoted) | |
216 return __fmtcpy(f, s, q.nrunesin, q.nbytesin); | |
217 return qstrfmt(s, nil, &q, f); | |
218 } | |
219 | |
220 int | |
221 quotestrfmt(Fmt *f) | |
222 { | |
223 return __quotestrfmt(0, f); | |
224 } | |
225 | |
226 int | |
227 quoterunestrfmt(Fmt *f) | |
228 { | |
229 return __quotestrfmt(1, f); | |
230 } | |
231 | |
232 void | |
233 quotefmtinstall(void) | |
234 { | |
235 fmtinstall('q', quotestrfmt); | |
236 fmtinstall('Q', quoterunestrfmt); | |
237 } | |
238 | |
239 int | |
240 __needsquotes(char *s, int *quotelenp) | |
241 { | |
242 Quoteinfo q; | |
243 | |
244 __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0); | |
245 *quotelenp = q.nbytesout; | |
246 | |
247 return q.quoted; | |
248 } | |
249 | |
250 int | |
251 __runeneedsquotes(Rune *r, int *quotelenp) | |
252 { | |
253 Quoteinfo q; | |
254 | |
255 __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0); | |
256 *quotelenp = q.nrunesout; | |
257 | |
258 return q.quoted; | |
259 } |