From 375a1ceb6ff9b4868f9e57b5cd865e7c2ce518fe Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 18 Aug 2012 23:51:30 +0200 Subject: Added "virtual pad" to SPPolyLine. (bzr r11608.1.12) --- src/sp-polyline.cpp | 68 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 19 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 8dbed2a22..16980bcb6 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -59,24 +59,39 @@ void SPPolyLineClass::sp_polyline_class_init(SPPolyLineClass *klass) item_class->description = SPPolyLine::getDescription; } -void SPPolyLine::init(SPPolyLine * /*polyline*/) -{ - /* Nothing here */ +CPolyLine::CPolyLine(SPPolyLine* polyline) : CShape(polyline) { + this->sppolyline = polyline; } -void SPPolyLine::build(SPObject * object, SPDocument * document, Inkscape::XML::Node * repr) +CPolyLine::~CPolyLine() { +} + +void SPPolyLine::init(SPPolyLine * polyline) { + polyline->cpolyline = new CPolyLine(polyline); + polyline->cshape = polyline->cpolyline; + polyline->clpeitem = polyline->cpolyline; + polyline->citem = polyline->cpolyline; + polyline->cobject = polyline->cpolyline; +} - if (((SPObjectClass *) SPPolyLineClass::static_parent_class)->build) { - ((SPObjectClass *) SPPolyLineClass::static_parent_class)->build (object, document, repr); - } +void CPolyLine::onBuild(SPDocument * document, Inkscape::XML::Node * repr) { + SPPolyLine* object = this->sppolyline; + + CShape::onBuild(document, repr); object->readAttr( "points" ); } -void SPPolyLine::set(SPObject *object, unsigned int key, const gchar *value) +// CPPIFY: remove +void SPPolyLine::build(SPObject * object, SPDocument * document, Inkscape::XML::Node * repr) { - SPPolyLine *polyline = SP_POLYLINE(object); + ((SPPolyLine*)object)->cpolyline->onBuild(document, repr); +} + +void CPolyLine::onSet(unsigned int key, const gchar* value) { + SPPolyLine* object = this->sppolyline; + SPPolyLine *polyline = object; switch (key) { case SP_ATTR_POINTS: { @@ -125,16 +140,22 @@ void SPPolyLine::set(SPObject *object, unsigned int key, const gchar *value) break; } default: - if (((SPObjectClass *) SPPolyLineClass::static_parent_class)->set) { - ((SPObjectClass *) SPPolyLineClass::static_parent_class)->set (object, key, value); - } + CShape::onSet(key, value); break; } } -Inkscape::XML::Node *SPPolyLine::write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +// CPPIFY: remove +void SPPolyLine::set(SPObject *object, unsigned int key, const gchar *value) { - SP_POLYLINE(object); + ((SPPolyLine*)object)->cpolyline->onSet(key, value); +} + +Inkscape::XML::Node* CPolyLine::onWrite(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { + SPPolyLine* object = this->sppolyline; + + // CPPIFY: This is a simple type check? + //SP_POLYLINE(object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:polyline"); @@ -144,16 +165,25 @@ Inkscape::XML::Node *SPPolyLine::write(SPObject *object, Inkscape::XML::Document repr->mergeFrom(object->getRepr(), "id"); } - if (((SPObjectClass *) (SPPolyLineClass::static_parent_class))->write) { - ((SPObjectClass *) (SPPolyLineClass::static_parent_class))->write (object, xml_doc, repr, flags); - } + CShape::onWrite(xml_doc, repr, flags); return repr; } -gchar *SPPolyLine::getDescription(SPItem * /*item*/) +// CPPIFY: remove +Inkscape::XML::Node *SPPolyLine::write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ + return ((SPPolyLine*)object)->cpolyline->onWrite(xml_doc, repr, flags); +} + +gchar* CPolyLine::onDescription() { + return g_strdup(_("Polyline")); +} + +// CPPIFY: remove +gchar *SPPolyLine::getDescription(SPItem * item) { - return g_strdup(_("Polyline")); + return ((SPPolyLine*)item)->cpolyline->onDescription(); } -- cgit v1.2.3 From 99cb30e28d4ee193f39e23464abbd7630cac8a2d Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 6 Oct 2012 23:56:27 +0200 Subject: Added virtual pad to SPFlowtext; removed old calls to virtual SPItem methods. (bzr r11608.1.46) --- src/sp-polyline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 16980bcb6..111bca390 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -56,7 +56,7 @@ void SPPolyLineClass::sp_polyline_class_init(SPPolyLineClass *klass) sp_object_class->set = SPPolyLine::set; sp_object_class->write = SPPolyLine::write; - item_class->description = SPPolyLine::getDescription; +// item_class->description = SPPolyLine::getDescription; } CPolyLine::CPolyLine(SPPolyLine* polyline) : CShape(polyline) { -- cgit v1.2.3 From a0a8d020201e0e38a63d9aa3dce228d7d9e6fb35 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Thu, 14 Mar 2013 12:42:39 +0100 Subject: Various changes. (bzr r11608.1.48) --- src/sp-polyline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 111bca390..319aad41f 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -52,7 +52,7 @@ void SPPolyLineClass::sp_polyline_class_init(SPPolyLineClass *klass) static_parent_class = (SPShapeClass *)g_type_class_ref(SP_TYPE_SHAPE); - sp_object_class->build = SPPolyLine::build; + //sp_object_class->build = SPPolyLine::build; sp_object_class->set = SPPolyLine::set; sp_object_class->write = SPPolyLine::write; -- cgit v1.2.3 From 957c3e4b7909d42c5a13f1b1dd583f877fc32259 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:46:57 +0100 Subject: Removed function pointers from SPObject and subclasses. Added some missing virtual pads for classes that were hidden by preprocessor macros. (bzr r11608.1.55) --- src/sp-polyline.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 319aad41f..aaa116cf5 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -53,8 +53,8 @@ void SPPolyLineClass::sp_polyline_class_init(SPPolyLineClass *klass) static_parent_class = (SPShapeClass *)g_type_class_ref(SP_TYPE_SHAPE); //sp_object_class->build = SPPolyLine::build; - sp_object_class->set = SPPolyLine::set; - sp_object_class->write = SPPolyLine::write; +// sp_object_class->set = SPPolyLine::set; +// sp_object_class->write = SPPolyLine::write; // item_class->description = SPPolyLine::getDescription; } -- cgit v1.2.3 From 7df6616da5ea2debb86838366ddf746841549cdb Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:56:13 +0100 Subject: Renamed virtual function names. (bzr r11608.1.57) --- src/sp-polyline.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 048c54b06..e8144d2a5 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -46,15 +46,15 @@ void sp_polyline_init(SPPolyLine * polyline) polyline->cobject = polyline->cpolyline; } -void CPolyLine::onBuild(SPDocument * document, Inkscape::XML::Node * repr) { +void CPolyLine::build(SPDocument * document, Inkscape::XML::Node * repr) { SPPolyLine* object = this->sppolyline; - CShape::onBuild(document, repr); + CShape::build(document, repr); object->readAttr( "points" ); } -void CPolyLine::onSet(unsigned int key, const gchar* value) { +void CPolyLine::set(unsigned int key, const gchar* value) { SPPolyLine* object = this->sppolyline; SPPolyLine *polyline = object; @@ -105,12 +105,12 @@ void CPolyLine::onSet(unsigned int key, const gchar* value) { break; } default: - CShape::onSet(key, value); + CShape::set(key, value); break; } } -Inkscape::XML::Node* CPolyLine::onWrite(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node* CPolyLine::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { SPPolyLine* object = this->sppolyline; if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { @@ -121,12 +121,12 @@ Inkscape::XML::Node* CPolyLine::onWrite(Inkscape::XML::Document *xml_doc, Inksca repr->mergeFrom(object->getRepr(), "id"); } - CShape::onWrite(xml_doc, repr, flags); + CShape::write(xml_doc, repr, flags); return repr; } -gchar* CPolyLine::onDescription() { +gchar* CPolyLine::description() { return g_strdup(_("Polyline")); } -- cgit v1.2.3 From a5d6e692d661f0bf7648e64e8fcb04588bb8f3ab Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Mon, 1 Apr 2013 00:07:00 +0200 Subject: Prepared exchange of casting macros. (bzr r11608.1.63) --- src/sp-polyline.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index e8144d2a5..27d17d081 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -38,6 +38,7 @@ CPolyLine::~CPolyLine() { void sp_polyline_init(SPPolyLine * polyline) { polyline->cpolyline = new CPolyLine(polyline); + polyline->typeHierarchy.insert(typeid(SPPolyLine)); delete polyline->cshape; polyline->cshape = polyline->cpolyline; -- cgit v1.2.3 From 69f3b6f1abb2bb422935d43262e1e99aab359954 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 01:41:30 +0200 Subject: Added constructors to SP classes. (bzr r11608.1.67) --- src/sp-polyline.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 27d17d081..83d1265df 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -21,7 +21,7 @@ #include "document.h" -G_DEFINE_TYPE(SPPolyLine, sp_polyline, SP_TYPE_SHAPE); +G_DEFINE_TYPE(SPPolyLine, sp_polyline, G_TYPE_OBJECT); static void sp_polyline_class_init(SPPolyLineClass *klass) @@ -35,8 +35,9 @@ CPolyLine::CPolyLine(SPPolyLine* polyline) : CShape(polyline) { CPolyLine::~CPolyLine() { } -void sp_polyline_init(SPPolyLine * polyline) -{ +SPPolyLine::SPPolyLine() : SPShape() { + SPPolyLine* polyline = this; + polyline->cpolyline = new CPolyLine(polyline); polyline->typeHierarchy.insert(typeid(SPPolyLine)); @@ -47,6 +48,11 @@ void sp_polyline_init(SPPolyLine * polyline) polyline->cobject = polyline->cpolyline; } +void sp_polyline_init(SPPolyLine * polyline) +{ + new (polyline) SPPolyLine(); +} + void CPolyLine::build(SPDocument * document, Inkscape::XML::Node * repr) { SPPolyLine* object = this->sppolyline; -- cgit v1.2.3 From d1af3566872dfff2aeec84859c87f1f8d13f79df Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 19:14:36 +0200 Subject: Registered classes with new factory. Hkern, Vkern and FeFuncX have to be rewritten, as they aren't real classes. (bzr r11608.1.69) --- src/sp-polyline.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 83d1265df..efa2bf874 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -20,6 +20,15 @@ #include "xml/repr.h" #include "document.h" +#include "sp-factory.h" + +namespace { + SPObject* createPolyLine() { + return new SPPolyLine(); + } + + bool polyLineRegistered = SPFactory::instance().registerObject("svg:polyline", createPolyLine); +} G_DEFINE_TYPE(SPPolyLine, sp_polyline, G_TYPE_OBJECT); -- cgit v1.2.3 From 8443720ce6429b9beec839e60b8a808595f4ba72 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 23:01:45 +0200 Subject: Cleaned up a bit. Uses some C++11 features. (bzr r11608.1.72) --- src/sp-polyline.cpp | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index efa2bf874..310fd9db8 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -30,13 +30,6 @@ namespace { bool polyLineRegistered = SPFactory::instance().registerObject("svg:polyline", createPolyLine); } -G_DEFINE_TYPE(SPPolyLine, sp_polyline, G_TYPE_OBJECT); - -static void -sp_polyline_class_init(SPPolyLineClass *klass) -{ -} - CPolyLine::CPolyLine(SPPolyLine* polyline) : CShape(polyline) { this->sppolyline = polyline; } @@ -57,11 +50,6 @@ SPPolyLine::SPPolyLine() : SPShape() { polyline->cobject = polyline->cpolyline; } -void sp_polyline_init(SPPolyLine * polyline) -{ - new (polyline) SPPolyLine(); -} - void CPolyLine::build(SPDocument * document, Inkscape::XML::Node * repr) { SPPolyLine* object = this->sppolyline; -- cgit v1.2.3 From 748ffce08bb6250c87adabb64f45bff02509e9e7 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 5 Apr 2013 00:27:58 +0200 Subject: Combined some classes. (bzr r11608.1.75) --- src/sp-polyline.cpp | 74 +++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 310fd9db8..c97b96b73 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -30,38 +30,24 @@ namespace { bool polyLineRegistered = SPFactory::instance().registerObject("svg:polyline", createPolyLine); } -CPolyLine::CPolyLine(SPPolyLine* polyline) : CShape(polyline) { - this->sppolyline = polyline; +SPPolyLine::SPPolyLine() : SPShape(), CShape(this) { + delete this->cshape; + this->cshape = this; + this->clpeitem = this; + this->citem = this; + this->cobject = this; } -CPolyLine::~CPolyLine() { +SPPolyLine::~SPPolyLine() { } -SPPolyLine::SPPolyLine() : SPShape() { - SPPolyLine* polyline = this; - - polyline->cpolyline = new CPolyLine(polyline); - polyline->typeHierarchy.insert(typeid(SPPolyLine)); - - delete polyline->cshape; - polyline->cshape = polyline->cpolyline; - polyline->clpeitem = polyline->cpolyline; - polyline->citem = polyline->cpolyline; - polyline->cobject = polyline->cpolyline; -} - -void CPolyLine::build(SPDocument * document, Inkscape::XML::Node * repr) { - SPPolyLine* object = this->sppolyline; - +void SPPolyLine::build(SPDocument * document, Inkscape::XML::Node * repr) { CShape::build(document, repr); - object->readAttr( "points" ); + this->readAttr("points"); } -void CPolyLine::set(unsigned int key, const gchar* value) { - SPPolyLine* object = this->sppolyline; - SPPolyLine *polyline = object; - +void SPPolyLine::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_POINTS: { SPCurve * curve; @@ -69,7 +55,10 @@ void CPolyLine::set(unsigned int key, const gchar* value) { char * eptr; gboolean hascpt; - if (!value) break; + if (!value) { + break; + } + curve = new SPCurve (); hascpt = FALSE; @@ -82,20 +71,35 @@ void CPolyLine::set(unsigned int key, const gchar* value) { while (*cptr != '\0' && (*cptr == ',' || *cptr == '\x20' || *cptr == '\x9' || *cptr == '\xD' || *cptr == '\xA')) { cptr++; } - if (!*cptr) break; + + if (!*cptr) { + break; + } x = g_ascii_strtod (cptr, &eptr); - if (eptr == cptr) break; + + if (eptr == cptr) { + break; + } + cptr = eptr; while (*cptr != '\0' && (*cptr == ',' || *cptr == '\x20' || *cptr == '\x9' || *cptr == '\xD' || *cptr == '\xA')) { cptr++; } - if (!*cptr) break; + + if (!*cptr) { + break; + } y = g_ascii_strtod (cptr, &eptr); - if (eptr == cptr) break; + + if (eptr == cptr) { + break; + } + cptr = eptr; + if (hascpt) { curve->lineto(x, y); } else { @@ -104,7 +108,7 @@ void CPolyLine::set(unsigned int key, const gchar* value) { } } - (SP_SHAPE (polyline))->setCurve (curve, TRUE); + this->setCurve(curve, TRUE); curve->unref(); break; } @@ -114,15 +118,13 @@ void CPolyLine::set(unsigned int key, const gchar* value) { } } -Inkscape::XML::Node* CPolyLine::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPPolyLine* object = this->sppolyline; - +Inkscape::XML::Node* SPPolyLine::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:polyline"); } - if (repr != object->getRepr()) { - repr->mergeFrom(object->getRepr(), "id"); + if (repr != this->getRepr()) { + repr->mergeFrom(this->getRepr(), "id"); } CShape::write(xml_doc, repr, flags); @@ -130,7 +132,7 @@ Inkscape::XML::Node* CPolyLine::write(Inkscape::XML::Document *xml_doc, Inkscape return repr; } -gchar* CPolyLine::description() { +gchar* SPPolyLine::description() { return g_strdup(_("Polyline")); } -- cgit v1.2.3 From cfe48de7f071e2e07a1f2f2ace3456f7b410e93b Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 5 Apr 2013 15:37:33 +0200 Subject: Merged Shape and subclasses. Cleaned up a bit. (bzr r11608.1.76) --- src/sp-polyline.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index c97b96b73..a85d0d64a 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -30,9 +30,7 @@ namespace { bool polyLineRegistered = SPFactory::instance().registerObject("svg:polyline", createPolyLine); } -SPPolyLine::SPPolyLine() : SPShape(), CShape(this) { - delete this->cshape; - this->cshape = this; +SPPolyLine::SPPolyLine() : SPShape() { this->clpeitem = this; this->citem = this; this->cobject = this; @@ -42,7 +40,7 @@ SPPolyLine::~SPPolyLine() { } void SPPolyLine::build(SPDocument * document, Inkscape::XML::Node * repr) { - CShape::build(document, repr); + SPShape::build(document, repr); this->readAttr("points"); } @@ -113,7 +111,7 @@ void SPPolyLine::set(unsigned int key, const gchar* value) { break; } default: - CShape::set(key, value); + SPShape::set(key, value); break; } } @@ -127,7 +125,7 @@ Inkscape::XML::Node* SPPolyLine::write(Inkscape::XML::Document *xml_doc, Inkscap repr->mergeFrom(this->getRepr(), "id"); } - CShape::write(xml_doc, repr, flags); + SPShape::write(xml_doc, repr, flags); return repr; } -- cgit v1.2.3 From 19d00efa85cfc42ccae9bd17ef575602f0d22c50 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 5 Apr 2013 19:42:32 +0200 Subject: Merged more classes. (bzr r11608.1.78) --- src/sp-polyline.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index a85d0d64a..448c5a27b 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -31,7 +31,6 @@ namespace { } SPPolyLine::SPPolyLine() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; } -- cgit v1.2.3 From 8073924aacdda310fb7492750f78d5389b3186af Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 5 Apr 2013 22:45:01 +0200 Subject: Merged Item. (bzr r11608.1.81) --- src/sp-polyline.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 448c5a27b..4638952a6 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -31,7 +31,6 @@ namespace { } SPPolyLine::SPPolyLine() : SPShape() { - this->citem = this; this->cobject = this; } -- cgit v1.2.3 From 27e2102f96a5554bcd5310ec11435d155773b279 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sun, 7 Apr 2013 18:28:22 +0200 Subject: Merge Object and subclasses. Merging of SP- and C-classes complete. (bzr r11608.1.86) --- src/sp-polyline.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/sp-polyline.cpp') diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 4638952a6..1de5492cd 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -31,7 +31,6 @@ namespace { } SPPolyLine::SPPolyLine() : SPShape() { - this->cobject = this; } SPPolyLine::~SPPolyLine() { -- cgit v1.2.3