summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Kreen2008-04-03 09:00:27 +0000
committerMarko Kreen2008-04-03 09:00:27 +0000
commit40c21125dec7939c3d2a4b3e9ad5d8aef4eff15d (patch)
treeef1f3eb66b30dbac436e9fad2ca4c05af33e5520
parent66ce65ce3c224af8f90685bc20828714a80c57a4 (diff)
dollar quoting
-rw-r--r--python/modules/cquoting.c29
-rw-r--r--python/skytools/_pyquoting.py9
2 files changed, 38 insertions, 0 deletions
diff --git a/python/modules/cquoting.c b/python/modules/cquoting.c
index 2dcfc227..42844ca2 100644
--- a/python/modules/cquoting.c
+++ b/python/modules/cquoting.c
@@ -386,6 +386,33 @@ failed:
return NULL;
}
+static PyObject *do_dolq(unsigned char *src, Py_ssize_t src_len)
+{
+ /* src_len >= 2, '$' in start and end */
+ unsigned char *src_end = src + src_len;
+ unsigned char *p1 = src + 1, *p2 = src_end - 2;
+
+ while (p1 < src_end && *p1 != '$')
+ p1++;
+ while (p2 > src && *p2 != '$')
+ p2--;
+ if (p2 <= p1)
+ goto failed;
+
+ p1++; /* position after '$' */
+
+ if ((p1 - src) != (src_end - p2))
+ goto failed;
+ if (memcmp(src, p2, p1 - src) != 0)
+ goto failed;
+
+ return PyString_FromStringAndSize((char *)p1, p2 - p1);
+
+failed:
+ PyErr_Format(PyExc_ValueError, "Broken dollar-quoted string");
+ return NULL;
+}
+
static PyObject *unquote_literal(PyObject *self, PyObject *args)
{
unsigned char *src = NULL;
@@ -400,6 +427,8 @@ static PyObject *unquote_literal(PyObject *self, PyObject *args)
Py_INCREF(Py_None);
return Py_None;
}
+ if (src_len >= 2 && src[0] == '$' && src[src_len - 1] == '$')
+ return do_dolq(src, src_len);
if (src_len < 2 || src[src_len - 1] != '\'')
goto badstr;
if (src[0] == '\'') {
diff --git a/python/skytools/_pyquoting.py b/python/skytools/_pyquoting.py
index 32d548ff..8f72eb5f 100644
--- a/python/skytools/_pyquoting.py
+++ b/python/skytools/_pyquoting.py
@@ -179,6 +179,15 @@ def unquote_literal(val, stdstr = False):
return _esql_rc.sub(_sub_unescape_sqlext, val[1:-1])
elif len(val) > 2 and val[0] in ('E', 'e') and val[1] == "'" and val[-1] == "'":
return _esql_rc.sub(_sub_unescape_sqlext, val[2:-1])
+ elif len(val) >= 2 and val[0] == '$' and val[-1] == '$':
+ p1 = val.find('$', 1)
+ p2 = val.rfind('$', 1, -1)
+ if p1 > 0 and p2 > p1:
+ t1 = val[:p1+1]
+ t2 = val[p2:]
+ if t1 == t2:
+ return val[len(t1):-len(t1)]
+ raise Exception("Bad dollar-quoted string")
elif val.lower() == "null":
return None
return val