// -*- mode: c++ -*- // Copyright (c) 2007-2008 PediaPress GmbH // See README.txt for additional licensing information. #include #include #include #include using namespace std; #define RET(x) {found(x); return x;} struct Token { int type; int start; int len; }; class MacroScanner { public: MacroScanner(Py_UNICODE *_start, Py_UNICODE *_end) { source = start = _start; end = _end; cursor = start; } int found(int val) { if (val==5 && tokens.size()) { Token &previous_token (tokens[tokens.size()-1]); if (previous_token.type==val) { previous_token.len += cursor-start; return tokens.size()-1; } } Token t; t.type = val; t.start = (start-source); t.len = cursor-start; tokens.push_back(t); return tokens.size()-1; } inline int scan(); Py_UNICODE *source; Py_UNICODE *start; Py_UNICODE *cursor; Py_UNICODE *end; vector tokens; }; int MacroScanner::scan() { std: start=cursor; Py_UNICODE *marker=cursor; Py_UNICODE *save_cursor = cursor; #define YYCTYPE Py_UNICODE #define YYCURSOR cursor #define YYMARKER marker #define YYLIMIT (end) // #define YYFILL(n) return 0; /*!re2c re2c:yyfill:enable = 0 ; */ /*!re2c "{"{2,} {RET(1);} "}"{2,} {RET(2);} "[[" | "]]" {RET(3);} "|" {RET(6);} '' {goto noinclude;} '' {goto nowiki;} '\000]* '>' {goto imagemap;} '\000]* '>' {goto math;} '\000]* '>' {goto gallery;} "" {RET(5);} "\000" {RET(0);} [^\000] {RET(5);} */ noinclude: /*!re2c '' {goto std;} [^\000] {goto noinclude;} "\000" {cursor=start+11; RET(5);} */ nowiki: /*!re2c '' {RET(5);} [^\000] {goto nowiki;} "\000" {RET(0);} */ math: /*!re2c '' {RET(5);} [^\000] {goto math;} "\000" {RET(0);} */ gallery: /*!re2c '' {RET(5);} [^\000] {goto gallery;} "\000" {RET(0);} */ imagemap: /*!re2c '' {RET(5);} [^\000] {goto imagemap;} "\000" {RET(0);} */ pre: /*!re2c '' {RET(5);} [^\000] {goto pre;} "\000" {RET(0);} */ } PyObject *py_scan(PyObject *self, PyObject *args) { PyObject *arg1; if (!PyArg_ParseTuple(args, "O:_expander.scan", &arg1)) { return 0; } PyUnicodeObject *unistr = (PyUnicodeObject*)PyUnicode_FromObject(arg1); if (unistr == NULL) { PyErr_SetString(PyExc_TypeError, "parameter cannot be converted to unicode in _expander.scan"); return 0; } Py_UNICODE *start = unistr->str; Py_UNICODE *end = start+unistr->length; MacroScanner scanner (start, end); Py_BEGIN_ALLOW_THREADS while (scanner.scan()) { } Py_END_ALLOW_THREADS Py_XDECREF(unistr); // return PyList_New(0); // uncomment to see timings for scanning int size = scanner.tokens.size(); PyObject *result = PyList_New(size); if (!result) { return 0; } for (int i=0; i