##// END OF EJS Templates
run-tests: stuff a `python3.exe` into the test bin directory on Windows...
run-tests: stuff a `python3.exe` into the test bin directory on Windows Windows doesn't have `python3.exe` as part of the python.org distribution, and that broke every script with a shebang after c102b704edb5. Windows itself provides a `python3.exe` app execution alias[1], but it is some sort of reparse point that MSYS is incapable of handling[2]. When run by MSYS, it simply prints $ python3 -V - Cannot open That in turn caused every `hghave` check, and test that invokes shebang scripts directly, to fail. Rather than try to patch up every script call to be invoked with `$PYTHON` (and regress when non Windows developers forget), copying the executable into the test binary directory with the new name just works. Since this directory is prepended to the system PATH value, it also overrides the broken execution alias. (The `_tmpbindir` is used instead of `_bindir` because the latter causes python3.exe to be copied into the repo next to hg.exe when `test-run-tests.t` runs. Something runs with this version of the executable and subsequent runs of `run-tests.py` inside `test-run-tests.t` try to copy over it while it is in use, and fail. This avoids the failures and the clutter.) I didn't conditionalize this on py3 because `python3.exe` needs to be present (for the shebangs) even when running py2 tests. It shouldn't matter to these simple scripts, and I think the intention is to make the test runner use py3 always, even if testing a py2 build. For now, still supporting py2 is helping to clean up the mess that is py3 tests. [1] https://stackoverflow.com/a/57168165 [2] https://stackoverflow.com/questions/59148628/solved-unable-to-run-python-3-7-on-windows-10-permission-denied#comment104524397_59148666 Differential Revision: https://phab.mercurial-scm.org/D9543

File last commit:

r41367:763b45bc default
r46684:cc0b332a default
Show More
base85.c
203 lines | 3.8 KiB | text/x-c | CLexer
Yuya Nishihara
base85: switch to policy importer
r32368 /*
base85 codec
Copyright 2006 Brendan Cully <brendan@kublai.com>
This software may be used and distributed according to the terms of
the GNU General Public License, incorporated herein by reference.
Largely based on git's implementation
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "util.h"
Augie Fackler
base85: allow clang-format oversight...
r36244 static const char b85chars[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
Yuya Nishihara
base85: switch to policy importer
r32368 static char b85dec[256];
static void b85prep(void)
{
unsigned i;
memset(b85dec, 0, sizeof(b85dec));
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 for (i = 0; i < sizeof(b85chars); i++) {
Yuya Nishihara
base85: switch to policy importer
r32368 b85dec[(int)(b85chars[i])] = i + 1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368 }
static PyObject *b85encode(PyObject *self, PyObject *args)
{
const unsigned char *text;
PyObject *out;
char *dst;
Py_ssize_t len, olen, i;
unsigned int acc, val, ch;
int pad = 0;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!PyArg_ParseTuple(args, PY23("s#|i", "y#|i"), &text, &len, &pad)) {
Yuya Nishihara
base85: switch to policy importer
r32368 return NULL;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (pad) {
Yuya Nishihara
base85: switch to policy importer
r32368 olen = ((len + 3) / 4 * 5) - 3;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 } else {
Yuya Nishihara
base85: switch to policy importer
r32368 olen = len % 4;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (olen) {
Yuya Nishihara
base85: switch to policy importer
r32368 olen++;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368 olen += len / 4 * 5;
}
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!(out = PyBytes_FromStringAndSize(NULL, olen + 3))) {
Yuya Nishihara
base85: switch to policy importer
r32368 return NULL;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368
dst = PyBytes_AsString(out);
while (len) {
acc = 0;
for (i = 24; i >= 0; i -= 8) {
ch = *text++;
acc |= ch << i;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (--len == 0) {
Yuya Nishihara
base85: switch to policy importer
r32368 break;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368 }
for (i = 4; i >= 0; i--) {
val = acc % 85;
acc /= 85;
dst[i] = b85chars[val];
}
dst += 5;
}
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!pad) {
Yuya Nishihara
base85: switch to policy importer
r32368 _PyBytes_Resize(&out, olen);
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368
return out;
}
static PyObject *b85decode(PyObject *self, PyObject *args)
{
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 PyObject *out = NULL;
Yuya Nishihara
base85: switch to policy importer
r32368 const char *text;
char *dst;
Py_ssize_t len, i, j, olen, cap;
int c;
unsigned int acc;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &len)) {
Yuya Nishihara
base85: switch to policy importer
r32368 return NULL;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368
olen = len / 5 * 4;
i = len % 5;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (i) {
Yuya Nishihara
base85: switch to policy importer
r32368 olen += i - 1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (!(out = PyBytes_FromStringAndSize(NULL, olen))) {
Yuya Nishihara
base85: switch to policy importer
r32368 return NULL;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
base85: switch to policy importer
r32368
dst = PyBytes_AsString(out);
i = 0;
Gregory Szorc
cext: move braces for control statements to same line...
r34438 while (i < len) {
Yuya Nishihara
base85: switch to policy importer
r32368 acc = 0;
cap = len - i - 1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (cap > 4) {
Yuya Nishihara
base85: switch to policy importer
r32368 cap = 4;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Gregory Szorc
cext: move braces for control statements to same line...
r34438 for (j = 0; j < cap; i++, j++) {
Yuya Nishihara
base85: switch to policy importer
r32368 c = b85dec[(int)*text++] - 1;
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 if (c < 0) {
PyErr_Format(
Augie Fackler
base85: allow clang-format oversight...
r36244 PyExc_ValueError,
"bad base85 character at position %d",
(int)i);
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 goto bail;
}
Yuya Nishihara
base85: switch to policy importer
r32368 acc = acc * 85 + c;
}
Gregory Szorc
cext: move braces for control statements to same line...
r34438 if (i++ < len) {
Yuya Nishihara
base85: switch to policy importer
r32368 c = b85dec[(int)*text++] - 1;
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 if (c < 0) {
PyErr_Format(
Augie Fackler
base85: allow clang-format oversight...
r36244 PyExc_ValueError,
"bad base85 character at position %d",
(int)i);
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 goto bail;
}
Yuya Nishihara
base85: switch to policy importer
r32368 /* overflow detection: 0xffffffff == "|NsC0",
* "|NsC" == 0x03030303 */
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 if (acc > 0x03030303 || (acc *= 85) > 0xffffffff - c) {
PyErr_Format(
Augie Fackler
base85: allow clang-format oversight...
r36244 PyExc_ValueError,
"bad base85 sequence at position %d",
(int)i);
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 goto bail;
}
Yuya Nishihara
base85: switch to policy importer
r32368 acc += c;
}
cap = olen < 4 ? olen : 4;
olen -= cap;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 for (j = 0; j < 4 - cap; j++) {
Yuya Nishihara
base85: switch to policy importer
r32368 acc *= 85;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (cap && cap < 4) {
Yuya Nishihara
base85: switch to policy importer
r32368 acc += 0xffffff >> (cap - 1) * 8;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Gregory Szorc
cext: move braces for control statements to same line...
r34438 for (j = 0; j < cap; j++) {
Yuya Nishihara
base85: switch to policy importer
r32368 acc = (acc << 8) | (acc >> 24);
*dst++ = acc;
}
}
return out;
Yuya Nishihara
base85: fix leak on error return from b85decode()...
r39483 bail:
Py_XDECREF(out);
return NULL;
Yuya Nishihara
base85: switch to policy importer
r32368 }
static char base85_doc[] = "Base85 Data Encoding";
static PyMethodDef methods[] = {
Augie Fackler
base85: allow clang-format oversight...
r36244 {"b85encode", b85encode, METH_VARARGS,
"Encode text in base85.\n\n"
"If the second parameter is true, pad the result to a multiple of "
"five characters.\n"},
{"b85decode", b85decode, METH_VARARGS, "Decode base85 text.\n"},
{NULL, NULL},
Yuya Nishihara
base85: switch to policy importer
r32368 };
static const int version = 1;
#ifdef IS_PY3K
static struct PyModuleDef base85_module = {
Augie Fackler
base85: allow clang-format oversight...
r36244 PyModuleDef_HEAD_INIT, "base85", base85_doc, -1, methods,
Yuya Nishihara
base85: switch to policy importer
r32368 };
PyMODINIT_FUNC PyInit_base85(void)
{
PyObject *m;
b85prep();
m = PyModule_Create(&base85_module);
PyModule_AddIntConstant(m, "version", version);
return m;
}
#else
PyMODINIT_FUNC initbase85(void)
{
PyObject *m;
m = Py_InitModule3("base85", methods, base85_doc);
b85prep();
PyModule_AddIntConstant(m, "version", version);
}
#endif