##// END OF EJS Templates
charencode: allow clang-format oversight...
Augie Fackler -
r36243:6c87d411 default
parent child Browse files
Show More
@@ -1,58 +1,56 b''
1 1 # Files that just need to be migrated to the formatter.
2 2 # Do not add new files here!
3 3 mercurial/cext/base85.c
4 mercurial/cext/charencode.c
5 mercurial/cext/charencode.h
6 4 mercurial/cext/dirs.c
7 5 mercurial/cext/manifest.c
8 6 mercurial/cext/mpatch.c
9 7 mercurial/cext/osutil.c
10 8 mercurial/cext/revlog.c
11 9 # Vendored code that we should never format:
12 10 contrib/python-zstandard/c-ext/bufferutil.c
13 11 contrib/python-zstandard/c-ext/compressiondict.c
14 12 contrib/python-zstandard/c-ext/compressionparams.c
15 13 contrib/python-zstandard/c-ext/compressionwriter.c
16 14 contrib/python-zstandard/c-ext/compressobj.c
17 15 contrib/python-zstandard/c-ext/compressor.c
18 16 contrib/python-zstandard/c-ext/compressoriterator.c
19 17 contrib/python-zstandard/c-ext/constants.c
20 18 contrib/python-zstandard/c-ext/decompressionwriter.c
21 19 contrib/python-zstandard/c-ext/decompressobj.c
22 20 contrib/python-zstandard/c-ext/decompressor.c
23 21 contrib/python-zstandard/c-ext/decompressoriterator.c
24 22 contrib/python-zstandard/c-ext/frameparams.c
25 23 contrib/python-zstandard/c-ext/python-zstandard.h
26 24 contrib/python-zstandard/zstd.c
27 25 contrib/python-zstandard/zstd/common/bitstream.h
28 26 contrib/python-zstandard/zstd/common/entropy_common.c
29 27 contrib/python-zstandard/zstd/common/error_private.c
30 28 contrib/python-zstandard/zstd/common/error_private.h
31 29 contrib/python-zstandard/zstd/common/fse.h
32 30 contrib/python-zstandard/zstd/common/fse_decompress.c
33 31 contrib/python-zstandard/zstd/common/huf.h
34 32 contrib/python-zstandard/zstd/common/mem.h
35 33 contrib/python-zstandard/zstd/common/pool.c
36 34 contrib/python-zstandard/zstd/common/pool.h
37 35 contrib/python-zstandard/zstd/common/threading.c
38 36 contrib/python-zstandard/zstd/common/threading.h
39 37 contrib/python-zstandard/zstd/common/xxhash.c
40 38 contrib/python-zstandard/zstd/common/xxhash.h
41 39 contrib/python-zstandard/zstd/common/zstd_common.c
42 40 contrib/python-zstandard/zstd/common/zstd_errors.h
43 41 contrib/python-zstandard/zstd/common/zstd_internal.h
44 42 contrib/python-zstandard/zstd/compress/fse_compress.c
45 43 contrib/python-zstandard/zstd/compress/huf_compress.c
46 44 contrib/python-zstandard/zstd/compress/zstd_compress.c
47 45 contrib/python-zstandard/zstd/compress/zstd_opt.h
48 46 contrib/python-zstandard/zstd/compress/zstdmt_compress.c
49 47 contrib/python-zstandard/zstd/compress/zstdmt_compress.h
50 48 contrib/python-zstandard/zstd/decompress/huf_decompress.c
51 49 contrib/python-zstandard/zstd/decompress/zstd_decompress.c
52 50 contrib/python-zstandard/zstd/dictBuilder/cover.c
53 51 contrib/python-zstandard/zstd/dictBuilder/divsufsort.c
54 52 contrib/python-zstandard/zstd/dictBuilder/divsufsort.h
55 53 contrib/python-zstandard/zstd/dictBuilder/zdict.c
56 54 contrib/python-zstandard/zstd/dictBuilder/zdict.h
57 55 contrib/python-zstandard/zstd/zstd.h
58 56 hgext/fsmonitor/pywatchman/bser.c
@@ -1,401 +1,399 b''
1 1 /*
2 2 charencode.c - miscellaneous character encoding
3 3
4 4 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
5 5
6 6 This software may be used and distributed according to the terms of
7 7 the GNU General Public License, incorporated herein by reference.
8 8 */
9 9
10 10 #define PY_SSIZE_T_CLEAN
11 11 #include <Python.h>
12 12 #include <assert.h>
13 13
14 14 #include "charencode.h"
15 15 #include "compat.h"
16 16 #include "util.h"
17 17
18 18 #ifdef IS_PY3K
19 19 /* The mapping of Python types is meant to be temporary to get Python
20 20 * 3 to compile. We should remove this once Python 3 support is fully
21 21 * supported and proper types are used in the extensions themselves. */
22 22 #define PyInt_Type PyLong_Type
23 23 #define PyInt_AS_LONG PyLong_AS_LONG
24 24 #endif
25 25
26 26 /* clang-format off */
27 27 static const char lowertable[128] = {
28 28 '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
29 29 '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
30 30 '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
31 31 '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
32 32 '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
33 33 '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
34 34 '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
35 35 '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
36 36 '\x40',
37 37 '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', /* A-G */
38 38 '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', /* H-O */
39 39 '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', /* P-W */
40 40 '\x78', '\x79', '\x7a', /* X-Z */
41 41 '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
42 42 '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
43 43 '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
44 44 '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
45 45 '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f'
46 46 };
47 47
48 48 static const char uppertable[128] = {
49 49 '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
50 50 '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
51 51 '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
52 52 '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
53 53 '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
54 54 '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
55 55 '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
56 56 '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
57 57 '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
58 58 '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f',
59 59 '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
60 60 '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
61 61 '\x60',
62 62 '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', /* a-g */
63 63 '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', /* h-o */
64 64 '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', /* p-w */
65 65 '\x58', '\x59', '\x5a', /* x-z */
66 66 '\x7b', '\x7c', '\x7d', '\x7e', '\x7f'
67 67 };
68 68
69 69 /* 1: no escape, 2: \<c>, 6: \u<x> */
70 70 static const uint8_t jsonlentable[256] = {
71 71 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 6, 2, 2, 6, 6, /* b, t, n, f, r */
72 72 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
73 73 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* " */
74 74 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
75 75 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
76 76 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, /* \\ */
77 77 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
78 78 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, /* DEL */
79 79 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
80 80 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
81 81 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
82 82 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
83 83 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
84 84 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
85 85 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
86 86 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
87 87 };
88 88
89 89 static const uint8_t jsonparanoidlentable[128] = {
90 90 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 6, 2, 2, 6, 6, /* b, t, n, f, r */
91 91 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
92 92 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* " */
93 93 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 6, 1, /* <, > */
94 94 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
95 95 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, /* \\ */
96 96 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
97 97 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, /* DEL */
98 98 };
99 99
100 100 static const char hexchartable[16] = {
101 101 '0', '1', '2', '3', '4', '5', '6', '7',
102 102 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
103 103 };
104 104 /* clang-format on */
105 105
106 106 /*
107 107 * Turn a hex-encoded string into binary.
108 108 */
109 109 PyObject *unhexlify(const char *str, Py_ssize_t len)
110 110 {
111 111 PyObject *ret;
112 112 char *d;
113 113 Py_ssize_t i;
114 114
115 115 ret = PyBytes_FromStringAndSize(NULL, len / 2);
116 116
117 117 if (!ret)
118 118 return NULL;
119 119
120 120 d = PyBytes_AsString(ret);
121 121
122 122 for (i = 0; i < len;) {
123 123 int hi = hexdigit(str, i++);
124 124 int lo = hexdigit(str, i++);
125 125 *d++ = (hi << 4) | lo;
126 126 }
127 127
128 128 return ret;
129 129 }
130 130
131 131 PyObject *isasciistr(PyObject *self, PyObject *args)
132 132 {
133 133 const char *buf;
134 134 Py_ssize_t i, len;
135 135 if (!PyArg_ParseTuple(args, "s#:isasciistr", &buf, &len))
136 136 return NULL;
137 137 i = 0;
138 138 /* char array in PyStringObject should be at least 4-byte aligned */
139 139 if (((uintptr_t)buf & 3) == 0) {
140 140 const uint32_t *p = (const uint32_t *)buf;
141 141 for (; i < len / 4; i++) {
142 142 if (p[i] & 0x80808080U)
143 143 Py_RETURN_FALSE;
144 144 }
145 145 i *= 4;
146 146 }
147 147 for (; i < len; i++) {
148 148 if (buf[i] & 0x80)
149 149 Py_RETURN_FALSE;
150 150 }
151 151 Py_RETURN_TRUE;
152 152 }
153 153
154 static inline PyObject *_asciitransform(PyObject *str_obj,
155 const char table[128],
156 PyObject *fallback_fn)
154 static inline PyObject *
155 _asciitransform(PyObject *str_obj, const char table[128], PyObject *fallback_fn)
157 156 {
158 157 char *str, *newstr;
159 158 Py_ssize_t i, len;
160 159 PyObject *newobj = NULL;
161 160 PyObject *ret = NULL;
162 161
163 162 str = PyBytes_AS_STRING(str_obj);
164 163 len = PyBytes_GET_SIZE(str_obj);
165 164
166 165 newobj = PyBytes_FromStringAndSize(NULL, len);
167 166 if (!newobj)
168 167 goto quit;
169 168
170 169 newstr = PyBytes_AS_STRING(newobj);
171 170
172 171 for (i = 0; i < len; i++) {
173 172 char c = str[i];
174 173 if (c & 0x80) {
175 174 if (fallback_fn != NULL) {
176 ret = PyObject_CallFunctionObjArgs(fallback_fn,
177 str_obj, NULL);
175 ret = PyObject_CallFunctionObjArgs(
176 fallback_fn, str_obj, NULL);
178 177 } else {
179 178 PyObject *err = PyUnicodeDecodeError_Create(
180 179 "ascii", str, len, i, (i + 1),
181 180 "unexpected code byte");
182 181 PyErr_SetObject(PyExc_UnicodeDecodeError, err);
183 182 Py_XDECREF(err);
184 183 }
185 184 goto quit;
186 185 }
187 186 newstr[i] = table[(unsigned char)c];
188 187 }
189 188
190 189 ret = newobj;
191 190 Py_INCREF(ret);
192 191 quit:
193 192 Py_XDECREF(newobj);
194 193 return ret;
195 194 }
196 195
197 196 PyObject *asciilower(PyObject *self, PyObject *args)
198 197 {
199 198 PyObject *str_obj;
200 199 if (!PyArg_ParseTuple(args, "O!:asciilower", &PyBytes_Type, &str_obj))
201 200 return NULL;
202 201 return _asciitransform(str_obj, lowertable, NULL);
203 202 }
204 203
205 204 PyObject *asciiupper(PyObject *self, PyObject *args)
206 205 {
207 206 PyObject *str_obj;
208 207 if (!PyArg_ParseTuple(args, "O!:asciiupper", &PyBytes_Type, &str_obj))
209 208 return NULL;
210 209 return _asciitransform(str_obj, uppertable, NULL);
211 210 }
212 211
213 212 PyObject *make_file_foldmap(PyObject *self, PyObject *args)
214 213 {
215 214 PyObject *dmap, *spec_obj, *normcase_fallback;
216 215 PyObject *file_foldmap = NULL;
217 216 enum normcase_spec spec;
218 217 PyObject *k, *v;
219 218 dirstateTupleObject *tuple;
220 219 Py_ssize_t pos = 0;
221 220 const char *table;
222 221
223 if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap",
224 &PyDict_Type, &dmap,
225 &PyInt_Type, &spec_obj,
226 &PyFunction_Type, &normcase_fallback))
222 if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap", &PyDict_Type,
223 &dmap, &PyInt_Type, &spec_obj, &PyFunction_Type,
224 &normcase_fallback))
227 225 goto quit;
228 226
229 227 spec = (int)PyInt_AS_LONG(spec_obj);
230 228 switch (spec) {
231 229 case NORMCASE_LOWER:
232 230 table = lowertable;
233 231 break;
234 232 case NORMCASE_UPPER:
235 233 table = uppertable;
236 234 break;
237 235 case NORMCASE_OTHER:
238 236 table = NULL;
239 237 break;
240 238 default:
241 239 PyErr_SetString(PyExc_TypeError, "invalid normcasespec");
242 240 goto quit;
243 241 }
244 242
245 243 /* Add some more entries to deal with additions outside this
246 244 function. */
247 245 file_foldmap = _dict_new_presized((PyDict_Size(dmap) / 10) * 11);
248 246 if (file_foldmap == NULL)
249 247 goto quit;
250 248
251 249 while (PyDict_Next(dmap, &pos, &k, &v)) {
252 250 if (!dirstate_tuple_check(v)) {
253 251 PyErr_SetString(PyExc_TypeError,
254 252 "expected a dirstate tuple");
255 253 goto quit;
256 254 }
257 255
258 256 tuple = (dirstateTupleObject *)v;
259 257 if (tuple->state != 'r') {
260 258 PyObject *normed;
261 259 if (table != NULL) {
262 260 normed = _asciitransform(k, table,
263 261 normcase_fallback);
264 262 } else {
265 263 normed = PyObject_CallFunctionObjArgs(
266 264 normcase_fallback, k, NULL);
267 265 }
268 266
269 267 if (normed == NULL)
270 268 goto quit;
271 269 if (PyDict_SetItem(file_foldmap, normed, k) == -1) {
272 270 Py_DECREF(normed);
273 271 goto quit;
274 272 }
275 273 Py_DECREF(normed);
276 274 }
277 275 }
278 276 return file_foldmap;
279 277 quit:
280 278 Py_XDECREF(file_foldmap);
281 279 return NULL;
282 280 }
283 281
284 282 /* calculate length of JSON-escaped string; returns -1 if unsupported */
285 283 static Py_ssize_t jsonescapelen(const char *buf, Py_ssize_t len, bool paranoid)
286 284 {
287 285 Py_ssize_t i, esclen = 0;
288 286
289 287 if (paranoid) {
290 288 /* don't want to process multi-byte escapes in C */
291 289 for (i = 0; i < len; i++) {
292 290 char c = buf[i];
293 291 if (c & 0x80) {
294 292 PyErr_SetString(PyExc_ValueError,
295 293 "cannot process non-ascii str");
296 294 return -1;
297 295 }
298 296 esclen += jsonparanoidlentable[(unsigned char)c];
299 297 if (esclen < 0) {
300 298 PyErr_SetString(PyExc_MemoryError,
301 299 "overflow in jsonescapelen");
302 300 return -1;
303 301 }
304 302 }
305 303 } else {
306 304 for (i = 0; i < len; i++) {
307 305 char c = buf[i];
308 306 esclen += jsonlentable[(unsigned char)c];
309 307 if (esclen < 0) {
310 308 PyErr_SetString(PyExc_MemoryError,
311 309 "overflow in jsonescapelen");
312 310 return -1;
313 311 }
314 312 }
315 313 }
316 314
317 315 return esclen;
318 316 }
319 317
320 318 /* map '\<c>' escape character */
321 319 static char jsonescapechar2(char c)
322 320 {
323 321 switch (c) {
324 322 case '\b':
325 323 return 'b';
326 324 case '\t':
327 325 return 't';
328 326 case '\n':
329 327 return 'n';
330 328 case '\f':
331 329 return 'f';
332 330 case '\r':
333 331 return 'r';
334 332 case '"':
335 333 return '"';
336 334 case '\\':
337 335 return '\\';
338 336 }
339 337 return '\0'; /* should not happen */
340 338 }
341 339
342 340 /* convert 'origbuf' to JSON-escaped form 'escbuf'; 'origbuf' should only
343 341 include characters mappable by json(paranoid)lentable */
344 342 static void encodejsonescape(char *escbuf, Py_ssize_t esclen,
345 343 const char *origbuf, Py_ssize_t origlen,
346 344 bool paranoid)
347 345 {
348 346 const uint8_t *lentable =
349 347 (paranoid) ? jsonparanoidlentable : jsonlentable;
350 348 Py_ssize_t i, j;
351 349
352 350 for (i = 0, j = 0; i < origlen; i++) {
353 351 char c = origbuf[i];
354 352 uint8_t l = lentable[(unsigned char)c];
355 353 assert(j + l <= esclen);
356 354 switch (l) {
357 355 case 1:
358 356 escbuf[j] = c;
359 357 break;
360 358 case 2:
361 359 escbuf[j] = '\\';
362 360 escbuf[j + 1] = jsonescapechar2(c);
363 361 break;
364 362 case 6:
365 363 memcpy(escbuf + j, "\\u00", 4);
366 364 escbuf[j + 4] = hexchartable[(unsigned char)c >> 4];
367 365 escbuf[j + 5] = hexchartable[(unsigned char)c & 0xf];
368 366 break;
369 367 }
370 368 j += l;
371 369 }
372 370 }
373 371
374 372 PyObject *jsonescapeu8fast(PyObject *self, PyObject *args)
375 373 {
376 374 PyObject *origstr, *escstr;
377 375 const char *origbuf;
378 376 Py_ssize_t origlen, esclen;
379 377 int paranoid;
380 if (!PyArg_ParseTuple(args, "O!i:jsonescapeu8fast",
381 &PyBytes_Type, &origstr, &paranoid))
378 if (!PyArg_ParseTuple(args, "O!i:jsonescapeu8fast", &PyBytes_Type,
379 &origstr, &paranoid))
382 380 return NULL;
383 381
384 382 origbuf = PyBytes_AS_STRING(origstr);
385 383 origlen = PyBytes_GET_SIZE(origstr);
386 384 esclen = jsonescapelen(origbuf, origlen, paranoid);
387 385 if (esclen < 0)
388 386 return NULL; /* unsupported char found or overflow */
389 387 if (origlen == esclen) {
390 388 Py_INCREF(origstr);
391 389 return origstr;
392 390 }
393 391
394 392 escstr = PyBytes_FromStringAndSize(NULL, esclen);
395 393 if (!escstr)
396 394 return NULL;
397 395 encodejsonescape(PyBytes_AS_STRING(escstr), esclen, origbuf, origlen,
398 396 paranoid);
399 397
400 398 return escstr;
401 399 }
General Comments 0
You need to be logged in to leave comments. Login now