[SCM] calf/master: + Big Bull: rewrite TTL scanner in a proper programming language ; ) to improve compatibility (now depends on flex instead of python.yappy)
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:37:32 UTC 2013
The following commit has been merged in the master branch:
commit 6a5e6b9ce67357e8ff9b491a7e58b4e837d9ac69
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date: Sun Aug 31 19:47:45 2008 +0000
+ Big Bull: rewrite TTL scanner in a proper programming language ;) to improve compatibility (now depends on flex instead of python.yappy)
git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@273 78b06b96-2940-0410-b7fc-879d825d01d8
diff --git a/bigbull/Makefile b/bigbull/Makefile
new file mode 100644
index 0000000..8187b50
--- /dev/null
+++ b/bigbull/Makefile
@@ -0,0 +1,8 @@
+all: calfpytools.cpp ttl.cpp Makefile setup.py ttldata.h
+ python setup.py build
+
+ttl.cpp: ttl.l Makefile ttldata.h
+ flex --batch --nodefault --c++ -o ttl.cpp --header-file=ttl.h ttl.l
+
+install:
+ python setup.py install
diff --git a/bigbull/calfpytools.cpp b/bigbull/calfpytools.cpp
index bde0f72..b13ecb3 100644
--- a/bigbull/calfpytools.cpp
+++ b/bigbull/calfpytools.cpp
@@ -1,12 +1,22 @@
#include "Python.h"
+#include "ttl.h"
+#include "ttldata.h"
+#include <map>
+#include <iostream>
+#include <fstream>
#include <jack/jack.h>
//////////////////////////////////////////////////// PyJackClient
+struct PyJackPort;
+
+typedef std::map<jack_port_t *, PyJackPort *> PortHandleMap;
+
struct PyJackClient
{
PyObject_HEAD
jack_client_t *client;
+ PortHandleMap *port_handle_map;
};
static PyTypeObject jackclient_type = {
@@ -40,10 +50,22 @@ static PyObject *jackclient_open(PyJackClient *self, PyObject *args)
return NULL;
self->client = jack_client_open(name, (jack_options_t)options, &status);
+ self->port_handle_map = new PortHandleMap;
return Py_BuildValue("i", status);
}
+static int jackclient_dealloc(PyJackPort *self)
+{
+ if (self->client)
+ {
+ PyObject_CallMethod((PyObject *)self, strdup("close"), NULL);
+ assert(!self->client);
+ }
+
+ return 0;
+}
+
#define CHECK_CLIENT if (!self->client) { PyErr_SetString(PyExc_ValueError, "Client not opened"); return NULL; }
@@ -59,12 +81,19 @@ static PyObject *jackclient_get_name(PyJackClient *self, PyObject *args)
static PyObject *create_jack_port(PyJackClient *client, jack_port_t *port)
{
+ PortHandleMap::iterator it = client->port_handle_map->find(port);
+ if (it != client->port_handle_map->end())
+ {
+ Py_INCREF(it->second);
+ return Py_BuildValue("O", it->second);
+ }
if (port)
{
PyObject *cobj = PyCObject_FromVoidPtr(port, NULL);
PyObject *args = Py_BuildValue("OO", client, cobj);
PyObject *newobj = _PyObject_New(&jackport_type);
jackport_type.tp_init(newobj, args, NULL);
+ (*client->port_handle_map)[port] = (PyJackPort *)newobj;
Py_DECREF(args);
return newobj;
}
@@ -97,6 +126,16 @@ static PyObject *jackclient_get_port(PyJackClient *self, PyObject *args)
return create_jack_port(self, port);
}
+static PyObject *jackclient_get_cobj(PyJackClient *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":get_cobj"))
+ return NULL;
+
+ CHECK_CLIENT
+
+ return PyCObject_FromVoidPtr((void *)self->client, NULL);
+}
+
static PyObject *jackclient_close(PyJackClient *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":close"))
@@ -117,6 +156,7 @@ static PyMethodDef jackclient_methods[] = {
{"get_name", (PyCFunction)jackclient_get_name, METH_VARARGS, "Retrieve client name"},
{"get_port", (PyCFunction)jackclient_get_port, METH_VARARGS, "Create port object from name of existing JACK port"},
{"register_port", (PyCFunction)jackclient_register_port, METH_VARARGS, "Register a new port and return an object that represents it"},
+ {"get_cobj", (PyCFunction)jackclient_get_cobj, METH_VARARGS, "Retrieve jack_client_t pointer for the client"},
{NULL, NULL, 0, NULL}
};
@@ -142,6 +182,17 @@ static int jackport_init(PyJackPort *self, PyObject *args, PyObject *kwds)
return 0;
}
+static int jackport_dealloc(PyJackPort *self)
+{
+ // if not unregistered, decref (unregister decrefs automatically)
+ if (self->client) {
+ self->client->port_handle_map->erase(self->port);
+ Py_DECREF(self->client);
+ }
+
+ return 0;
+}
+
#define CHECK_PORT_CLIENT if (!self->client || !self->client->client) { PyErr_SetString(PyExc_ValueError, "Client not opened"); return NULL; }
#define CHECK_PORT if (!self->port) { PyErr_SetString(PyExc_ValueError, "The port is not valid"); return NULL; }
@@ -186,6 +237,17 @@ static PyObject *jackport_get_name(PyJackPort *self, PyObject *args)
return Py_BuildValue("s", jack_port_short_name(self->port));
}
+static PyObject *jackport_get_cobj(PyJackPort *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":get_cobj"))
+ return NULL;
+
+ CHECK_PORT_CLIENT
+ CHECK_PORT
+
+ return PyCObject_FromVoidPtr((void *)self->port, NULL);
+}
+
static PyObject *jackport_get_aliases(PyJackPort *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_aliases"))
@@ -205,6 +267,26 @@ static PyObject *jackport_get_aliases(PyJackPort *self, PyObject *args)
return Py_BuildValue("[ss]", aliases[0], aliases[1]);
}
+static PyObject *jackport_get_connections(PyJackPort *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":get_aliases"))
+ return NULL;
+
+ CHECK_PORT_CLIENT
+ CHECK_PORT
+
+ const char **conns = jack_port_get_all_connections(self->client->client, self->port);
+
+ PyObject *res = PyList_New(0);
+ if (conns)
+ {
+ for (const char **p = conns; *p; p++)
+ PyList_Append(res, PyString_FromString(*p));
+ }
+
+ return res;
+}
+
static PyObject *jackport_set_name(PyJackPort *self, PyObject *args)
{
const char *name;
@@ -227,11 +309,13 @@ static PyObject *jackport_unregister(PyJackPort *self, PyObject *args)
PyJackClient *client = self->client;
+ client->port_handle_map->erase(self->port);
jack_port_unregister(self->client->client, self->port);
self->port = NULL;
self->client = NULL;
Py_DECREF(client);
+ client = NULL;
Py_INCREF(Py_None);
return Py_None;
}
@@ -243,22 +327,45 @@ static PyMethodDef jackport_methods[] = {
{"get_full_name", (PyCFunction)jackport_get_full_name, METH_VARARGS, "Retrieve full port name (including client name)"},
{"get_name", (PyCFunction)jackport_get_name, METH_VARARGS, "Retrieve short port name (without client name)"},
{"set_name", (PyCFunction)jackport_set_name, METH_VARARGS, "Set short port name"},
- {"get_aliases", (PyCFunction)jackport_get_aliases, METH_VARARGS, "Retrieve two port aliases"},
+ {"get_aliases", (PyCFunction)jackport_get_aliases, METH_VARARGS, "Retrieve a list of port aliases"},
+ {"get_connections", (PyCFunction)jackport_get_connections, METH_VARARGS, "Retrieve a list of ports the port is connected to"},
+ {"get_cobj", (PyCFunction)jackport_get_cobj, METH_VARARGS, "Retrieve jack_port_t pointer for the port"},
{NULL, NULL, 0, NULL}
};
//////////////////////////////////////////////////// calfpytools
-/*
-static PyObject *calfpytools_test(PyObject *self, PyObject *args)
+static PyObject *calfpytools_scan_ttl_file(PyObject *self, PyObject *args)
{
- return Py_BuildValue("i", 42);
+ char *ttl_name = NULL;
+ if (!PyArg_ParseTuple(args, "s:scan_ttl_file", &ttl_name))
+ return NULL;
+
+ std::filebuf fb;
+ fb.open(ttl_name, std::ios::in);
+ std::istream istr(&fb);
+ TTLLexer lexer(&istr);
+ lexer.yylex();
+ return lexer.grab();
+}
+
+static PyObject *calfpytools_scan_ttl_string(PyObject *self, PyObject *args)
+{
+ char *data = NULL;
+ if (!PyArg_ParseTuple(args, "s:scan_ttl_string", &data))
+ return NULL;
+
+ std::string data_str = data;
+ std::stringstream str(data_str);
+ TTLLexer lexer(&str);
+ lexer.yylex();
+ return lexer.grab();
}
-*/
static PyMethodDef module_methods[] = {
-// {"test", calfpytools_test, METH_VARARGS, "Do nothing, return 42"},
+ {"scan_ttl_file", calfpytools_scan_ttl_file, METH_VARARGS, "Scan a TTL file, return a list of token tuples"},
+ {"scan_ttl_string", calfpytools_scan_ttl_string, METH_VARARGS, "Scan a TTL string, return a list of token tuples"},
{NULL, NULL, 0, NULL}
};
@@ -268,6 +375,7 @@ PyMODINIT_FUNC initcalfpytools()
jackclient_type.tp_flags = Py_TPFLAGS_DEFAULT;
jackclient_type.tp_doc = "JACK client object";
jackclient_type.tp_methods = jackclient_methods;
+ jackclient_type.tp_dealloc = (destructor)jackclient_dealloc;
if (PyType_Ready(&jackclient_type) < 0)
return;
@@ -276,6 +384,7 @@ PyMODINIT_FUNC initcalfpytools()
jackport_type.tp_doc = "JACK port object (created by client)";
jackport_type.tp_methods = jackport_methods;
jackport_type.tp_init = (initproc)jackport_init;
+ jackport_type.tp_dealloc = (destructor)jackport_dealloc;
if (PyType_Ready(&jackport_type) < 0)
return;
diff --git a/bigbull/fakeserv.py b/bigbull/fakeserv.py
index f6e9d7f..04c807d 100644
--- a/bigbull/fakeserv.py
+++ b/bigbull/fakeserv.py
@@ -2,7 +2,6 @@ import re
import os
import sys
import glob
-import yappy.parser
lv2 = "http://lv2plug.in/ns/lv2core#"
lv2evt = "http://lv2plug.in/ns/ext/event#"
@@ -95,87 +94,6 @@ class SimpleRDFModel:
for p in self.bySubject[s].keys():
print "%s %s %s" % (s, p, self.bySubject[s][p])
-def parseTTL(uri, content, model):
- # Missing stuff: translated literals, blank nodes
- print "Parsing: %s" % uri
- prefixes = {}
- lexer = yappy.parser.Lexer([
- (r"(?m)^\s*#[^\n]*", ""),
- ('"""(\n|\r|.)*?"""', lambda x : ("string", x[3:-3])),
- (r'"([^"\\]|\\.)+"', lambda x : ("string", x[1:-1])),
- (r"<>", lambda x : ("URI", uri)),
- (r"<[^>]*>", lambda x : ("URI", x[1:-1])),
- ("[-a-zA-Z0-9_]*:[-a-zA-Z0-9_]*", lambda x : ("prnot", x)),
- ("@prefix", lambda x : ("prefix", x)),
- (r"-?[0-9]+\.[0-9]+", lambda x : ("number", float(x))),
- (r"-?[0-9]+", lambda x : ("number", int(x))),
- ("[a-zA-Z0-9_]+", lambda x : ("symbol", x)),
- (r"[()\[\];.,]", lambda x : (x, x)),
- ("\s+", ""),
- ])
- spo_stack = []
- spo = ["", "", ""]
- item = 0
- anoncnt = 1
- for x in lexer.scan(content):
- if x[0] == '':
- continue
- if x[0] == 'prefix':
- spo[0] = "@prefix"
- item = 1
- continue
- elif (x[0] == '.' and spo_stack == []) or x[0] == ';' or x[0] == ',':
- if item == 3:
- if spo[0] == "@prefix":
- prefixes[spo[1][:-1]] = spo[2]
- else:
- model.addTriple(spo[0], spo[1], spo[2])
- if x[0] == '.': item = 0
- elif x[0] == ';': item = 1
- elif x[0] == ',': item = 2
- else:
- raise Exception, uri+": Unexpected " + x[0]
- elif x[0] == "prnot" and item < 3:
- prnot = x[1].split(":")
- if item != 0 and spo[0] == "@prefix":
- spo[item] = x[1]
- else:
- spo[item] = prefixes[prnot[0]] + prnot[1]
- item += 1
- elif (x[0] == 'URI' or x[0] == "string" or x[0] == "number" or (x[0] == "symbol" and x[1] == "a" and item == 1)) and (item < 3):
- if x[0] == "URI" and x[1].find(":") == -1 and x[1][0] != "/":
- # This is quite silly
- x = ("URI", os.path.dirname(uri) + "/" + x[1])
- spo[item] = x[1]
- item += 1
- elif x[0] == '[':
- if item != 2:
- raise Exception, "Incorrect use of ["
- uri2 = uri + "$anon$" + str(anoncnt)
- spo[2] = uri2
- spo_stack.append(spo)
- spo = [uri2, "", ""]
- item = 1
- anoncnt += 1
- elif x[0] == ']' or x[0] == ')':
- if item == 3:
- model.addTriple(spo[0], spo[1], spo[2])
- item = 0
- spo = spo_stack[-1]
- spo_stack = spo_stack[:-1]
- item = 3
- elif x[0] == '(':
- if item != 2:
- raise Exception, "Incorrect use of ("
- uri2 = uri + "$anon$" + str(anoncnt)
- spo[2] = uri2
- spo_stack.append(spo)
- spo = [uri2, "", ""]
- item = 2
- anoncnt += 1
- else:
- print uri + ": Unexpected: " + repr(x)
-
class FakeServer(object):
def __init__(self):
pass
diff --git a/bigbull/lv2.py b/bigbull/lv2.py
index b8b1733..34d4bb6 100644
--- a/bigbull/lv2.py
+++ b/bigbull/lv2.py
@@ -2,7 +2,7 @@ import re
import os
import sys
import glob
-import yappy.parser
+import calfpytools
lv2 = "http://lv2plug.in/ns/lv2core#"
lv2evt = "http://lv2plug.in/ns/ext/event#"
@@ -100,25 +100,11 @@ def parseTTL(uri, content, model, debug):
if debug:
print "Parsing: %s" % uri
prefixes = {}
- lexer = yappy.parser.Lexer([
- (r"(?m)^\s*#[^\n]*", ""),
- ('"""(\n|\r|.)*?"""', lambda x : ("string", x[3:-3])),
- (r'"([^"\\]|\\.)+"', lambda x : ("string", x[1:-1])),
- (r"<>", lambda x : ("URI", uri)),
- (r"<[^>]*>", lambda x : ("URI", x[1:-1])),
- ("[-a-zA-Z0-9_]*:[-a-zA-Z0-9_]*", lambda x : ("prnot", x)),
- ("@prefix", lambda x : ("prefix", x)),
- (r"-?[0-9]+\.[0-9]+", lambda x : ("number", float(x))),
- (r"-?[0-9]+", lambda x : ("number", int(x))),
- ("[a-zA-Z0-9_]+", lambda x : ("symbol", x)),
- (r"[()\[\];.,]", lambda x : (x, x)),
- ("\s+", ""),
- ])
spo_stack = []
spo = ["", "", ""]
item = 0
anoncnt = 1
- for x in lexer.scan(content):
+ for x in calfpytools.scan_ttl_string(content):
if x[0] == '':
continue
if x[0] == 'prefix':
@@ -135,10 +121,10 @@ def parseTTL(uri, content, model, debug):
elif x[0] == ';': item = 1
elif x[0] == ',': item = 2
else:
- # Kludge for swh's plugins
- if x[0] != '.' and x[0] != ',':
+ if x[0] == '.':
+ item = 0
+ elif item != 0:
raise Exception, uri+": Unexpected " + x[0]
- item = 0
elif x[0] == "prnot" and item < 3:
prnot = x[1].split(":")
if item != 0 and spo[0] == "@prefix":
@@ -149,7 +135,9 @@ def parseTTL(uri, content, model, debug):
spo[item] = prefixes[prnot[0]] + prnot[1]
item += 1
elif (x[0] == 'URI' or x[0] == "string" or x[0] == "number" or (x[0] == "symbol" and x[1] == "a" and item == 1)) and (item < 3):
- if x[0] == "URI" and x[1].find(":") == -1 and x[1][0] != "/":
+ if x[0] == "URI" and x[1] == "":
+ x = ("URI", uri)
+ elif x[0] == "URI" and x[1].find(":") == -1 and x[1] != "" and x[1][0] != "/":
# This is quite silly
x = ("URI", os.path.dirname(uri) + "/" + x[1])
spo[item] = x[1]
@@ -230,7 +218,7 @@ class LV2DB:
world.copyFrom(self.manifests)
seeAlso = self.manifests.bySubject[uri]["http://www.w3.org/2000/01/rdf-schema#seeAlso"]
for doc in seeAlso:
- # print "Loading " + doc
+ # print "Loading " + doc + " for plugin " + uri
parseTTL(doc, file(doc).read(), world, self.debug)
self.plugin_info[uri] = world
info = self.plugin_info[uri]
diff --git a/bigbull/setup.py b/bigbull/setup.py
index 23286cb..3cc0c5b 100644
--- a/bigbull/setup.py
+++ b/bigbull/setup.py
@@ -3,7 +3,9 @@ from distutils.core import setup, Extension
module1 = Extension('calfpytools',
libraries = ['jack'],
- sources = ['calfpytools.cpp']
+ sources = ['calfpytools.cpp', 'ttl.cpp'],
+ extra_compile_args = ["-g"],
+ extra_link_args = ["-g"]
)
setup (name = 'CalfPyTools',
diff --git a/bigbull/test.py b/bigbull/test.py
index c9e358a..37d65dd 100755
--- a/bigbull/test.py
+++ b/bigbull/test.py
@@ -1,20 +1,33 @@
#!/usr/bin/env python
import calfpytools
+import time
+
+print calfpytools.scan_ttl_file("/usr/local/lib/lv2/allpass-swh.lv2/plugin.ttl")
client = calfpytools.JackClient()
client.open("calf")
+print client.get_cobj()
port = client.register_port("port")
print port
+print port.get_cobj()
assert port.get_name() == "port"
assert port.get_full_name() == "calf:port"
assert port.set_name("port2") == "port2"
assert port.get_name() == "port2"
assert port.get_full_name() == "calf:port2"
assert port.is_valid()
+
+# This doesn't work: assert client.get_port("calf:port2") == port (because JACK C API doesn't reuse the jack_port_t structs)
+
port2 = client.get_port("system:playback_1")
assert port2.get_name() == "playback_1"
print port2.get_full_name()
print port2.get_aliases()
+# prevent Patchage from crashing
+time.sleep(1)
port.unregister()
+assert port2 == client.get_port("system:playback_1")
assert not port.is_valid()
-client.close()
+print port2.get_connections()
+#client.close()
+
diff --git a/bigbull/ttl.h b/bigbull/ttl.h
new file mode 100644
index 0000000..208c600
--- /dev/null
+++ b/bigbull/ttl.h
@@ -0,0 +1,281 @@
+#ifndef yyHEADER_H
+#define yyHEADER_H 1
+#define yyIN_HEADER 1
+
+#line 6 "ttl.h"
+
+#line 8 "ttl.h"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 34
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+ /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+ * following macro. This is required in order to pass the c++-multiple-scanners
+ * test in the regression suite. We get reports that it breaks inheritance.
+ * We will address this in a future release of flex, or omit the C++ scanner
+ * altogether.
+ */
+ #define yyFlexLexer yyFlexLexer
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+#include <iostream>
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ * Given that the standard has decreed that size_t exists since 1989,
+ * I guess we can afford to depend on it. Manoj.
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+
+ std::istream* yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+/* Begin user sect3 */
+
+#define yytext_ptr yytext
+
+#include <FlexLexer.h>
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+#define C_COMMENT 1
+#define C_LONGSTRING 2
+#define C_STRING 3
+
+#endif
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+#define YY_DECL int yyFlexLexer::yylex()
+#endif /* !YY_DECL */
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#line 46 "ttl.l"
+
+
+#line 280 "ttl.h"
+#undef yyIN_HEADER
+#endif /* yyHEADER_H */
diff --git a/bigbull/ttl.l b/bigbull/ttl.l
new file mode 100644
index 0000000..138f747
--- /dev/null
+++ b/bigbull/ttl.l
@@ -0,0 +1,46 @@
+%{
+#include <Python.h>
+#include "ttldata.h"
+
+int yyFlexLexer::yywrap() { return 1; }
+
+void yyerror(const char *str)
+{
+ PyErr_SetString(PyExc_SyntaxError, str);
+}
+
+%}
+
+%x C_COMMENT C_LONGSTRING C_STRING
+
+SYMBOL [A-Za-z_-][a-zA-Z0-9_-]*
+TRIPLEQUOTE \"\"\"
+
+%%
+
+ at prefix { LEXER_DATA->add("prefix", "@prefix"); }
+# BEGIN(C_COMMENT);
+{TRIPLEQUOTE} { LEXER_DATA->strctx.clear(); BEGIN(C_LONGSTRING); }
+\" { LEXER_DATA->strctx.clear(); BEGIN(C_STRING); }
+\<[^>]*\> { LEXER_DATA->add("URI", std::string(yytext + 1, strlen(yytext) - 2)); }
+[+-]?[0-9]+\.[0-9]*([eE][-+]?[0-9]+)? { std::stringstream ss(yytext); double value; ss >> value; LEXER_DATA->add("number", PyFloat_FromDouble(value)); }
+[+-]?[0-9]+ { LEXER_DATA->add("number", PyInt_FromLong(atol(yytext))); }
+{SYMBOL}?:{SYMBOL}? { LEXER_DATA->add("prnot", yytext); }
+{SYMBOL} { LEXER_DATA->add("symbol", yytext); }
+[.,;\[\]\(\)] { LEXER_DATA->add(yytext, yytext); }
+[ \t\n] ;
+
+. { printf("Unexpected characters: '%s'\n", yytext); yyerror("Syntax error"); }
+
+<C_LONGSTRING>{TRIPLEQUOTE} { LEXER_DATA->add("string", LEXER_DATA->strctx); BEGIN(INITIAL); }
+<C_LONGSTRING>[^"]+ LEXER_DATA->strctx += yytext;
+<C_LONGSTRING>\" LEXER_DATA->strctx += yytext;
+
+<C_STRING>\" { LEXER_DATA->add("string", LEXER_DATA->strctx); BEGIN(INITIAL); }
+<C_STRING>\\\" LEXER_DATA->strctx += "\"";
+<C_STRING>[^\\\"\n]+ LEXER_DATA->strctx += yytext;
+
+<C_COMMENT>\n { BEGIN(INITIAL); }
+<C_COMMENT>. ;
+
+%%
diff --git a/bigbull/ttldata.h b/bigbull/ttldata.h
new file mode 100644
index 0000000..cc73920
--- /dev/null
+++ b/bigbull/ttldata.h
@@ -0,0 +1,38 @@
+#ifndef _TTLDATA_H
+#define _TTLDATA_H
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <Python.h>
+
+class TTLLexer: public yyFlexLexer
+{
+public:
+ std::string strctx;
+ PyObject *pylist;
+
+ TTLLexer(std::istream *istr) : yyFlexLexer(istr), pylist(PyList_New(0)) {}
+ void add(const std::string &type, const std::string &value) {
+ PyList_Append(pylist, Py_BuildValue("(ss)", type.c_str(), value.c_str()));
+ // printf("Type %s, Value %s\n", type.c_str(), value.c_str());
+ }
+ void add(const std::string &type, PyObject *value) {
+ PyList_Append(pylist, Py_BuildValue("(sO)", type.c_str(), value));
+ PyObject *str = PyObject_Str(value);
+ // printf("Type %s, Repr Value %s\n", type.c_str(), PyString_AsString(str));
+ Py_DECREF(str);
+ }
+ PyObject *grab() {
+ PyObject *tmp = pylist;
+ pylist = NULL;
+ return tmp;
+ }
+ ~TTLLexer() {
+ Py_XDECREF(pylist);
+ }
+};
+
+#define LEXER_DATA (dynamic_cast<TTLLexer *>(this))
+
+#endif
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list