##// END OF EJS Templates
parsers: clean up whitespace
Matt Mackall -
r7091:12b35ae0 default
parent child Browse files
Show More
@@ -1,169 +1,169 b''
1 /*
1 /*
2 parsers.c - efficient content parsing
2 parsers.c - efficient content parsing
3
3
4 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
4 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
5
5
6 This software may be used and distributed according to the terms of
6 This software may be used and distributed according to the terms of
7 the GNU General Public License, incorporated herein by reference.
7 the GNU General Public License, incorporated herein by reference.
8 */
8 */
9
9
10 #include <Python.h>
10 #include <Python.h>
11 #include <ctype.h>
11 #include <ctype.h>
12 #include <string.h>
12 #include <string.h>
13
13
14 static int hexdigit(char c)
14 static int hexdigit(char c)
15 {
15 {
16 if (c >= '0' && c <= '9')
16 if (c >= '0' && c <= '9')
17 return c - '0';
17 return c - '0';
18
18
19 if (c >= 'A' && c <= 'F')
19 if (c >= 'A' && c <= 'F')
20 return c - 'A' + 10;
20 return c - 'A' + 10;
21
21
22 if (c >= 'a' && c <= 'f')
22 if (c >= 'a' && c <= 'f')
23 return c - 'a' + 10;
23 return c - 'a' + 10;
24
24
25 return -1;
25 return -1;
26 }
26 }
27
27
28 /*
28 /*
29 * Turn a hex-encoded string into binary.
29 * Turn a hex-encoded string into binary.
30 */
30 */
31 static PyObject *unhexlify(const char *str, int len)
31 static PyObject *unhexlify(const char *str, int len)
32 {
32 {
33 PyObject *ret = NULL;
33 PyObject *ret = NULL;
34 const char *c;
34 const char *c;
35 char *d;
35 char *d;
36
36
37 if (len % 2) {
37 if (len % 2) {
38 PyErr_SetString(PyExc_ValueError,
38 PyErr_SetString(PyExc_ValueError,
39 "input is not even in length");
39 "input is not even in length");
40 goto bail;
40 goto bail;
41 }
41 }
42
42
43 ret = PyString_FromStringAndSize(NULL, len / 2);
43 ret = PyString_FromStringAndSize(NULL, len / 2);
44 if (!ret)
44 if (!ret)
45 goto bail;
45 goto bail;
46
46
47 d = PyString_AsString(ret);
47 d = PyString_AsString(ret);
48 if (!d)
48 if (!d)
49 goto bail;
49 goto bail;
50
50
51 for (c = str; c < str + len;) {
51 for (c = str; c < str + len;) {
52 int hi = hexdigit(*c++);
52 int hi = hexdigit(*c++);
53 int lo = hexdigit(*c++);
53 int lo = hexdigit(*c++);
54
54
55 if (hi == -1 || lo == -1) {
55 if (hi == -1 || lo == -1) {
56 PyErr_SetString(PyExc_ValueError,
56 PyErr_SetString(PyExc_ValueError,
57 "input contains non-hex character");
57 "input contains non-hex character");
58 goto bail;
58 goto bail;
59 }
59 }
60
60
61 *d++ = (hi << 4) | lo;
61 *d++ = (hi << 4) | lo;
62 }
62 }
63
63
64 goto done;
64 goto done;
65
65
66 bail:
66 bail:
67 Py_XDECREF(ret);
67 Py_XDECREF(ret);
68 ret = NULL;
68 ret = NULL;
69 done:
69 done:
70 return ret;
70 return ret;
71 }
71 }
72
72
73 /*
73 /*
74 * This code assumes that a manifest is stitched together with newline
74 * This code assumes that a manifest is stitched together with newline
75 * ('\n') characters.
75 * ('\n') characters.
76 */
76 */
77 static PyObject *parse_manifest(PyObject *self, PyObject *args)
77 static PyObject *parse_manifest(PyObject *self, PyObject *args)
78 {
78 {
79 PyObject *mfdict, *fdict;
79 PyObject *mfdict, *fdict;
80 char *str, *cur, *start, *zero;
80 char *str, *cur, *start, *zero;
81 int len;
81 int len;
82
82
83 if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
83 if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
84 &PyDict_Type, &mfdict,
84 &PyDict_Type, &mfdict,
85 &PyDict_Type, &fdict,
85 &PyDict_Type, &fdict,
86 &str, &len))
86 &str, &len))
87 goto quit;
87 goto quit;
88
88
89 for (start = cur = str, zero = NULL; cur < str + len; cur++) {
89 for (start = cur = str, zero = NULL; cur < str + len; cur++) {
90 PyObject *file = NULL, *node = NULL;
90 PyObject *file = NULL, *node = NULL;
91 PyObject *flags = NULL;
91 PyObject *flags = NULL;
92 int nlen;
92 int nlen;
93
93
94 if (!*cur) {
94 if (!*cur) {
95 zero = cur;
95 zero = cur;
96 continue;
96 continue;
97 }
97 }
98 else if (*cur != '\n')
98 else if (*cur != '\n')
99 continue;
99 continue;
100
100
101 if (!zero) {
101 if (!zero) {
102 PyErr_SetString(PyExc_ValueError,
102 PyErr_SetString(PyExc_ValueError,
103 "manifest entry has no separator");
103 "manifest entry has no separator");
104 goto quit;
104 goto quit;
105 }
105 }
106
106
107 file = PyString_FromStringAndSize(start, zero - start);
107 file = PyString_FromStringAndSize(start, zero - start);
108 if (!file)
108 if (!file)
109 goto bail;
109 goto bail;
110
110
111 nlen = cur - zero - 1;
111 nlen = cur - zero - 1;
112
112
113 node = unhexlify(zero + 1, nlen > 40 ? 40 : nlen);
113 node = unhexlify(zero + 1, nlen > 40 ? 40 : nlen);
114 if (!node)
114 if (!node)
115 goto bail;
115 goto bail;
116
116
117 if (nlen > 40) {
117 if (nlen > 40) {
118 PyObject *flags;
118 PyObject *flags;
119
119
120 flags = PyString_FromStringAndSize(zero + 41,
120 flags = PyString_FromStringAndSize(zero + 41,
121 nlen - 40);
121 nlen - 40);
122 if (!flags)
122 if (!flags)
123 goto bail;
123 goto bail;
124
124
125 if (PyDict_SetItem(fdict, file, flags) == -1)
125 if (PyDict_SetItem(fdict, file, flags) == -1)
126 goto bail;
126 goto bail;
127 }
127 }
128
128
129 if (PyDict_SetItem(mfdict, file, node) == -1)
129 if (PyDict_SetItem(mfdict, file, node) == -1)
130 goto bail;
130 goto bail;
131
131
132 start = cur + 1;
132 start = cur + 1;
133 zero = NULL;
133 zero = NULL;
134
134
135 Py_XDECREF(flags);
135 Py_XDECREF(flags);
136 Py_XDECREF(node);
136 Py_XDECREF(node);
137 Py_XDECREF(file);
137 Py_XDECREF(file);
138 continue;
138 continue;
139 bail:
139 bail:
140 Py_XDECREF(flags);
140 Py_XDECREF(flags);
141 Py_XDECREF(node);
141 Py_XDECREF(node);
142 Py_XDECREF(file);
142 Py_XDECREF(file);
143 goto quit;
143 goto quit;
144 }
144 }
145
145
146 if (len > 0 && *(cur - 1) != '\n') {
146 if (len > 0 && *(cur - 1) != '\n') {
147 PyErr_SetString(PyExc_ValueError,
147 PyErr_SetString(PyExc_ValueError,
148 "manifest contains trailing garbage");
148 "manifest contains trailing garbage");
149 goto quit;
149 goto quit;
150 }
150 }
151
151
152 Py_INCREF(Py_None);
152 Py_INCREF(Py_None);
153 return Py_None;
153 return Py_None;
154
154
155 quit:
155 quit:
156 return NULL;
156 return NULL;
157 }
157 }
158
158
159 static char parsers_doc[] = "Efficient content parsing.";
159 static char parsers_doc[] = "Efficient content parsing.";
160
160
161 static PyMethodDef methods[] = {
161 static PyMethodDef methods[] = {
162 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
162 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
163 {NULL, NULL}
163 {NULL, NULL}
164 };
164 };
165
165
166 PyMODINIT_FUNC initparsers(void)
166 PyMODINIT_FUNC initparsers(void)
167 {
167 {
168 Py_InitModule3("parsers", methods, parsers_doc);
168 Py_InitModule3("parsers", methods, parsers_doc);
169 }
169 }
General Comments 0
You need to be logged in to leave comments. Login now