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 (3609B) | |
--- | |
1 /* | |
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 noti… | |
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 IMPLI… | |
10 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES… | |
11 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY | |
12 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. | |
13 */ | |
14 #include <u.h> | |
15 #include <libc.h> | |
16 #include "fmt.h" | |
17 #include "fmtdef.h" | |
18 | |
19 extern int (*doquote)(int); | |
20 | |
21 /* | |
22 * How many bytes of output UTF will be produced by quoting (if necessar… | |
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: | |
28 * NUL in input | |
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. | |
33 */ | |
34 void | |
35 __quotesetup(char *s, int nin, int nout, Quoteinfo *q, int sharp) | |
36 { | |
37 int c; | |
38 | |
39 q->quoted = 0; | |
40 q->nbytesout = 0; | |
41 q->nrunesout = 0; | |
42 q->nbytesin = 0; | |
43 q->nrunesin = 0; | |
44 if(sharp || nin==0 || *s=='\0'){ | |
45 if(nout < 2) | |
46 return; | |
47 q->quoted = 1; | |
48 q->nbytesout = 2; | |
49 q->nrunesout = 2; | |
50 } | |
51 for(; nin!=0; nin-=1){ | |
52 c = *s; | |
53 | |
54 if(c == '\0') | |
55 break; | |
56 if(q->nrunesout+1 > nout) | |
57 break; | |
58 | |
59 if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquo… | |
60 if(!q->quoted){ | |
61 if(1+q->nrunesout+1+1 > nout) /* … | |
62 break; | |
63 q->nrunesout += 2; /* include quo… | |
64 q->nbytesout += 2; /* include quo… | |
65 q->quoted = 1; | |
66 } | |
67 if(c == '\'') { | |
68 q->nbytesout++; | |
69 q->nrunesout++; /* quotes reprodu… | |
70 } | |
71 } | |
72 | |
73 /* advance input */ | |
74 s++; | |
75 q->nbytesin++; | |
76 q->nrunesin++; | |
77 | |
78 /* advance output */ | |
79 q->nbytesout++; | |
80 q->nrunesout++; | |
81 } | |
82 } | |
83 | |
84 static int | |
85 qstrfmt(char *sin, Quoteinfo *q, Fmt *f) | |
86 { | |
87 int r; | |
88 char *t, *s, *m, *me; | |
89 ulong fl; | |
90 int nc, w; | |
91 | |
92 m = sin; | |
93 me = m + q->nbytesin; | |
94 | |
95 w = f->width; | |
96 fl = f->flags; | |
97 if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0) | |
98 return -1; | |
99 t = f->to; | |
100 s = f->stop; | |
101 FMTCHAR(f, t, s, '\''); | |
102 for(nc = q->nrunesin; nc > 0; nc--){ | |
103 r = *(uchar*)m++; | |
104 FMTCHAR(f, t, s, r); | |
105 if(r == '\'') | |
106 FMTCHAR(f, t, s, r); | |
107 } | |
108 | |
109 FMTCHAR(f, t, s, '\''); | |
110 f->nfmt += t - (char *)f->to; | |
111 f->to = t; | |
112 if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0) | |
113 return -1; | |
114 return 0; | |
115 } | |
116 | |
117 int | |
118 __quotestrfmt(int runesin, Fmt *f) | |
119 { | |
120 int outlen; | |
121 char *s; | |
122 Quoteinfo q; | |
123 | |
124 f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable fo… | |
125 s = va_arg(f->args, char *); | |
126 if(!s) | |
127 return __fmtcpy(f, "<nil>", 5, 5); | |
128 | |
129 if(f->flush) | |
130 outlen = 0x7FFFFFFF; /* if we can flush, no outpu… | |
131 else | |
132 outlen = (char*)f->stop - (char*)f->to; | |
133 | |
134 __quotesetup(s, -1, outlen, &q, f->flags&FmtSharp); | |
135 | |
136 if(!q.quoted) | |
137 return __fmtcpy(f, s, q.nrunesin, q.nbytesin); | |
138 return qstrfmt(s, &q, f); | |
139 } | |
140 | |
141 int | |
142 quotestrfmt(Fmt *f) | |
143 { | |
144 return __quotestrfmt(0, f); | |
145 } | |
146 | |
147 void | |
148 quotefmtinstall(void) | |
149 { | |
150 fmtinstall('q', quotestrfmt); | |
151 } | |
152 | |
153 int | |
154 __needsquotes(char *s, int *quotelenp) | |
155 { | |
156 Quoteinfo q; | |
157 | |
158 __quotesetup(s, -1, 0x7FFFFFFF, &q, 0); | |
159 *quotelenp = q.nbytesout; | |
160 | |
161 return q.quoted; | |
162 } |