diff options
Diffstat (limited to 'chromium/third_party/catapult/common/py_vulcanize/third_party/rjsmin/rjsmin.c')
-rw-r--r-- | chromium/third_party/catapult/common/py_vulcanize/third_party/rjsmin/rjsmin.c | 510 |
1 files changed, 510 insertions, 0 deletions
diff --git a/chromium/third_party/catapult/common/py_vulcanize/third_party/rjsmin/rjsmin.c b/chromium/third_party/catapult/common/py_vulcanize/third_party/rjsmin/rjsmin.c new file mode 100644 index 00000000000..aa77a88ee4b --- /dev/null +++ b/chromium/third_party/catapult/common/py_vulcanize/third_party/rjsmin/rjsmin.c @@ -0,0 +1,510 @@ +/* + * Copyright 2011 - 2015 + * Andr\xe9 Malo or his licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cext.h" +EXT_INIT_FUNC; + +#define RJSMIN_DULL_BIT (1 << 0) +#define RJSMIN_PRE_REGEX_BIT (1 << 1) +#define RJSMIN_REGEX_DULL_BIT (1 << 2) +#define RJSMIN_REGEX_CC_DULL_BIT (1 << 3) +#define RJSMIN_ID_LIT_BIT (1 << 4) +#define RJSMIN_ID_LIT_O_BIT (1 << 5) +#define RJSMIN_ID_LIT_C_BIT (1 << 6) +#define RJSMIN_STRING_DULL_BIT (1 << 7) +#define RJSMIN_SPACE_BIT (1 << 8) +#define RJSMIN_POST_REGEX_OFF_BIT (1 << 9) + +#ifdef EXT3 +typedef Py_UNICODE rchar; +#else +typedef unsigned char rchar; +#endif +#define U(c) ((rchar)(c)) + +#define RJSMIN_IS_DULL(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_DULL_BIT)) + +#define RJSMIN_IS_REGEX_DULL(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_REGEX_DULL_BIT)) + +#define RJSMIN_IS_REGEX_CC_DULL(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_REGEX_CC_DULL_BIT)) + +#define RJSMIN_IS_STRING_DULL(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_STRING_DULL_BIT)) + +#define RJSMIN_IS_ID_LITERAL(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_ID_LIT_BIT)) + +#define RJSMIN_IS_ID_LITERAL_OPEN(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_ID_LIT_O_BIT)) + +#define RJSMIN_IS_ID_LITERAL_CLOSE(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_ID_LIT_C_BIT)) + +#define RJSMIN_IS_POST_REGEX_OFF(c) ((U(c) > 127) || \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_POST_REGEX_OFF_BIT)) + +#define RJSMIN_IS_SPACE(c) ((U(c) <= 127) && \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_SPACE_BIT)) + +#define RJSMIN_IS_PRE_REGEX_1(c) ((U(c) <= 127) && \ + (rjsmin_charmask[U(c) & 0x7F] & RJSMIN_PRE_REGEX_BIT)) + + +static const unsigned short rjsmin_charmask[128] = { + 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 2, 396, 396, 2, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, + 396, 687, 588, 653, 765, 653, 143, 588, + 687, 205, 653, 237, 143, 237, 141, 648, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 143, 143, 653, 143, 653, 143, + 653, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 683, 513, 197, 653, 765, + 653, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 687, 143, 207, 653, 765 +}; + +static Py_ssize_t +rjsmin(const rchar *source, rchar *target, Py_ssize_t length, + int keep_bang_comments) +{ + const rchar *reset, *pcreset = NULL, *pctoken = NULL, *xtarget, + *sentinel = source + length; + rchar *tstart = target; + int post_regex = 0; + rchar c, quote, spaced = U(' '); + + while (source < sentinel) { + c = *source++; + if (RJSMIN_IS_DULL(c)) { + if (post_regex) post_regex = 0; + if (pctoken) pctoken = NULL; + if (spaced == U('\n')) spaced = U(' '); + + *target++ = c; + continue; + } + switch (c) { + + /* String */ + case U('\''): case U('"'): + if (post_regex) post_regex = 0; + if (pctoken) pctoken = NULL; + if (spaced == U('\n')) spaced = U(' '); + + reset = source; + *target++ = quote = c; + while (source < sentinel) { + c = *source++; + *target++ = c; + if (RJSMIN_IS_STRING_DULL(c)) + continue; + switch (c) { + case U('\''): case U('"'): + if (c == quote) + goto cont; + continue; + case U('\\'): + if (source < sentinel) { + c = *source++; + *target++ = c; + if (c == U('\r') && source < sentinel + && *source == U('\n')) + *target++ = *source++; + } + continue; + } + break; + } + target -= source - reset; + source = reset; + continue; + + /* Comment or Regex or something else entirely */ + case U('/'): + if (!(source < sentinel)) { + if (post_regex) post_regex = 0; + if (pctoken) pctoken = NULL; + if (spaced == U('\n')) spaced = U(' '); + + *target++ = c; + } + else { + switch (*source) { + /* Comment */ + case U('*'): case U('/'): + goto skip_or_copy_ws; + + default: + xtarget = NULL; + if ( target == tstart + || RJSMIN_IS_PRE_REGEX_1(*((pctoken ? pctoken : target) + - 1)) + || ( + (xtarget = pctoken ? pctoken : target) + && (xtarget - tstart >= 6) + && *(xtarget - 1) == U('n') + && *(xtarget - 2) == U('r') + && *(xtarget - 3) == U('u') + && *(xtarget - 4) == U('t') + && *(xtarget - 5) == U('e') + && *(xtarget - 6) == U('r') + && ( + xtarget - tstart == 6 + || !RJSMIN_IS_ID_LITERAL(*(xtarget - 7)) + ) + )) { + + /* Regex */ + if (post_regex) post_regex = 0; + if (pctoken) pctoken = NULL; + + reset = source; + if (spaced == U('\n')) { + spaced = U(' '); + if (xtarget) + *target++ = U('\n'); + } + + *target++ = U('/'); + while (source < sentinel) { + c = *source++; + *target++ = c; + if (RJSMIN_IS_REGEX_DULL(c)) + continue; + switch (c) { + case U('/'): + post_regex = 1; + goto cont; + case U('\\'): + if (source < sentinel) { + c = *source++; + *target++ = c; + if (c == U('\r') || c == U('\n')) + break; + } + continue; + case U('['): + while (source < sentinel) { + c = *source++; + *target++ = c; + if (RJSMIN_IS_REGEX_CC_DULL(c)) + continue; + switch (c) { + case U('\\'): + if (source < sentinel) { + c = *source++; + *target++ = c; + if (c == U('\r') || c == U('\n')) + break; + } + continue; + case U(']'): + goto cont_regex; + } + } + break; + } + break; + cont_regex: + continue; + } + target -= source - reset; + source = reset; + } + else { + /* Just a slash */ + if (post_regex) post_regex = 0; + if (pctoken) pctoken = NULL; + if (spaced == U('\n')) spaced = U(' '); + + *target++ = c; + } + continue; + } + } + continue; + + /* Whitespace */ + default: + skip_or_copy_ws: + quote = U(' '); + --source; + while (source < sentinel) { + c = *source++; + if (RJSMIN_IS_SPACE(c)) + continue; + switch (c) { + case U('\r'): case U('\n'): + quote = U('\n'); + continue; + case U('/'): + if (source < sentinel) { + switch (*source) { + case U('*'): + reset = source++; + /* copy bang comment, if requested */ + if ( keep_bang_comments && source < sentinel + && *source == U('!')) { + if (!pctoken) { + pctoken = target; + pcreset = reset; + } + + *target++ = U('/'); + *target++ = U('*'); + *target++ = *source++; + while (source < sentinel) { + c = *source++; + *target++ = c; + if (c == U('*') && source < sentinel + && *source == U('/')) { + *target++ = *source++; + reset = NULL; + break; + } + } + if (!reset) + continue; + + target -= source - reset; + source = reset; + if (pcreset == reset) { + pctoken = NULL; + pcreset = NULL; + } + + } + /* strip regular comment */ + else { + while (source < sentinel) { + c = *source++; + if (c == U('*') && source < sentinel + && *source == U('/')) { + ++source; + reset = NULL; + break; + } + } + if (!reset) + continue; + source = reset; + *target++ = U('/'); + } + goto cont; + case U('/'): + ++source; + while (source < sentinel) { + c = *source++; + switch (c) { + case U('\n'): + break; + case U('\r'): + if (source < sentinel + && *source == U('\n')) + ++source; + break; + default: + continue; + } + break; + } + quote = U('\n'); + continue; + } + } + } + --source; + break; + } + + if ((tstart < (pctoken ? pctoken : target) && source < sentinel) + && ((quote == U('\n') + && ((RJSMIN_IS_ID_LITERAL_CLOSE(*((pctoken ? + pctoken : target) - 1)) + && RJSMIN_IS_ID_LITERAL_OPEN(*source)) + || (post_regex + && RJSMIN_IS_POST_REGEX_OFF(*source) + && !(post_regex = 0)))) + || + (quote == U(' ') && !pctoken + && ((RJSMIN_IS_ID_LITERAL(*(target - 1)) + && RJSMIN_IS_ID_LITERAL(*source)) + || (source < sentinel + && ((*(target - 1) == U('+') + && *source == U('+')) + || (*(target - 1) == U('-') + && *source == U('-')))))))) { + *target++ = quote; + } + + pcreset = NULL; + spaced = quote; + } + cont: + continue; + } + return (Py_ssize_t)(target - tstart); +} + + +PyDoc_STRVAR(rjsmin_jsmin__doc__, +"jsmin(script, keep_bang_comments=False)\n\ +\n\ +Minify javascript based on `jsmin.c by Douglas Crockford`_\\.\n\ +\n\ +Instead of parsing the stream char by char, it uses a regular\n\ +expression approach which minifies the whole script with one big\n\ +substitution regex.\n\ +\n\ +.. _jsmin.c by Douglas Crockford:\n\ + http://www.crockford.com/javascript/jsmin.c\n\ +\n\ +:Note: This is a hand crafted C implementation built on the regex\n\ + semantics.\n\ +\n\ +:Parameters:\n\ + `script` : ``str``\n\ + Script to minify\n\ +\n\ + `keep_bang_comments` : ``bool``\n\ + Keep comments starting with an exclamation mark? (``/*!...*/``)\n\ +\n\ +:Return: Minified script\n\ +:Rtype: ``str``"); + +static PyObject * +rjsmin_jsmin(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *script, *keep_bang_comments_ = NULL, *result; + static char *kwlist[] = {"script", "keep_bang_comments", NULL}; + Py_ssize_t slength, length; + int keep_bang_comments; +#ifdef EXT2 + int uni; +#define UOBJ "O" +#endif +#ifdef EXT3 +#define UOBJ "U" +#endif + + if (!PyArg_ParseTupleAndKeywords(args, kwds, UOBJ "|O", kwlist, + &script, &keep_bang_comments_)) + return NULL; + + if (!keep_bang_comments_) + keep_bang_comments = 0; + else { + keep_bang_comments = PyObject_IsTrue(keep_bang_comments_); + if (keep_bang_comments == -1) + return NULL; + } + +#ifdef EXT2 + if (PyUnicode_Check(script)) { + if (!(script = PyUnicode_AsUTF8String(script))) + return NULL; + uni = 1; + } + else { + if (!(script = PyObject_Str(script))) + return NULL; + uni = 0; + } +#endif + +#ifdef EXT3 + Py_INCREF(script); +#define PyString_GET_SIZE PyUnicode_GET_SIZE +#define PyString_AS_STRING PyUnicode_AS_UNICODE +#define _PyString_Resize PyUnicode_Resize +#define PyString_FromStringAndSize PyUnicode_FromUnicode +#endif + + slength = PyString_GET_SIZE(script); + if (!(result = PyString_FromStringAndSize(NULL, slength))) { + Py_DECREF(script); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + length = rjsmin((rchar *)PyString_AS_STRING(script), + (rchar *)PyString_AS_STRING(result), + slength, keep_bang_comments); + Py_END_ALLOW_THREADS + + Py_DECREF(script); + if (length < 0) { + Py_DECREF(result); + return NULL; + } + if (length != slength && _PyString_Resize(&result, length) == -1) + return NULL; + +#ifdef EXT2 + if (uni) { + script = PyUnicode_DecodeUTF8(PyString_AS_STRING(result), + PyString_GET_SIZE(result), "strict"); + Py_DECREF(result); + if (!script) + return NULL; + result = script; + } +#endif + return result; +} + +/* ------------------------ BEGIN MODULE DEFINITION ------------------------ */ + +EXT_METHODS = { + {"jsmin", + (PyCFunction)rjsmin_jsmin, METH_VARARGS | METH_KEYWORDS, + rjsmin_jsmin__doc__}, + + {NULL} /* Sentinel */ +}; + +PyDoc_STRVAR(EXT_DOCS_VAR, +"C implementation of rjsmin\n\ +==========================\n\ +\n\ +C implementation of rjsmin."); + + +EXT_DEFINE(EXT_MODULE_NAME, EXT_METHODS_VAR, EXT_DOCS_VAR); + +EXT_INIT_FUNC { + PyObject *m; + + /* Create the module and populate stuff */ + if (!(m = EXT_CREATE(&EXT_DEFINE_VAR))) + EXT_INIT_ERROR(NULL); + + EXT_ADD_UNICODE(m, "__author__", "Andr\xe9 Malo", "latin-1"); + EXT_ADD_STRING(m, "__docformat__", "restructuredtext en"); + + EXT_INIT_RETURN(m); +} + +/* ------------------------- END MODULE DEFINITION ------------------------- */ |