From 1e99fb68c13b9c322cea0650cd0d25a8ad7e8577 Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 25 Apr 2014 11:58:33 +0300 Subject: [PATCH 01/26] Change project structure for support libs. --HG-- branch : feature --- Valentina.pro | 218 +--------------- dist/copyright_template.txt | 27 ++ src/app/app.pri | 234 ++++++++++++++++++ src/app/app.pro | 234 ++++++++++++++++++ src/{ => app}/container/calculator.cpp | 0 src/{ => app}/container/calculator.h | 0 src/app/container/container.pri | 11 + src/{ => app}/container/vcontainer.cpp | 0 src/{ => app}/container/vcontainer.h | 0 src/{ => app}/container/vincrement.cpp | 0 src/{ => app}/container/vincrement.h | 0 src/{ => app}/container/vmeasurement.cpp | 0 src/{ => app}/container/vmeasurement.h | 0 src/{ => app}/dialogs/app/configdialog.cpp | 0 src/{ => app}/dialogs/app/configdialog.h | 0 src/{ => app}/dialogs/app/dialoghistory.cpp | 0 src/{ => app}/dialogs/app/dialoghistory.h | 0 src/{ => app}/dialogs/app/dialoghistory.ui | 0 .../dialogs/app/dialogincrements.cpp | 0 src/{ => app}/dialogs/app/dialogincrements.h | 0 src/{ => app}/dialogs/app/dialogincrements.ui | 0 .../app/dialogindividualmeasurements.cpp | 0 .../app/dialogindividualmeasurements.h | 0 .../app/dialogindividualmeasurements.ui | 0 .../dialogs/app/dialogmeasurements.cpp | 0 .../dialogs/app/dialogmeasurements.h | 0 .../dialogs/app/dialogmeasurements.ui | 0 .../dialogs/app/dialogpatternproperties.cpp | 0 .../dialogs/app/dialogpatternproperties.h | 0 .../dialogs/app/dialogpatternproperties.ui | 0 .../app/dialogstandardmeasurements.cpp | 0 .../dialogs/app/dialogstandardmeasurements.h | 0 .../dialogs/app/dialogstandardmeasurements.ui | 0 src/{ => app}/dialogs/app/pages.cpp | 0 src/{ => app}/dialogs/app/pages.h | 0 src/{ => app}/dialogs/dialogs.h | 0 src/app/dialogs/dialogs.pri | 90 +++++++ .../dialogs/tools/dialogalongline.cpp | 0 src/{ => app}/dialogs/tools/dialogalongline.h | 0 .../dialogs/tools/dialogalongline.ui | 0 src/{ => app}/dialogs/tools/dialogarc.cpp | 0 src/{ => app}/dialogs/tools/dialogarc.h | 0 src/{ => app}/dialogs/tools/dialogarc.ui | 0 .../dialogs/tools/dialogbisector.cpp | 0 src/{ => app}/dialogs/tools/dialogbisector.h | 0 src/{ => app}/dialogs/tools/dialogbisector.ui | 0 src/{ => app}/dialogs/tools/dialogcutarc.cpp | 0 src/{ => app}/dialogs/tools/dialogcutarc.h | 0 src/{ => app}/dialogs/tools/dialogcutarc.ui | 0 .../dialogs/tools/dialogcutspline.cpp | 0 src/{ => app}/dialogs/tools/dialogcutspline.h | 0 .../dialogs/tools/dialogcutspline.ui | 0 .../dialogs/tools/dialogcutsplinepath.cpp | 0 .../dialogs/tools/dialogcutsplinepath.h | 0 .../dialogs/tools/dialogcutsplinepath.ui | 0 src/{ => app}/dialogs/tools/dialogdetail.cpp | 0 src/{ => app}/dialogs/tools/dialogdetail.h | 0 src/{ => app}/dialogs/tools/dialogdetail.ui | 0 src/{ => app}/dialogs/tools/dialogendline.cpp | 0 src/{ => app}/dialogs/tools/dialogendline.h | 0 src/{ => app}/dialogs/tools/dialogendline.ui | 0 src/{ => app}/dialogs/tools/dialogheight.cpp | 0 src/{ => app}/dialogs/tools/dialogheight.h | 0 src/{ => app}/dialogs/tools/dialogheight.ui | 0 src/{ => app}/dialogs/tools/dialogline.cpp | 0 src/{ => app}/dialogs/tools/dialogline.h | 0 src/{ => app}/dialogs/tools/dialogline.ui | 0 .../dialogs/tools/dialoglineintersect.cpp | 0 .../dialogs/tools/dialoglineintersect.h | 0 .../dialogs/tools/dialoglineintersect.ui | 0 src/{ => app}/dialogs/tools/dialognormal.cpp | 0 src/{ => app}/dialogs/tools/dialognormal.h | 0 src/{ => app}/dialogs/tools/dialognormal.ui | 0 .../dialogs/tools/dialogpointofcontact.cpp | 0 .../dialogs/tools/dialogpointofcontact.h | 0 .../dialogs/tools/dialogpointofcontact.ui | 0 .../tools/dialogpointofintersection.cpp | 0 .../dialogs/tools/dialogpointofintersection.h | 0 .../tools/dialogpointofintersection.ui | 0 .../dialogs/tools/dialogshoulderpoint.cpp | 0 .../dialogs/tools/dialogshoulderpoint.h | 0 .../dialogs/tools/dialogshoulderpoint.ui | 0 .../dialogs/tools/dialogsinglepoint.cpp | 0 .../dialogs/tools/dialogsinglepoint.h | 0 .../dialogs/tools/dialogsinglepoint.ui | 0 src/{ => app}/dialogs/tools/dialogspline.cpp | 0 src/{ => app}/dialogs/tools/dialogspline.h | 0 src/{ => app}/dialogs/tools/dialogspline.ui | 0 .../dialogs/tools/dialogsplinepath.cpp | 0 .../dialogs/tools/dialogsplinepath.h | 0 .../dialogs/tools/dialogsplinepath.ui | 0 src/{ => app}/dialogs/tools/dialogtool.cpp | 0 src/{ => app}/dialogs/tools/dialogtool.h | 0 .../dialogs/tools/dialogtriangle.cpp | 0 src/{ => app}/dialogs/tools/dialogtriangle.h | 0 src/{ => app}/dialogs/tools/dialogtriangle.ui | 0 .../dialogs/tools/dialoguniondetails.cpp | 0 .../dialogs/tools/dialoguniondetails.h | 0 .../dialogs/tools/dialoguniondetails.ui | 0 src/app/exception/exception.pri | 15 ++ src/{ => app}/exception/vexception.cpp | 0 src/{ => app}/exception/vexception.h | 0 src/{ => app}/exception/vexceptionbadid.cpp | 0 src/{ => app}/exception/vexceptionbadid.h | 0 .../exception/vexceptionconversionerror.cpp | 0 .../exception/vexceptionconversionerror.h | 0 .../exception/vexceptionemptyparameter.cpp | 0 .../exception/vexceptionemptyparameter.h | 0 .../exception/vexceptionobjecterror.cpp | 0 .../exception/vexceptionobjecterror.h | 0 src/{ => app}/exception/vexceptionwrongid.cpp | 0 src/{ => app}/exception/vexceptionwrongid.h | 0 src/app/geometry/geometry.pri | 21 ++ src/{ => app}/geometry/varc.cpp | 0 src/{ => app}/geometry/varc.h | 0 src/{ => app}/geometry/vdetail.cpp | 0 src/{ => app}/geometry/vdetail.h | 0 src/{ => app}/geometry/vequidistant.cpp | 0 src/{ => app}/geometry/vequidistant.h | 0 src/{ => app}/geometry/vgobject.cpp | 0 src/{ => app}/geometry/vgobject.h | 0 src/{ => app}/geometry/vnodedetail.cpp | 0 src/{ => app}/geometry/vnodedetail.h | 0 src/{ => app}/geometry/vpointf.cpp | 0 src/{ => app}/geometry/vpointf.h | 0 src/{ => app}/geometry/vspline.cpp | 0 src/{ => app}/geometry/vspline.h | 0 src/{ => app}/geometry/vsplinepath.cpp | 0 src/{ => app}/geometry/vsplinepath.h | 0 src/{ => app}/geometry/vsplinepoint.cpp | 0 src/{ => app}/geometry/vsplinepoint.h | 0 src/{ => app}/main.cpp | 0 src/{ => app}/mainwindow.cpp | 0 src/{ => app}/mainwindow.h | 0 src/{ => app}/mainwindow.ui | 0 src/{ => app}/options.h | 0 {share => src/app/share}/resources/cursor.qrc | 0 .../resources/cursor/alongline_cursor.png | Bin .../share}/resources/cursor/arc_cursor.png | Bin .../resources/cursor/arc_cut_cursor.png | Bin .../resources/cursor/bisector_cursor.png | Bin .../resources/cursor/endline_cursor.png | Bin .../share}/resources/cursor/height_cursor.png | Bin .../resources/cursor/intersect_cursor.png | Bin .../share}/resources/cursor/line_cursor.png | Bin .../resources/cursor/new_detail_cursor.png | Bin .../share}/resources/cursor/normal_cursor.png | Bin .../resources/cursor/pointcontact_cursor.png | Bin .../cursor/pointofintersect_cursor.png | Bin .../resources/cursor/shoulder_cursor.png | Bin .../share}/resources/cursor/spline_cursor.png | Bin .../cursor/spline_cut_point_cursor.png | Bin .../resources/cursor/splinepath_cursor.png | Bin .../cursor/splinepath_cut_point_cursor.png | Bin .../resources/cursor/triangle_cursor.png | Bin .../share}/resources/cursor/union_cursor.png | Bin {share => src/app/share}/resources/icon.qrc | 0 .../share}/resources/icon/16x16/mirror.png | Bin .../share}/resources/icon/24x24/arrowDown.png | Bin .../share}/resources/icon/24x24/arrowLeft.png | Bin .../resources/icon/24x24/arrowLeftDown.png | Bin .../resources/icon/24x24/arrowLeftUp.png | Bin .../resources/icon/24x24/arrowRight.png | Bin .../resources/icon/24x24/arrowRightDown.png | Bin .../resources/icon/24x24/arrowRightUp.png | Bin .../share}/resources/icon/24x24/arrowUp.png | Bin .../app/share}/resources/icon/24x24/equal.png | Bin .../share}/resources/icon/24x24/putHere.png | Bin .../resources/icon/24x24/putHereLeft.png | Bin .../resources/icon/32x32/along_line.png | Bin .../app/share}/resources/icon/32x32/arc.png | Bin .../share}/resources/icon/32x32/arc_cut.png | Bin .../resources/icon/32x32/arrow_cursor.png | Bin .../share}/resources/icon/32x32/bisector.png | Bin .../app/share}/resources/icon/32x32/draw.png | Bin .../share}/resources/icon/32x32/height.png | Bin .../share}/resources/icon/32x32/history.png | Bin .../share}/resources/icon/32x32/intersect.png | Bin .../share}/resources/icon/32x32/kontur.png | Bin .../share}/resources/icon/32x32/layout.png | Bin .../app/share}/resources/icon/32x32/line.png | Bin .../resources/icon/32x32/new_detail.png | Bin .../share}/resources/icon/32x32/new_draw.png | Bin .../share}/resources/icon/32x32/normal.png | Bin .../resources/icon/32x32/option_draw.png | Bin .../resources/icon/32x32/point_of_contact.png | Bin .../icon/32x32/point_of_intersection.png | Bin .../share}/resources/icon/32x32/put_after.png | Bin .../share}/resources/icon/32x32/segment.png | Bin .../share}/resources/icon/32x32/shoulder.png | Bin .../share}/resources/icon/32x32/spline.png | Bin .../resources/icon/32x32/splinePath.png | Bin .../icon/32x32/splinePath_cut_point.png | Bin .../resources/icon/32x32/spline_cut_point.png | Bin .../app/share}/resources/icon/32x32/table.png | Bin .../share}/resources/icon/32x32/triangle.png | Bin .../app/share}/resources/icon/32x32/union.png | Bin .../share}/resources/icon/64x64/icon64x64.ico | Bin .../share}/resources/icon/64x64/icon64x64.png | Bin .../app/share}/resources/icon/Graduation.png | Bin .../app/share}/resources/icon/config.png | Bin .../app/share}/resources/icon/flags/cs.png | Bin .../app/share}/resources/icon/flags/de.png | Bin .../app/share}/resources/icon/flags/en.png | Bin .../app/share}/resources/icon/flags/fr.png | Bin .../app/share}/resources/icon/flags/he_IL.png | Bin .../app/share}/resources/icon/flags/ru.png | Bin .../app/share}/resources/icon/flags/uk.png | Bin .../app/share}/resources/icon/individual.png | Bin .../app/share}/resources/icon/logo.svg | 0 .../share}/resources/icon/pattern_config.png | Bin .../16x16/actions/document-new.png | Bin .../16x16/actions/document-open.png | Bin .../16x16/actions/document-save-as.png | Bin .../16x16/actions/document-save.png | Bin .../win.icon.theme/16x16/actions/go-next.png | Bin .../win.icon.theme/16x16/actions/list-add.png | Bin .../16x16/actions/list-remove.png | Bin .../16x16/actions/object-rotate-left.png | Bin .../16x16/actions/process-stop.png | Bin .../win.icon.theme/16x16/actions/zoom-in.png | Bin .../win.icon.theme/16x16/actions/zoom-out.png | Bin .../24x24/actions/document-new.png | Bin .../24x24/actions/document-open.png | Bin .../24x24/actions/document-save-as.png | Bin .../24x24/actions/document-save.png | Bin .../win.icon.theme/24x24/actions/go-next.png | Bin .../win.icon.theme/24x24/actions/list-add.png | Bin .../24x24/actions/list-remove.png | Bin .../24x24/actions/object-rotate-left.png | Bin .../24x24/actions/process-stop.png | Bin .../win.icon.theme/24x24/actions/zoom-in.png | Bin .../win.icon.theme/24x24/actions/zoom-out.png | Bin .../32x32/actions/document-new.png | Bin .../32x32/actions/document-open.png | Bin .../32x32/actions/document-save-as.png | Bin .../32x32/actions/document-save.png | Bin .../win.icon.theme/32x32/actions/go-next.png | Bin .../win.icon.theme/32x32/actions/list-add.png | Bin .../32x32/actions/list-remove.png | Bin .../32x32/actions/object-rotate-left.png | Bin .../32x32/actions/process-stop.png | Bin .../win.icon.theme/32x32/actions/zoom-in.png | Bin .../win.icon.theme/32x32/actions/zoom-out.png | Bin .../icons/win.icon.theme/index.theme | 0 {share => src/app/share}/resources/schema.qrc | 0 .../schema/individual_measurements.xsd | 0 .../app/share}/resources/schema/pattern.xsd | 0 .../schema/standard_measurements.xsd | 0 {share => src/app/share}/resources/theme.qrc | 0 .../app/share}/resources/valentina.rc | 0 .../tables/individual/indivindual_ru.vit | 0 .../share}/tables/standard/GOST_man_ru.vst | 0 .../app/share}/translations/valentina.ts | 0 .../app/share}/translations/valentina_cs.ts | 0 .../app/share}/translations/valentina_de.ts | 0 .../app/share}/translations/valentina_fr.ts | 0 .../share}/translations/valentina_he_IL.ts | 0 .../app/share}/translations/valentina_ru.ts | 0 .../app/share}/translations/valentina_uk.ts | 0 src/{ => app}/stable.cpp | 0 src/{ => app}/stable.h | 0 src/{ => app}/tablewindow.cpp | 0 src/{ => app}/tablewindow.h | 0 src/{ => app}/tablewindow.ui | 0 src/{ => app}/tools/drawTools/drawtools.h | 0 .../tools/drawTools/vabstractspline.cpp | 0 .../tools/drawTools/vabstractspline.h | 0 src/{ => app}/tools/drawTools/vdrawtool.cpp | 0 src/{ => app}/tools/drawTools/vdrawtool.h | 0 .../tools/drawTools/vtoolalongline.cpp | 0 .../tools/drawTools/vtoolalongline.h | 0 src/{ => app}/tools/drawTools/vtoolarc.cpp | 0 src/{ => app}/tools/drawTools/vtoolarc.h | 0 .../tools/drawTools/vtoolbisector.cpp | 0 src/{ => app}/tools/drawTools/vtoolbisector.h | 0 src/{ => app}/tools/drawTools/vtoolcutarc.cpp | 0 src/{ => app}/tools/drawTools/vtoolcutarc.h | 0 .../tools/drawTools/vtoolcutspline.cpp | 0 .../tools/drawTools/vtoolcutspline.h | 0 .../tools/drawTools/vtoolcutsplinepath.cpp | 0 .../tools/drawTools/vtoolcutsplinepath.h | 0 .../tools/drawTools/vtoolendline.cpp | 0 src/{ => app}/tools/drawTools/vtoolendline.h | 0 src/{ => app}/tools/drawTools/vtoolheight.cpp | 0 src/{ => app}/tools/drawTools/vtoolheight.h | 0 src/{ => app}/tools/drawTools/vtoolline.cpp | 0 src/{ => app}/tools/drawTools/vtoolline.h | 0 .../tools/drawTools/vtoollineintersect.cpp | 0 .../tools/drawTools/vtoollineintersect.h | 0 .../tools/drawTools/vtoollinepoint.cpp | 0 .../tools/drawTools/vtoollinepoint.h | 0 src/{ => app}/tools/drawTools/vtoolnormal.cpp | 0 src/{ => app}/tools/drawTools/vtoolnormal.h | 0 src/{ => app}/tools/drawTools/vtoolpoint.cpp | 0 src/{ => app}/tools/drawTools/vtoolpoint.h | 0 .../tools/drawTools/vtoolpointofcontact.cpp | 0 .../tools/drawTools/vtoolpointofcontact.h | 0 .../drawTools/vtoolpointofintersection.cpp | 0 .../drawTools/vtoolpointofintersection.h | 0 .../tools/drawTools/vtoolshoulderpoint.cpp | 0 .../tools/drawTools/vtoolshoulderpoint.h | 0 .../tools/drawTools/vtoolsinglepoint.cpp | 0 .../tools/drawTools/vtoolsinglepoint.h | 0 src/{ => app}/tools/drawTools/vtoolspline.cpp | 0 src/{ => app}/tools/drawTools/vtoolspline.h | 0 .../tools/drawTools/vtoolsplinepath.cpp | 0 .../tools/drawTools/vtoolsplinepath.h | 0 .../tools/drawTools/vtooltriangle.cpp | 0 src/{ => app}/tools/drawTools/vtooltriangle.h | 0 src/{ => app}/tools/nodeDetails/nodedetails.h | 0 .../tools/nodeDetails/vabstractnode.cpp | 0 .../tools/nodeDetails/vabstractnode.h | 0 src/{ => app}/tools/nodeDetails/vnodearc.cpp | 0 src/{ => app}/tools/nodeDetails/vnodearc.h | 0 .../tools/nodeDetails/vnodepoint.cpp | 0 src/{ => app}/tools/nodeDetails/vnodepoint.h | 0 .../tools/nodeDetails/vnodespline.cpp | 0 src/{ => app}/tools/nodeDetails/vnodespline.h | 0 .../tools/nodeDetails/vnodesplinepath.cpp | 0 .../tools/nodeDetails/vnodesplinepath.h | 0 src/{ => app}/tools/tools.h | 0 src/app/tools/tools.pri | 68 +++++ src/{ => app}/tools/vabstracttool.cpp | 0 src/{ => app}/tools/vabstracttool.h | 0 src/{ => app}/tools/vdatatool.cpp | 0 src/{ => app}/tools/vdatatool.h | 0 src/{ => app}/tools/vtooldetail.cpp | 0 src/{ => app}/tools/vtooldetail.h | 0 src/{ => app}/tools/vtooluniondetails.cpp | 0 src/{ => app}/tools/vtooluniondetails.h | 0 src/{ => app}/version.cpp | 0 src/{ => app}/version.h | 0 src/{ => app}/widgets/doubledelegate.cpp | 0 src/{ => app}/widgets/doubledelegate.h | 0 src/{ => app}/widgets/textdelegate.cpp | 0 src/{ => app}/widgets/textdelegate.h | 0 src/{ => app}/widgets/vapplication.cpp | 0 src/{ => app}/widgets/vapplication.h | 0 src/{ => app}/widgets/vcontrolpointspline.cpp | 0 src/{ => app}/widgets/vcontrolpointspline.h | 0 .../widgets/vgraphicssimpletextitem.cpp | 0 .../widgets/vgraphicssimpletextitem.h | 0 src/{ => app}/widgets/vitem.cpp | 0 src/{ => app}/widgets/vitem.h | 0 src/{ => app}/widgets/vmaingraphicsscene.cpp | 0 src/{ => app}/widgets/vmaingraphicsscene.h | 0 src/{ => app}/widgets/vmaingraphicsview.cpp | 0 src/{ => app}/widgets/vmaingraphicsview.h | 0 src/{ => app}/widgets/vsimplearc.cpp | 0 src/{ => app}/widgets/vsimplearc.h | 0 src/{ => app}/widgets/vsimplespline.cpp | 0 src/{ => app}/widgets/vsimplespline.h | 0 src/{ => app}/widgets/vsimplesplinepath.cpp | 0 src/{ => app}/widgets/vsimplesplinepath.h | 0 src/{ => app}/widgets/vtablegraphicsview.cpp | 0 src/{ => app}/widgets/vtablegraphicsview.h | 0 src/app/widgets/widgets.pri | 27 ++ src/{ => app}/xml/vdomdocument.cpp | 0 src/{ => app}/xml/vdomdocument.h | 0 src/{ => app}/xml/vindividualmeasurements.cpp | 0 src/{ => app}/xml/vindividualmeasurements.h | 0 src/{ => app}/xml/vpattern.cpp | 0 src/{ => app}/xml/vpattern.h | 0 src/{ => app}/xml/vstandardmeasurements.cpp | 0 src/{ => app}/xml/vstandardmeasurements.h | 0 src/{ => app}/xml/vtoolrecord.cpp | 0 src/{ => app}/xml/vtoolrecord.h | 0 src/app/xml/xml.pri | 13 + src/container/container.pri | 11 - src/dialogs/dialogs.pri | 90 ------- src/exception/exception.pri | 15 -- src/geometry/geometry.pri | 21 -- src/src.pri | 14 -- src/src.pro | 50 ++++ src/tools/tools.pri | 68 ----- src/widgets/widgets.pri | 27 -- src/xml/xml.pri | 13 - 378 files changed, 792 insertions(+), 475 deletions(-) create mode 100644 dist/copyright_template.txt create mode 100644 src/app/app.pri create mode 100644 src/app/app.pro rename src/{ => app}/container/calculator.cpp (100%) rename src/{ => app}/container/calculator.h (100%) create mode 100644 src/app/container/container.pri rename src/{ => app}/container/vcontainer.cpp (100%) rename src/{ => app}/container/vcontainer.h (100%) rename src/{ => app}/container/vincrement.cpp (100%) rename src/{ => app}/container/vincrement.h (100%) rename src/{ => app}/container/vmeasurement.cpp (100%) rename src/{ => app}/container/vmeasurement.h (100%) rename src/{ => app}/dialogs/app/configdialog.cpp (100%) rename src/{ => app}/dialogs/app/configdialog.h (100%) rename src/{ => app}/dialogs/app/dialoghistory.cpp (100%) rename src/{ => app}/dialogs/app/dialoghistory.h (100%) rename src/{ => app}/dialogs/app/dialoghistory.ui (100%) rename src/{ => app}/dialogs/app/dialogincrements.cpp (100%) rename src/{ => app}/dialogs/app/dialogincrements.h (100%) rename src/{ => app}/dialogs/app/dialogincrements.ui (100%) rename src/{ => app}/dialogs/app/dialogindividualmeasurements.cpp (100%) rename src/{ => app}/dialogs/app/dialogindividualmeasurements.h (100%) rename src/{ => app}/dialogs/app/dialogindividualmeasurements.ui (100%) rename src/{ => app}/dialogs/app/dialogmeasurements.cpp (100%) rename src/{ => app}/dialogs/app/dialogmeasurements.h (100%) rename src/{ => app}/dialogs/app/dialogmeasurements.ui (100%) rename src/{ => app}/dialogs/app/dialogpatternproperties.cpp (100%) rename src/{ => app}/dialogs/app/dialogpatternproperties.h (100%) rename src/{ => app}/dialogs/app/dialogpatternproperties.ui (100%) rename src/{ => app}/dialogs/app/dialogstandardmeasurements.cpp (100%) rename src/{ => app}/dialogs/app/dialogstandardmeasurements.h (100%) rename src/{ => app}/dialogs/app/dialogstandardmeasurements.ui (100%) rename src/{ => app}/dialogs/app/pages.cpp (100%) rename src/{ => app}/dialogs/app/pages.h (100%) rename src/{ => app}/dialogs/dialogs.h (100%) create mode 100644 src/app/dialogs/dialogs.pri rename src/{ => app}/dialogs/tools/dialogalongline.cpp (100%) rename src/{ => app}/dialogs/tools/dialogalongline.h (100%) rename src/{ => app}/dialogs/tools/dialogalongline.ui (100%) rename src/{ => app}/dialogs/tools/dialogarc.cpp (100%) rename src/{ => app}/dialogs/tools/dialogarc.h (100%) rename src/{ => app}/dialogs/tools/dialogarc.ui (100%) rename src/{ => app}/dialogs/tools/dialogbisector.cpp (100%) rename src/{ => app}/dialogs/tools/dialogbisector.h (100%) rename src/{ => app}/dialogs/tools/dialogbisector.ui (100%) rename src/{ => app}/dialogs/tools/dialogcutarc.cpp (100%) rename src/{ => app}/dialogs/tools/dialogcutarc.h (100%) rename src/{ => app}/dialogs/tools/dialogcutarc.ui (100%) rename src/{ => app}/dialogs/tools/dialogcutspline.cpp (100%) rename src/{ => app}/dialogs/tools/dialogcutspline.h (100%) rename src/{ => app}/dialogs/tools/dialogcutspline.ui (100%) rename src/{ => app}/dialogs/tools/dialogcutsplinepath.cpp (100%) rename src/{ => app}/dialogs/tools/dialogcutsplinepath.h (100%) rename src/{ => app}/dialogs/tools/dialogcutsplinepath.ui (100%) rename src/{ => app}/dialogs/tools/dialogdetail.cpp (100%) rename src/{ => app}/dialogs/tools/dialogdetail.h (100%) rename src/{ => app}/dialogs/tools/dialogdetail.ui (100%) rename src/{ => app}/dialogs/tools/dialogendline.cpp (100%) rename src/{ => app}/dialogs/tools/dialogendline.h (100%) rename src/{ => app}/dialogs/tools/dialogendline.ui (100%) rename src/{ => app}/dialogs/tools/dialogheight.cpp (100%) rename src/{ => app}/dialogs/tools/dialogheight.h (100%) rename src/{ => app}/dialogs/tools/dialogheight.ui (100%) rename src/{ => app}/dialogs/tools/dialogline.cpp (100%) rename src/{ => app}/dialogs/tools/dialogline.h (100%) rename src/{ => app}/dialogs/tools/dialogline.ui (100%) rename src/{ => app}/dialogs/tools/dialoglineintersect.cpp (100%) rename src/{ => app}/dialogs/tools/dialoglineintersect.h (100%) rename src/{ => app}/dialogs/tools/dialoglineintersect.ui (100%) rename src/{ => app}/dialogs/tools/dialognormal.cpp (100%) rename src/{ => app}/dialogs/tools/dialognormal.h (100%) rename src/{ => app}/dialogs/tools/dialognormal.ui (100%) rename src/{ => app}/dialogs/tools/dialogpointofcontact.cpp (100%) rename src/{ => app}/dialogs/tools/dialogpointofcontact.h (100%) rename src/{ => app}/dialogs/tools/dialogpointofcontact.ui (100%) rename src/{ => app}/dialogs/tools/dialogpointofintersection.cpp (100%) rename src/{ => app}/dialogs/tools/dialogpointofintersection.h (100%) rename src/{ => app}/dialogs/tools/dialogpointofintersection.ui (100%) rename src/{ => app}/dialogs/tools/dialogshoulderpoint.cpp (100%) rename src/{ => app}/dialogs/tools/dialogshoulderpoint.h (100%) rename src/{ => app}/dialogs/tools/dialogshoulderpoint.ui (100%) rename src/{ => app}/dialogs/tools/dialogsinglepoint.cpp (100%) rename src/{ => app}/dialogs/tools/dialogsinglepoint.h (100%) rename src/{ => app}/dialogs/tools/dialogsinglepoint.ui (100%) rename src/{ => app}/dialogs/tools/dialogspline.cpp (100%) rename src/{ => app}/dialogs/tools/dialogspline.h (100%) rename src/{ => app}/dialogs/tools/dialogspline.ui (100%) rename src/{ => app}/dialogs/tools/dialogsplinepath.cpp (100%) rename src/{ => app}/dialogs/tools/dialogsplinepath.h (100%) rename src/{ => app}/dialogs/tools/dialogsplinepath.ui (100%) rename src/{ => app}/dialogs/tools/dialogtool.cpp (100%) rename src/{ => app}/dialogs/tools/dialogtool.h (100%) rename src/{ => app}/dialogs/tools/dialogtriangle.cpp (100%) rename src/{ => app}/dialogs/tools/dialogtriangle.h (100%) rename src/{ => app}/dialogs/tools/dialogtriangle.ui (100%) rename src/{ => app}/dialogs/tools/dialoguniondetails.cpp (100%) rename src/{ => app}/dialogs/tools/dialoguniondetails.h (100%) rename src/{ => app}/dialogs/tools/dialoguniondetails.ui (100%) create mode 100644 src/app/exception/exception.pri rename src/{ => app}/exception/vexception.cpp (100%) rename src/{ => app}/exception/vexception.h (100%) rename src/{ => app}/exception/vexceptionbadid.cpp (100%) rename src/{ => app}/exception/vexceptionbadid.h (100%) rename src/{ => app}/exception/vexceptionconversionerror.cpp (100%) rename src/{ => app}/exception/vexceptionconversionerror.h (100%) rename src/{ => app}/exception/vexceptionemptyparameter.cpp (100%) rename src/{ => app}/exception/vexceptionemptyparameter.h (100%) rename src/{ => app}/exception/vexceptionobjecterror.cpp (100%) rename src/{ => app}/exception/vexceptionobjecterror.h (100%) rename src/{ => app}/exception/vexceptionwrongid.cpp (100%) rename src/{ => app}/exception/vexceptionwrongid.h (100%) create mode 100644 src/app/geometry/geometry.pri rename src/{ => app}/geometry/varc.cpp (100%) rename src/{ => app}/geometry/varc.h (100%) rename src/{ => app}/geometry/vdetail.cpp (100%) rename src/{ => app}/geometry/vdetail.h (100%) rename src/{ => app}/geometry/vequidistant.cpp (100%) rename src/{ => app}/geometry/vequidistant.h (100%) rename src/{ => app}/geometry/vgobject.cpp (100%) rename src/{ => app}/geometry/vgobject.h (100%) rename src/{ => app}/geometry/vnodedetail.cpp (100%) rename src/{ => app}/geometry/vnodedetail.h (100%) rename src/{ => app}/geometry/vpointf.cpp (100%) rename src/{ => app}/geometry/vpointf.h (100%) rename src/{ => app}/geometry/vspline.cpp (100%) rename src/{ => app}/geometry/vspline.h (100%) rename src/{ => app}/geometry/vsplinepath.cpp (100%) rename src/{ => app}/geometry/vsplinepath.h (100%) rename src/{ => app}/geometry/vsplinepoint.cpp (100%) rename src/{ => app}/geometry/vsplinepoint.h (100%) rename src/{ => app}/main.cpp (100%) rename src/{ => app}/mainwindow.cpp (100%) rename src/{ => app}/mainwindow.h (100%) rename src/{ => app}/mainwindow.ui (100%) rename src/{ => app}/options.h (100%) rename {share => src/app/share}/resources/cursor.qrc (100%) rename {share => src/app/share}/resources/cursor/alongline_cursor.png (100%) rename {share => src/app/share}/resources/cursor/arc_cursor.png (100%) rename {share => src/app/share}/resources/cursor/arc_cut_cursor.png (100%) rename {share => src/app/share}/resources/cursor/bisector_cursor.png (100%) rename {share => src/app/share}/resources/cursor/endline_cursor.png (100%) rename {share => src/app/share}/resources/cursor/height_cursor.png (100%) rename {share => src/app/share}/resources/cursor/intersect_cursor.png (100%) rename {share => src/app/share}/resources/cursor/line_cursor.png (100%) rename {share => src/app/share}/resources/cursor/new_detail_cursor.png (100%) rename {share => src/app/share}/resources/cursor/normal_cursor.png (100%) rename {share => src/app/share}/resources/cursor/pointcontact_cursor.png (100%) rename {share => src/app/share}/resources/cursor/pointofintersect_cursor.png (100%) rename {share => src/app/share}/resources/cursor/shoulder_cursor.png (100%) rename {share => src/app/share}/resources/cursor/spline_cursor.png (100%) rename {share => src/app/share}/resources/cursor/spline_cut_point_cursor.png (100%) rename {share => src/app/share}/resources/cursor/splinepath_cursor.png (100%) rename {share => src/app/share}/resources/cursor/splinepath_cut_point_cursor.png (100%) rename {share => src/app/share}/resources/cursor/triangle_cursor.png (100%) rename {share => src/app/share}/resources/cursor/union_cursor.png (100%) rename {share => src/app/share}/resources/icon.qrc (100%) rename {share => src/app/share}/resources/icon/16x16/mirror.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowDown.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowLeft.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowLeftDown.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowLeftUp.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowRight.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowRightDown.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowRightUp.png (100%) rename {share => src/app/share}/resources/icon/24x24/arrowUp.png (100%) rename {share => src/app/share}/resources/icon/24x24/equal.png (100%) rename {share => src/app/share}/resources/icon/24x24/putHere.png (100%) rename {share => src/app/share}/resources/icon/24x24/putHereLeft.png (100%) rename {share => src/app/share}/resources/icon/32x32/along_line.png (100%) rename {share => src/app/share}/resources/icon/32x32/arc.png (100%) rename {share => src/app/share}/resources/icon/32x32/arc_cut.png (100%) rename {share => src/app/share}/resources/icon/32x32/arrow_cursor.png (100%) rename {share => src/app/share}/resources/icon/32x32/bisector.png (100%) rename {share => src/app/share}/resources/icon/32x32/draw.png (100%) rename {share => src/app/share}/resources/icon/32x32/height.png (100%) rename {share => src/app/share}/resources/icon/32x32/history.png (100%) rename {share => src/app/share}/resources/icon/32x32/intersect.png (100%) rename {share => src/app/share}/resources/icon/32x32/kontur.png (100%) rename {share => src/app/share}/resources/icon/32x32/layout.png (100%) rename {share => src/app/share}/resources/icon/32x32/line.png (100%) rename {share => src/app/share}/resources/icon/32x32/new_detail.png (100%) rename {share => src/app/share}/resources/icon/32x32/new_draw.png (100%) rename {share => src/app/share}/resources/icon/32x32/normal.png (100%) rename {share => src/app/share}/resources/icon/32x32/option_draw.png (100%) rename {share => src/app/share}/resources/icon/32x32/point_of_contact.png (100%) rename {share => src/app/share}/resources/icon/32x32/point_of_intersection.png (100%) rename {share => src/app/share}/resources/icon/32x32/put_after.png (100%) rename {share => src/app/share}/resources/icon/32x32/segment.png (100%) rename {share => src/app/share}/resources/icon/32x32/shoulder.png (100%) rename {share => src/app/share}/resources/icon/32x32/spline.png (100%) rename {share => src/app/share}/resources/icon/32x32/splinePath.png (100%) rename {share => src/app/share}/resources/icon/32x32/splinePath_cut_point.png (100%) rename {share => src/app/share}/resources/icon/32x32/spline_cut_point.png (100%) rename {share => src/app/share}/resources/icon/32x32/table.png (100%) rename {share => src/app/share}/resources/icon/32x32/triangle.png (100%) rename {share => src/app/share}/resources/icon/32x32/union.png (100%) rename {share => src/app/share}/resources/icon/64x64/icon64x64.ico (100%) rename {share => src/app/share}/resources/icon/64x64/icon64x64.png (100%) rename {share => src/app/share}/resources/icon/Graduation.png (100%) rename {share => src/app/share}/resources/icon/config.png (100%) rename {share => src/app/share}/resources/icon/flags/cs.png (100%) rename {share => src/app/share}/resources/icon/flags/de.png (100%) rename {share => src/app/share}/resources/icon/flags/en.png (100%) rename {share => src/app/share}/resources/icon/flags/fr.png (100%) rename {share => src/app/share}/resources/icon/flags/he_IL.png (100%) rename {share => src/app/share}/resources/icon/flags/ru.png (100%) rename {share => src/app/share}/resources/icon/flags/uk.png (100%) rename {share => src/app/share}/resources/icon/individual.png (100%) rename {share => src/app/share}/resources/icon/logo.svg (100%) rename {share => src/app/share}/resources/icon/pattern_config.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/document-new.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/document-open.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/document-save-as.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/document-save.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/go-next.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/list-add.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/list-remove.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/object-rotate-left.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/process-stop.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/zoom-in.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/16x16/actions/zoom-out.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/document-new.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/document-open.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/document-save-as.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/document-save.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/go-next.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/list-add.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/list-remove.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/object-rotate-left.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/process-stop.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/zoom-in.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/24x24/actions/zoom-out.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/document-new.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/document-open.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/document-save-as.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/document-save.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/go-next.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/list-add.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/list-remove.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/object-rotate-left.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/process-stop.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/zoom-in.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/32x32/actions/zoom-out.png (100%) rename {share => src/app/share}/resources/icons/win.icon.theme/index.theme (100%) rename {share => src/app/share}/resources/schema.qrc (100%) rename {share => src/app/share}/resources/schema/individual_measurements.xsd (100%) rename {share => src/app/share}/resources/schema/pattern.xsd (100%) rename {share => src/app/share}/resources/schema/standard_measurements.xsd (100%) rename {share => src/app/share}/resources/theme.qrc (100%) rename {share => src/app/share}/resources/valentina.rc (100%) rename {share => src/app/share}/tables/individual/indivindual_ru.vit (100%) rename {share => src/app/share}/tables/standard/GOST_man_ru.vst (100%) rename {share => src/app/share}/translations/valentina.ts (100%) rename {share => src/app/share}/translations/valentina_cs.ts (100%) rename {share => src/app/share}/translations/valentina_de.ts (100%) rename {share => src/app/share}/translations/valentina_fr.ts (100%) rename {share => src/app/share}/translations/valentina_he_IL.ts (100%) rename {share => src/app/share}/translations/valentina_ru.ts (100%) rename {share => src/app/share}/translations/valentina_uk.ts (100%) rename src/{ => app}/stable.cpp (100%) rename src/{ => app}/stable.h (100%) rename src/{ => app}/tablewindow.cpp (100%) rename src/{ => app}/tablewindow.h (100%) rename src/{ => app}/tablewindow.ui (100%) rename src/{ => app}/tools/drawTools/drawtools.h (100%) rename src/{ => app}/tools/drawTools/vabstractspline.cpp (100%) rename src/{ => app}/tools/drawTools/vabstractspline.h (100%) rename src/{ => app}/tools/drawTools/vdrawtool.cpp (100%) rename src/{ => app}/tools/drawTools/vdrawtool.h (100%) rename src/{ => app}/tools/drawTools/vtoolalongline.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolalongline.h (100%) rename src/{ => app}/tools/drawTools/vtoolarc.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolarc.h (100%) rename src/{ => app}/tools/drawTools/vtoolbisector.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolbisector.h (100%) rename src/{ => app}/tools/drawTools/vtoolcutarc.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolcutarc.h (100%) rename src/{ => app}/tools/drawTools/vtoolcutspline.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolcutspline.h (100%) rename src/{ => app}/tools/drawTools/vtoolcutsplinepath.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolcutsplinepath.h (100%) rename src/{ => app}/tools/drawTools/vtoolendline.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolendline.h (100%) rename src/{ => app}/tools/drawTools/vtoolheight.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolheight.h (100%) rename src/{ => app}/tools/drawTools/vtoolline.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolline.h (100%) rename src/{ => app}/tools/drawTools/vtoollineintersect.cpp (100%) rename src/{ => app}/tools/drawTools/vtoollineintersect.h (100%) rename src/{ => app}/tools/drawTools/vtoollinepoint.cpp (100%) rename src/{ => app}/tools/drawTools/vtoollinepoint.h (100%) rename src/{ => app}/tools/drawTools/vtoolnormal.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolnormal.h (100%) rename src/{ => app}/tools/drawTools/vtoolpoint.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolpoint.h (100%) rename src/{ => app}/tools/drawTools/vtoolpointofcontact.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolpointofcontact.h (100%) rename src/{ => app}/tools/drawTools/vtoolpointofintersection.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolpointofintersection.h (100%) rename src/{ => app}/tools/drawTools/vtoolshoulderpoint.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolshoulderpoint.h (100%) rename src/{ => app}/tools/drawTools/vtoolsinglepoint.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolsinglepoint.h (100%) rename src/{ => app}/tools/drawTools/vtoolspline.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolspline.h (100%) rename src/{ => app}/tools/drawTools/vtoolsplinepath.cpp (100%) rename src/{ => app}/tools/drawTools/vtoolsplinepath.h (100%) rename src/{ => app}/tools/drawTools/vtooltriangle.cpp (100%) rename src/{ => app}/tools/drawTools/vtooltriangle.h (100%) rename src/{ => app}/tools/nodeDetails/nodedetails.h (100%) rename src/{ => app}/tools/nodeDetails/vabstractnode.cpp (100%) rename src/{ => app}/tools/nodeDetails/vabstractnode.h (100%) rename src/{ => app}/tools/nodeDetails/vnodearc.cpp (100%) rename src/{ => app}/tools/nodeDetails/vnodearc.h (100%) rename src/{ => app}/tools/nodeDetails/vnodepoint.cpp (100%) rename src/{ => app}/tools/nodeDetails/vnodepoint.h (100%) rename src/{ => app}/tools/nodeDetails/vnodespline.cpp (100%) rename src/{ => app}/tools/nodeDetails/vnodespline.h (100%) rename src/{ => app}/tools/nodeDetails/vnodesplinepath.cpp (100%) rename src/{ => app}/tools/nodeDetails/vnodesplinepath.h (100%) rename src/{ => app}/tools/tools.h (100%) create mode 100644 src/app/tools/tools.pri rename src/{ => app}/tools/vabstracttool.cpp (100%) rename src/{ => app}/tools/vabstracttool.h (100%) rename src/{ => app}/tools/vdatatool.cpp (100%) rename src/{ => app}/tools/vdatatool.h (100%) rename src/{ => app}/tools/vtooldetail.cpp (100%) rename src/{ => app}/tools/vtooldetail.h (100%) rename src/{ => app}/tools/vtooluniondetails.cpp (100%) rename src/{ => app}/tools/vtooluniondetails.h (100%) rename src/{ => app}/version.cpp (100%) rename src/{ => app}/version.h (100%) rename src/{ => app}/widgets/doubledelegate.cpp (100%) rename src/{ => app}/widgets/doubledelegate.h (100%) rename src/{ => app}/widgets/textdelegate.cpp (100%) rename src/{ => app}/widgets/textdelegate.h (100%) rename src/{ => app}/widgets/vapplication.cpp (100%) rename src/{ => app}/widgets/vapplication.h (100%) rename src/{ => app}/widgets/vcontrolpointspline.cpp (100%) rename src/{ => app}/widgets/vcontrolpointspline.h (100%) rename src/{ => app}/widgets/vgraphicssimpletextitem.cpp (100%) rename src/{ => app}/widgets/vgraphicssimpletextitem.h (100%) rename src/{ => app}/widgets/vitem.cpp (100%) rename src/{ => app}/widgets/vitem.h (100%) rename src/{ => app}/widgets/vmaingraphicsscene.cpp (100%) rename src/{ => app}/widgets/vmaingraphicsscene.h (100%) rename src/{ => app}/widgets/vmaingraphicsview.cpp (100%) rename src/{ => app}/widgets/vmaingraphicsview.h (100%) rename src/{ => app}/widgets/vsimplearc.cpp (100%) rename src/{ => app}/widgets/vsimplearc.h (100%) rename src/{ => app}/widgets/vsimplespline.cpp (100%) rename src/{ => app}/widgets/vsimplespline.h (100%) rename src/{ => app}/widgets/vsimplesplinepath.cpp (100%) rename src/{ => app}/widgets/vsimplesplinepath.h (100%) rename src/{ => app}/widgets/vtablegraphicsview.cpp (100%) rename src/{ => app}/widgets/vtablegraphicsview.h (100%) create mode 100644 src/app/widgets/widgets.pri rename src/{ => app}/xml/vdomdocument.cpp (100%) rename src/{ => app}/xml/vdomdocument.h (100%) rename src/{ => app}/xml/vindividualmeasurements.cpp (100%) rename src/{ => app}/xml/vindividualmeasurements.h (100%) rename src/{ => app}/xml/vpattern.cpp (100%) rename src/{ => app}/xml/vpattern.h (100%) rename src/{ => app}/xml/vstandardmeasurements.cpp (100%) rename src/{ => app}/xml/vstandardmeasurements.h (100%) rename src/{ => app}/xml/vtoolrecord.cpp (100%) rename src/{ => app}/xml/vtoolrecord.h (100%) create mode 100644 src/app/xml/xml.pri delete mode 100644 src/container/container.pri delete mode 100644 src/dialogs/dialogs.pri delete mode 100644 src/exception/exception.pri delete mode 100644 src/geometry/geometry.pri delete mode 100644 src/src.pri create mode 100644 src/src.pro delete mode 100644 src/tools/tools.pri delete mode 100644 src/widgets/widgets.pri delete mode 100644 src/xml/xml.pri diff --git a/Valentina.pro b/Valentina.pro index a3d4f4742..65d926226 100644 --- a/Valentina.pro +++ b/Valentina.pro @@ -1,216 +1,2 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2013-06-18T12:36:43 -# -#------------------------------------------------- - -# Use out-of-source builds (shadow builds) - -QT += core gui widgets xml svg printsupport xmlpatterns - -TEMPLATE = app - -TARGET = valentina - -CONFIG -= debug_and_release debug_and_release_target -CONFIG += c++11 - -#DEFINES += ... - -# directory for executable file -DESTDIR = bin - -# files created moc -MOC_DIR = moc - -# objecs files -OBJECTS_DIR = obj - -# files created rcc -RCC_DIR = rcc - -# files created uic -UI_DIR = uic - -include(src/src.pri) -include(src/container/container.pri) -include(src/dialogs/dialogs.pri) -include(src/exception/exception.pri) -include(src/geometry/geometry.pri) -include(src/tools/tools.pri) -include(src/widgets/widgets.pri) -include(src/xml/xml.pri) - -RESOURCES += \ - share/resources/icon.qrc \ - share/resources/cursor.qrc \ - share/resources/theme.qrc \ - share/resources/schema.qrc - -OTHER_FILES += share/resources/valentina.rc \ - share/resources/icon/64x64/icon64x64.ico - -TRANSLATIONS += share/translations/valentina.ts \ - share/translations/valentina_ru.ts \ - share/translations/valentina_uk.ts \ - share/translations/valentina_de.ts \ - share/translations/valentina_cs.ts \ - share/translations/valentina_he_IL.ts \ - share/translations/valentina_fr.ts - -unix { -QMAKE_CXX = ccache g++ -} - -CONFIG += precompile_header -# Precompiled headers (PCH) -PRECOMPILED_HEADER = src/stable.h -win32-msvc* { - PRECOMPILED_SOURCE = src/stable.cpp -} - -CONFIG(debug, debug|release){ - # Debug - unix { - *-g++{ - QMAKE_CXXFLAGS += -isystem "/usr/include/qt5" -isystem "/usr/include/qt5/QtWidgets" \ - -isystem "/usr/include/qt5/QtXml" -isystem "/usr/include/qt5/QtGui" \ - -isystem "/usr/include/qt5/QtCore" -isystem "$${UI_DIR}" -isystem "$${MOC_DIR}" \ - -isystem "$${RCC_DIR}" \ - -O0 -Wall -Wextra -pedantic -Weffc++ -Woverloaded-virtual -Wctor-dtor-privacy \ - -Wnon-virtual-dtor -Wold-style-cast -Wconversion -Winit-self -Wstack-protector \ - -Wunreachable-code -Wcast-align -Wcast-qual -Wdisabled-optimization -Wfloat-equal \ - -Wformat=2 -Wimport \ - -Winvalid-pch -Wunsafe-loop-optimizations -Wlong-long -Wmissing-format-attribute \ - -Wmissing-include-dirs -Wpacked -Wredundant-decls -Winline \ - -Wswitch-default -Wswitch-enum -Wuninitialized -Wvariadic-macros \ - -Wlogical-op -Wnoexcept -Wmissing-noreturn -Wpointer-arith\ - -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 - -ftrapv - } - } else { - *-g++{#Don't use additional GCC keys on Windows system. - QMAKE_CXXFLAGS += -O0 -Wall -Wextra -pedantic - } - } -}else{ - # Release - *-g++{ - QMAKE_CXXFLAGS += -O2 - } - - DEFINES += QT_NO_DEBUG_OUTPUT -} - -message(Qt version: $$[QT_VERSION]) -message(Qt is installed in $$[QT_INSTALL_PREFIX]) -message(Qt resources can be found in the following locations:) -message(Documentation: $$[QT_INSTALL_DOCS]) -message(Header files: $$[QT_INSTALL_HEADERS]) -message(Libraries: $$[QT_INSTALL_LIBS]) -message(Binary files (executables): $$[QT_INSTALL_BINS]) -message(Plugins: $$[QT_INSTALL_PLUGINS]) -message(Data files: $$[QT_INSTALL_DATA]) -message(Translation files: $$[QT_INSTALL_TRANSLATIONS]) -message(Settings: $$[QT_INSTALL_SETTINGS]) -message(Examples: $$[QT_INSTALL_EXAMPLES]) - -win32:RC_FILE = share/resources/valentina.rc - -# Remove generated files at cleaning -QMAKE_DISTCLEAN += $${DESTDIR}/* \ - $${OBJECTS_DIR}/* \ - $${UI_DIR}/* \ - $${MOC_DIR}/* \ - $${RCC_DIR}/* \ - $$PWD/share/translations/valentina_*.qm - -INSTALL_TRANSLATIONS += share/translations/valentina_ru.qm \ - share/translations/valentina_uk.qm \ - share/translations/valentina_de.qm \ - share/translations/valentina_cs.qm \ - share/translations/valentina_he_IL.qm \ - share/translations/valentina_fr.qm - -INSTALL_STANDARD_MEASHUREMENTS += share/tables/standard/GOST_man_ru.vst - -INSTALL_INDIVIDUAL_MEASHUREMENTS += share/tables/individual/indivindual_ru.vit - -unix { -#VARIABLES -isEmpty(PREFIX) { - PREFIX = /usr -} -BINDIR = $$PREFIX/bin -DATADIR =$$PREFIX/share -DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" -#MAKE INSTALL -target.path = $$BINDIR -desktop.path = $$DATADIR/applications/ -desktop.files += dist/$${TARGET}.desktop -pixmaps.path = $$DATADIR/pixmaps/ -pixmaps.files += dist/$${TARGET}.png -translations.path = $$DATADIR/$${TARGET}/translations/ -translations.files = $$INSTALL_TRANSLATIONS -standard.path = $$DATADIR/$${TARGET}/tables/standard/ -standard.files = $$INSTALL_STANDARD_MEASHUREMENTS -individual.path = $$DATADIR/$${TARGET}/tables/individual/ -individual.files = $$INSTALL_INDIVIDUAL_MEASHUREMENTS -INSTALLS += target \ - desktop \ - pixmaps \ - translations \ - standard \ - individual -} - -!isEmpty(TRANSLATIONS): { - for(_translation_name, TRANSLATIONS) { - _translation_name_qm = $$section(_translation_name,".", 0, 0).qm - - system($$shell_path($$[QT_INSTALL_BINS]/lrelease) $$shell_path($$PWD/$$_translation_name) -qm $$shell_path($$PWD/$$_translation_name_qm)) - } -} - -# Copies the given files to the destination directory -defineTest(copyToDestdir) { - files = $$1 - DDIR = $$2 - mkpath($$DDIR) - - for(FILE, files) { - - # Replace slashes in paths with backslashes for Windows - win32{ - FILE ~= s,/,\\,g - DDIR ~= s,/,\\,g - } - QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\n\\t) - } - - export(QMAKE_POST_LINK) -} - -for(DIR, INSTALL_TRANSLATIONS) { - #add these absolute paths to a variable which - #ends up as 'mkcommands = path1 path2 path3 ...' - tr_path += $$PWD/$$DIR -} - -copyToDestdir($$tr_path, $$shell_path($$OUT_PWD/$$DESTDIR/translations)) - -for(DIR, INSTALL_STANDARD_MEASHUREMENTS) { - #add these absolute paths to a variable which - #ends up as 'mkcommands = path1 path2 path3 ...' - st_path += $$PWD/$$DIR -} - -copyToDestdir($$st_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/standard)) - -for(DIR, INSTALL_INDIVIDUAL_MEASHUREMENTS) { - #add these absolute paths to a variable which - #ends up as 'mkcommands = path1 path2 path3 ...' - ind_path += $$PWD/$$DIR -} - -copyToDestdir($$ind_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/individual)) +TEMPLATE = subdirs +SUBDIRS = src diff --git a/dist/copyright_template.txt b/dist/copyright_template.txt new file mode 100644 index 000000000..9339f95da --- /dev/null +++ b/dist/copyright_template.txt @@ -0,0 +1,27 @@ +/************************************************************************ + ** + ** @file %FILENAME% + ** @author Roman Telezhinsky + ** @date %DAY% %MONTH%, %YEAR% + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ diff --git a/src/app/app.pri b/src/app/app.pri new file mode 100644 index 000000000..dedc86004 --- /dev/null +++ b/src/app/app.pri @@ -0,0 +1,234 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-06-18T12:36:43 +# +#------------------------------------------------- + +# Use out-of-source builds (shadow builds) + +QT += core gui widgets xml svg printsupport xmlpatterns + +TEMPLATE = app + +TARGET = valentina + +CONFIG -= debug_and_release debug_and_release_target +CONFIG += c++11 + +#DEFINES += ... + +# directory for executable file +DESTDIR = bin + +# files created moc +MOC_DIR = moc + +# objecs files +OBJECTS_DIR = obj + +# files created rcc +RCC_DIR = rcc + +# files created uic +UI_DIR = uic + +include(src/app/container/container.pri) +include(src/app/dialogs/dialogs.pri) +include(src/app/exception/exception.pri) +include(src/app/geometry/geometry.pri) +include(src/app/tools/tools.pri) +include(src/app/widgets/widgets.pri) +include(src/app/xml/xml.pri) + +SOURCES += \ + src/app/main.cpp \ + src/app/mainwindow.cpp \ + src/app/tablewindow.cpp \ + src/app/stable.cpp \ + src/app/version.cpp + +HEADERS += \ + src/app/mainwindow.h \ + src/app/options.h \ + src/app/tablewindow.h \ + src/app/stable.h \ + src/app/version.h + +FORMS += \ + src/app/mainwindow.ui \ + src/app/tablewindow.ui + +RESOURCES += \ + share/resources/icon.qrc \ + share/resources/cursor.qrc \ + share/resources/theme.qrc \ + share/resources/schema.qrc + +OTHER_FILES += share/resources/valentina.rc \ + share/resources/icon/64x64/icon64x64.ico + +TRANSLATIONS += share/translations/valentina.ts \ + share/translations/valentina_ru.ts \ + share/translations/valentina_uk.ts \ + share/translations/valentina_de.ts \ + share/translations/valentina_cs.ts \ + share/translations/valentina_he_IL.ts \ + share/translations/valentina_fr.ts + +unix { +QMAKE_CXX = ccache g++ +} + +CONFIG += precompile_header +# Precompiled headers (PCH) +PRECOMPILED_HEADER = src/stable.h +win32-msvc* { + PRECOMPILED_SOURCE = src/stable.cpp +} + +CONFIG(debug, debug|release){ + # Debug + unix { + *-g++{ + QMAKE_CXXFLAGS += -isystem "/usr/include/qt5" -isystem "/usr/include/qt5/QtWidgets" \ + -isystem "/usr/include/qt5/QtXml" -isystem "/usr/include/qt5/QtGui" \ + -isystem "/usr/include/qt5/QtCore" -isystem "$${UI_DIR}" -isystem "$${MOC_DIR}" \ + -isystem "$${RCC_DIR}" \ + -O0 -Wall -Wextra -pedantic -Weffc++ -Woverloaded-virtual -Wctor-dtor-privacy \ + -Wnon-virtual-dtor -Wold-style-cast -Wconversion -Winit-self -Wstack-protector \ + -Wunreachable-code -Wcast-align -Wcast-qual -Wdisabled-optimization -Wfloat-equal \ + -Wformat=2 -Wimport \ + -Winvalid-pch -Wunsafe-loop-optimizations -Wlong-long -Wmissing-format-attribute \ + -Wmissing-include-dirs -Wpacked -Wredundant-decls -Winline \ + -Wswitch-default -Wswitch-enum -Wuninitialized -Wvariadic-macros \ + -Wlogical-op -Wnoexcept -Wmissing-noreturn -Wpointer-arith\ + -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 + -ftrapv + } + } else { + *-g++{#Don't use additional GCC keys on Windows system. + QMAKE_CXXFLAGS += -O0 -Wall -Wextra -pedantic + } + } +}else{ + # Release + *-g++{ + QMAKE_CXXFLAGS += -O2 + } + + DEFINES += QT_NO_DEBUG_OUTPUT +} + +message(Qt version: $$[QT_VERSION]) +message(Qt is installed in $$[QT_INSTALL_PREFIX]) +message(Qt resources can be found in the following locations:) +message(Documentation: $$[QT_INSTALL_DOCS]) +message(Header files: $$[QT_INSTALL_HEADERS]) +message(Libraries: $$[QT_INSTALL_LIBS]) +message(Binary files (executables): $$[QT_INSTALL_BINS]) +message(Plugins: $$[QT_INSTALL_PLUGINS]) +message(Data files: $$[QT_INSTALL_DATA]) +message(Translation files: $$[QT_INSTALL_TRANSLATIONS]) +message(Settings: $$[QT_INSTALL_SETTINGS]) +message(Examples: $$[QT_INSTALL_EXAMPLES]) + +win32:RC_FILE = share/resources/valentina.rc + +# Remove generated files at cleaning +QMAKE_DISTCLEAN += $${DESTDIR}/* \ + $${OBJECTS_DIR}/* \ + $${UI_DIR}/* \ + $${MOC_DIR}/* \ + $${RCC_DIR}/* \ + $$PWD/share/translations/valentina_*.qm + +INSTALL_TRANSLATIONS += share/translations/valentina_ru.qm \ + share/translations/valentina_uk.qm \ + share/translations/valentina_de.qm \ + share/translations/valentina_cs.qm \ + share/translations/valentina_he_IL.qm \ + share/translations/valentina_fr.qm + +INSTALL_STANDARD_MEASHUREMENTS += share/tables/standard/GOST_man_ru.vst + +INSTALL_INDIVIDUAL_MEASHUREMENTS += share/tables/individual/indivindual_ru.vit + +unix { +#VARIABLES +isEmpty(PREFIX) { + PREFIX = /usr +} +BINDIR = $$PREFIX/bin +DATADIR =$$PREFIX/share +DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" +#MAKE INSTALL +target.path = $$BINDIR +desktop.path = $$DATADIR/applications/ +desktop.files += dist/$${TARGET}.desktop +pixmaps.path = $$DATADIR/pixmaps/ +pixmaps.files += dist/$${TARGET}.png +translations.path = $$DATADIR/$${TARGET}/translations/ +translations.files = $$INSTALL_TRANSLATIONS +standard.path = $$DATADIR/$${TARGET}/tables/standard/ +standard.files = $$INSTALL_STANDARD_MEASHUREMENTS +individual.path = $$DATADIR/$${TARGET}/tables/individual/ +individual.files = $$INSTALL_INDIVIDUAL_MEASHUREMENTS +INSTALLS += target \ + desktop \ + pixmaps \ + translations \ + standard \ + individual +} + +!isEmpty(TRANSLATIONS): { + for(_translation_name, TRANSLATIONS) { + _translation_name_qm = $$section(_translation_name,".", 0, 0).qm + + system($$shell_path($$[QT_INSTALL_BINS]/lrelease) $$shell_path($$PWD/$$_translation_name) -qm $$shell_path($$PWD/$$_translation_name_qm)) + } +} + +# Copies the given files to the destination directory +defineTest(copyToDestdir) { + files = $$1 + DDIR = $$2 + mkpath($$DDIR) + + for(FILE, files) { + + # Replace slashes in paths with backslashes for Windows + win32{ + FILE ~= s,/,\\,g + DDIR ~= s,/,\\,g + } + QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\n\\t) + } + + export(QMAKE_POST_LINK) +} + +for(DIR, INSTALL_TRANSLATIONS) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + tr_path += $$PWD/$$DIR +} + +copyToDestdir($$tr_path, $$shell_path($$OUT_PWD/$$DESTDIR/translations)) + +for(DIR, INSTALL_STANDARD_MEASHUREMENTS) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + st_path += $$PWD/$$DIR +} + +copyToDestdir($$st_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/standard)) + +for(DIR, INSTALL_INDIVIDUAL_MEASHUREMENTS) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + ind_path += $$PWD/$$DIR +} + +copyToDestdir($$ind_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/individual)) + diff --git a/src/app/app.pro b/src/app/app.pro new file mode 100644 index 000000000..f691e6641 --- /dev/null +++ b/src/app/app.pro @@ -0,0 +1,234 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-06-18T12:36:43 +# +#------------------------------------------------- + +# Use out-of-source builds (shadow builds) + +QT += core gui widgets xml svg printsupport xmlpatterns + +TEMPLATE = app + +TARGET = valentina + +CONFIG -= debug_and_release debug_and_release_target +CONFIG += c++11 + +#DEFINES += ... + +# directory for executable file +DESTDIR = bin + +# files created moc +MOC_DIR = moc + +# objecs files +OBJECTS_DIR = obj + +# files created rcc +RCC_DIR = rcc + +# files created uic +UI_DIR = uic + +include(container/container.pri) +include(dialogs/dialogs.pri) +include(exception/exception.pri) +include(geometry/geometry.pri) +include(tools/tools.pri) +include(widgets/widgets.pri) +include(xml/xml.pri) + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + tablewindow.cpp \ + stable.cpp \ + version.cpp + +HEADERS += \ + mainwindow.h \ + options.h \ + tablewindow.h \ + stable.h \ + version.h + +FORMS += \ + mainwindow.ui \ + tablewindow.ui + +RESOURCES += \ + share/resources/icon.qrc \ + share/resources/cursor.qrc \ + share/resources/theme.qrc \ + share/resources/schema.qrc + +OTHER_FILES += share/resources/valentina.rc \ + share/resources/icon/64x64/icon64x64.ico + +TRANSLATIONS += share/translations/valentina.ts \ + share/translations/valentina_ru.ts \ + share/translations/valentina_uk.ts \ + share/translations/valentina_de.ts \ + share/translations/valentina_cs.ts \ + share/translations/valentina_he_IL.ts \ + share/translations/valentina_fr.ts + +unix { +QMAKE_CXX = ccache g++ +} + +CONFIG += precompile_header +# Precompiled headers (PCH) +PRECOMPILED_HEADER = stable.h +win32-msvc* { + PRECOMPILED_SOURCE = stable.cpp +} + +CONFIG(debug, debug|release){ + # Debug + unix { + *-g++{ + QMAKE_CXXFLAGS += -isystem "/usr/include/qt5" -isystem "/usr/include/qt5/QtWidgets" \ + -isystem "/usr/include/qt5/QtXml" -isystem "/usr/include/qt5/QtGui" \ + -isystem "/usr/include/qt5/QtCore" -isystem "$${UI_DIR}" -isystem "$${MOC_DIR}" \ + -isystem "$${RCC_DIR}" \ + -O0 -Wall -Wextra -pedantic -Weffc++ -Woverloaded-virtual -Wctor-dtor-privacy \ + -Wnon-virtual-dtor -Wold-style-cast -Wconversion -Winit-self -Wstack-protector \ + -Wunreachable-code -Wcast-align -Wcast-qual -Wdisabled-optimization -Wfloat-equal \ + -Wformat=2 -Wimport \ + -Winvalid-pch -Wunsafe-loop-optimizations -Wlong-long -Wmissing-format-attribute \ + -Wmissing-include-dirs -Wpacked -Wredundant-decls -Winline \ + -Wswitch-default -Wswitch-enum -Wuninitialized -Wvariadic-macros \ + -Wlogical-op -Wnoexcept -Wmissing-noreturn -Wpointer-arith\ + -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 + -ftrapv + } + } else { + *-g++{#Don't use additional GCC keys on Windows system. + QMAKE_CXXFLAGS += -O0 -Wall -Wextra -pedantic + } + } +}else{ + # Release + *-g++{ + QMAKE_CXXFLAGS += -O2 + } + + DEFINES += QT_NO_DEBUG_OUTPUT +} + +message(Qt version: $$[QT_VERSION]) +message(Qt is installed in $$[QT_INSTALL_PREFIX]) +message(Qt resources can be found in the following locations:) +message(Documentation: $$[QT_INSTALL_DOCS]) +message(Header files: $$[QT_INSTALL_HEADERS]) +message(Libraries: $$[QT_INSTALL_LIBS]) +message(Binary files (executables): $$[QT_INSTALL_BINS]) +message(Plugins: $$[QT_INSTALL_PLUGINS]) +message(Data files: $$[QT_INSTALL_DATA]) +message(Translation files: $$[QT_INSTALL_TRANSLATIONS]) +message(Settings: $$[QT_INSTALL_SETTINGS]) +message(Examples: $$[QT_INSTALL_EXAMPLES]) + +win32:RC_FILE = share/resources/valentina.rc + +# Remove generated files at cleaning +QMAKE_DISTCLEAN += $${DESTDIR}/* \ + $${OBJECTS_DIR}/* \ + $${UI_DIR}/* \ + $${MOC_DIR}/* \ + $${RCC_DIR}/* \ + $$PWD/share/translations/valentina_*.qm + +INSTALL_TRANSLATIONS += share/translations/valentina_ru.qm \ + share/translations/valentina_uk.qm \ + share/translations/valentina_de.qm \ + share/translations/valentina_cs.qm \ + share/translations/valentina_he_IL.qm \ + share/translations/valentina_fr.qm + +INSTALL_STANDARD_MEASHUREMENTS += share/tables/standard/GOST_man_ru.vst + +INSTALL_INDIVIDUAL_MEASHUREMENTS += share/tables/individual/indivindual_ru.vit + +unix { +#VARIABLES +isEmpty(PREFIX) { + PREFIX = /usr +} +BINDIR = $$PREFIX/bin +DATADIR =$$PREFIX/share +DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" +#MAKE INSTALL +target.path = $$BINDIR +desktop.path = $$DATADIR/applications/ +desktop.files += dist/$${TARGET}.desktop +pixmaps.path = $$DATADIR/pixmaps/ +pixmaps.files += dist/$${TARGET}.png +translations.path = $$DATADIR/$${TARGET}/translations/ +translations.files = $$INSTALL_TRANSLATIONS +standard.path = $$DATADIR/$${TARGET}/tables/standard/ +standard.files = $$INSTALL_STANDARD_MEASHUREMENTS +individual.path = $$DATADIR/$${TARGET}/tables/individual/ +individual.files = $$INSTALL_INDIVIDUAL_MEASHUREMENTS +INSTALLS += target \ + desktop \ + pixmaps \ + translations \ + standard \ + individual +} + +!isEmpty(TRANSLATIONS): { + for(_translation_name, TRANSLATIONS) { + _translation_name_qm = $$section(_translation_name,".", 0, 0).qm + + system($$shell_path($$[QT_INSTALL_BINS]/lrelease) $$shell_path($$PWD/$$_translation_name) -qm $$shell_path($$PWD/$$_translation_name_qm)) + } +} + +# Copies the given files to the destination directory +defineTest(copyToDestdir) { + files = $$1 + DDIR = $$2 + mkpath($$DDIR) + + for(FILE, files) { + + # Replace slashes in paths with backslashes for Windows + win32{ + FILE ~= s,/,\\,g + DDIR ~= s,/,\\,g + } + QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\n\\t) + } + + export(QMAKE_POST_LINK) +} + +for(DIR, INSTALL_TRANSLATIONS) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + tr_path += $$PWD/$$DIR +} + +copyToDestdir($$tr_path, $$shell_path($$OUT_PWD/$$DESTDIR/translations)) + +for(DIR, INSTALL_STANDARD_MEASHUREMENTS) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + st_path += $$PWD/$$DIR +} + +copyToDestdir($$st_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/standard)) + +for(DIR, INSTALL_INDIVIDUAL_MEASHUREMENTS) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + ind_path += $$PWD/$$DIR +} + +copyToDestdir($$ind_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/individual)) + diff --git a/src/container/calculator.cpp b/src/app/container/calculator.cpp similarity index 100% rename from src/container/calculator.cpp rename to src/app/container/calculator.cpp diff --git a/src/container/calculator.h b/src/app/container/calculator.h similarity index 100% rename from src/container/calculator.h rename to src/app/container/calculator.h diff --git a/src/app/container/container.pri b/src/app/container/container.pri new file mode 100644 index 000000000..ffbefb2cf --- /dev/null +++ b/src/app/container/container.pri @@ -0,0 +1,11 @@ +SOURCES += \ + container/vcontainer.cpp \ + container/calculator.cpp \ + container/vmeasurement.cpp \ + container/vincrement.cpp + +HEADERS += \ + container/vcontainer.h \ + container/calculator.h \ + container/vmeasurement.h \ + container/vincrement.h diff --git a/src/container/vcontainer.cpp b/src/app/container/vcontainer.cpp similarity index 100% rename from src/container/vcontainer.cpp rename to src/app/container/vcontainer.cpp diff --git a/src/container/vcontainer.h b/src/app/container/vcontainer.h similarity index 100% rename from src/container/vcontainer.h rename to src/app/container/vcontainer.h diff --git a/src/container/vincrement.cpp b/src/app/container/vincrement.cpp similarity index 100% rename from src/container/vincrement.cpp rename to src/app/container/vincrement.cpp diff --git a/src/container/vincrement.h b/src/app/container/vincrement.h similarity index 100% rename from src/container/vincrement.h rename to src/app/container/vincrement.h diff --git a/src/container/vmeasurement.cpp b/src/app/container/vmeasurement.cpp similarity index 100% rename from src/container/vmeasurement.cpp rename to src/app/container/vmeasurement.cpp diff --git a/src/container/vmeasurement.h b/src/app/container/vmeasurement.h similarity index 100% rename from src/container/vmeasurement.h rename to src/app/container/vmeasurement.h diff --git a/src/dialogs/app/configdialog.cpp b/src/app/dialogs/app/configdialog.cpp similarity index 100% rename from src/dialogs/app/configdialog.cpp rename to src/app/dialogs/app/configdialog.cpp diff --git a/src/dialogs/app/configdialog.h b/src/app/dialogs/app/configdialog.h similarity index 100% rename from src/dialogs/app/configdialog.h rename to src/app/dialogs/app/configdialog.h diff --git a/src/dialogs/app/dialoghistory.cpp b/src/app/dialogs/app/dialoghistory.cpp similarity index 100% rename from src/dialogs/app/dialoghistory.cpp rename to src/app/dialogs/app/dialoghistory.cpp diff --git a/src/dialogs/app/dialoghistory.h b/src/app/dialogs/app/dialoghistory.h similarity index 100% rename from src/dialogs/app/dialoghistory.h rename to src/app/dialogs/app/dialoghistory.h diff --git a/src/dialogs/app/dialoghistory.ui b/src/app/dialogs/app/dialoghistory.ui similarity index 100% rename from src/dialogs/app/dialoghistory.ui rename to src/app/dialogs/app/dialoghistory.ui diff --git a/src/dialogs/app/dialogincrements.cpp b/src/app/dialogs/app/dialogincrements.cpp similarity index 100% rename from src/dialogs/app/dialogincrements.cpp rename to src/app/dialogs/app/dialogincrements.cpp diff --git a/src/dialogs/app/dialogincrements.h b/src/app/dialogs/app/dialogincrements.h similarity index 100% rename from src/dialogs/app/dialogincrements.h rename to src/app/dialogs/app/dialogincrements.h diff --git a/src/dialogs/app/dialogincrements.ui b/src/app/dialogs/app/dialogincrements.ui similarity index 100% rename from src/dialogs/app/dialogincrements.ui rename to src/app/dialogs/app/dialogincrements.ui diff --git a/src/dialogs/app/dialogindividualmeasurements.cpp b/src/app/dialogs/app/dialogindividualmeasurements.cpp similarity index 100% rename from src/dialogs/app/dialogindividualmeasurements.cpp rename to src/app/dialogs/app/dialogindividualmeasurements.cpp diff --git a/src/dialogs/app/dialogindividualmeasurements.h b/src/app/dialogs/app/dialogindividualmeasurements.h similarity index 100% rename from src/dialogs/app/dialogindividualmeasurements.h rename to src/app/dialogs/app/dialogindividualmeasurements.h diff --git a/src/dialogs/app/dialogindividualmeasurements.ui b/src/app/dialogs/app/dialogindividualmeasurements.ui similarity index 100% rename from src/dialogs/app/dialogindividualmeasurements.ui rename to src/app/dialogs/app/dialogindividualmeasurements.ui diff --git a/src/dialogs/app/dialogmeasurements.cpp b/src/app/dialogs/app/dialogmeasurements.cpp similarity index 100% rename from src/dialogs/app/dialogmeasurements.cpp rename to src/app/dialogs/app/dialogmeasurements.cpp diff --git a/src/dialogs/app/dialogmeasurements.h b/src/app/dialogs/app/dialogmeasurements.h similarity index 100% rename from src/dialogs/app/dialogmeasurements.h rename to src/app/dialogs/app/dialogmeasurements.h diff --git a/src/dialogs/app/dialogmeasurements.ui b/src/app/dialogs/app/dialogmeasurements.ui similarity index 100% rename from src/dialogs/app/dialogmeasurements.ui rename to src/app/dialogs/app/dialogmeasurements.ui diff --git a/src/dialogs/app/dialogpatternproperties.cpp b/src/app/dialogs/app/dialogpatternproperties.cpp similarity index 100% rename from src/dialogs/app/dialogpatternproperties.cpp rename to src/app/dialogs/app/dialogpatternproperties.cpp diff --git a/src/dialogs/app/dialogpatternproperties.h b/src/app/dialogs/app/dialogpatternproperties.h similarity index 100% rename from src/dialogs/app/dialogpatternproperties.h rename to src/app/dialogs/app/dialogpatternproperties.h diff --git a/src/dialogs/app/dialogpatternproperties.ui b/src/app/dialogs/app/dialogpatternproperties.ui similarity index 100% rename from src/dialogs/app/dialogpatternproperties.ui rename to src/app/dialogs/app/dialogpatternproperties.ui diff --git a/src/dialogs/app/dialogstandardmeasurements.cpp b/src/app/dialogs/app/dialogstandardmeasurements.cpp similarity index 100% rename from src/dialogs/app/dialogstandardmeasurements.cpp rename to src/app/dialogs/app/dialogstandardmeasurements.cpp diff --git a/src/dialogs/app/dialogstandardmeasurements.h b/src/app/dialogs/app/dialogstandardmeasurements.h similarity index 100% rename from src/dialogs/app/dialogstandardmeasurements.h rename to src/app/dialogs/app/dialogstandardmeasurements.h diff --git a/src/dialogs/app/dialogstandardmeasurements.ui b/src/app/dialogs/app/dialogstandardmeasurements.ui similarity index 100% rename from src/dialogs/app/dialogstandardmeasurements.ui rename to src/app/dialogs/app/dialogstandardmeasurements.ui diff --git a/src/dialogs/app/pages.cpp b/src/app/dialogs/app/pages.cpp similarity index 100% rename from src/dialogs/app/pages.cpp rename to src/app/dialogs/app/pages.cpp diff --git a/src/dialogs/app/pages.h b/src/app/dialogs/app/pages.h similarity index 100% rename from src/dialogs/app/pages.h rename to src/app/dialogs/app/pages.h diff --git a/src/dialogs/dialogs.h b/src/app/dialogs/dialogs.h similarity index 100% rename from src/dialogs/dialogs.h rename to src/app/dialogs/dialogs.h diff --git a/src/app/dialogs/dialogs.pri b/src/app/dialogs/dialogs.pri new file mode 100644 index 000000000..7cb2470bf --- /dev/null +++ b/src/app/dialogs/dialogs.pri @@ -0,0 +1,90 @@ +HEADERS += \ + dialogs/dialogs.h \ + dialogs/tools/dialogtriangle.h \ + dialogs/tools/dialogtool.h \ + dialogs/tools/dialogsplinepath.h \ + dialogs/tools/dialogspline.h \ + dialogs/tools/dialogsinglepoint.h \ + dialogs/tools/dialogshoulderpoint.h \ + dialogs/tools/dialogpointofintersection.h \ + dialogs/tools/dialogpointofcontact.h \ + dialogs/tools/dialognormal.h \ + dialogs/tools/dialoglineintersect.h \ + dialogs/tools/dialogline.h \ + dialogs/tools/dialogheight.h \ + dialogs/tools/dialogendline.h \ + dialogs/tools/dialogdetail.h \ + dialogs/tools/dialogbisector.h \ + dialogs/tools/dialogarc.h \ + dialogs/tools/dialogalongline.h \ + dialogs/tools/dialogcutspline.h \ + dialogs/tools/dialogcutsplinepath.h \ + dialogs/tools/dialoguniondetails.h \ + dialogs/tools/dialogcutarc.h \ + dialogs/app/dialogincrements.h \ + dialogs/app/dialoghistory.h \ + dialogs/app/configdialog.h \ + dialogs/app/pages.h \ + dialogs/app/dialogpatternproperties.h \ + dialogs/app/dialogmeasurements.h \ + dialogs/app/dialogstandardmeasurements.h \ + dialogs/app/dialogindividualmeasurements.h + +SOURCES += \ + dialogs/tools/dialogtriangle.cpp \ + dialogs/tools/dialogtool.cpp \ + dialogs/tools/dialogsplinepath.cpp \ + dialogs/tools/dialogspline.cpp \ + dialogs/tools/dialogsinglepoint.cpp \ + dialogs/tools/dialogshoulderpoint.cpp \ + dialogs/tools/dialogpointofintersection.cpp \ + dialogs/tools/dialogpointofcontact.cpp \ + dialogs/tools/dialognormal.cpp \ + dialogs/tools/dialoglineintersect.cpp \ + dialogs/tools/dialogline.cpp \ + dialogs/tools/dialogheight.cpp \ + dialogs/tools/dialogendline.cpp \ + dialogs/tools/dialogdetail.cpp \ + dialogs/tools/dialogbisector.cpp \ + dialogs/tools/dialogarc.cpp \ + dialogs/tools/dialogalongline.cpp \ + dialogs/tools/dialogcutspline.cpp \ + dialogs/tools/dialogcutsplinepath.cpp \ + dialogs/tools/dialoguniondetails.cpp \ + dialogs/tools/dialogcutarc.cpp \ + dialogs/app/dialogincrements.cpp \ + dialogs/app/dialoghistory.cpp \ + dialogs/app/configdialog.cpp \ + dialogs/app/pages.cpp \ + dialogs/app/dialogpatternproperties.cpp \ + dialogs/app/dialogmeasurements.cpp \ + dialogs/app/dialogstandardmeasurements.cpp \ + dialogs/app/dialogindividualmeasurements.cpp + +FORMS += \ + dialogs/tools/dialogtriangle.ui \ + dialogs/tools/dialogsplinepath.ui \ + dialogs/tools/dialogspline.ui \ + dialogs/tools/dialogsinglepoint.ui \ + dialogs/tools/dialogshoulderpoint.ui \ + dialogs/tools/dialogpointofintersection.ui \ + dialogs/tools/dialogpointofcontact.ui \ + dialogs/tools/dialognormal.ui \ + dialogs/tools/dialoglineintersect.ui \ + dialogs/tools/dialogline.ui \ + dialogs/tools/dialogheight.ui \ + dialogs/tools/dialogendline.ui \ + dialogs/tools/dialogdetail.ui \ + dialogs/tools/dialogbisector.ui \ + dialogs/tools/dialogarc.ui \ + dialogs/tools/dialogalongline.ui \ + dialogs/tools/dialogcutspline.ui \ + dialogs/tools/dialogcutsplinepath.ui \ + dialogs/tools/dialoguniondetails.ui \ + dialogs/tools/dialogcutarc.ui \ + dialogs/app/dialogincrements.ui \ + dialogs/app/dialoghistory.ui \ + dialogs/app/dialogpatternproperties.ui \ + dialogs/app/dialogmeasurements.ui \ + dialogs/app/dialogstandardmeasurements.ui \ + dialogs/app/dialogindividualmeasurements.ui diff --git a/src/dialogs/tools/dialogalongline.cpp b/src/app/dialogs/tools/dialogalongline.cpp similarity index 100% rename from src/dialogs/tools/dialogalongline.cpp rename to src/app/dialogs/tools/dialogalongline.cpp diff --git a/src/dialogs/tools/dialogalongline.h b/src/app/dialogs/tools/dialogalongline.h similarity index 100% rename from src/dialogs/tools/dialogalongline.h rename to src/app/dialogs/tools/dialogalongline.h diff --git a/src/dialogs/tools/dialogalongline.ui b/src/app/dialogs/tools/dialogalongline.ui similarity index 100% rename from src/dialogs/tools/dialogalongline.ui rename to src/app/dialogs/tools/dialogalongline.ui diff --git a/src/dialogs/tools/dialogarc.cpp b/src/app/dialogs/tools/dialogarc.cpp similarity index 100% rename from src/dialogs/tools/dialogarc.cpp rename to src/app/dialogs/tools/dialogarc.cpp diff --git a/src/dialogs/tools/dialogarc.h b/src/app/dialogs/tools/dialogarc.h similarity index 100% rename from src/dialogs/tools/dialogarc.h rename to src/app/dialogs/tools/dialogarc.h diff --git a/src/dialogs/tools/dialogarc.ui b/src/app/dialogs/tools/dialogarc.ui similarity index 100% rename from src/dialogs/tools/dialogarc.ui rename to src/app/dialogs/tools/dialogarc.ui diff --git a/src/dialogs/tools/dialogbisector.cpp b/src/app/dialogs/tools/dialogbisector.cpp similarity index 100% rename from src/dialogs/tools/dialogbisector.cpp rename to src/app/dialogs/tools/dialogbisector.cpp diff --git a/src/dialogs/tools/dialogbisector.h b/src/app/dialogs/tools/dialogbisector.h similarity index 100% rename from src/dialogs/tools/dialogbisector.h rename to src/app/dialogs/tools/dialogbisector.h diff --git a/src/dialogs/tools/dialogbisector.ui b/src/app/dialogs/tools/dialogbisector.ui similarity index 100% rename from src/dialogs/tools/dialogbisector.ui rename to src/app/dialogs/tools/dialogbisector.ui diff --git a/src/dialogs/tools/dialogcutarc.cpp b/src/app/dialogs/tools/dialogcutarc.cpp similarity index 100% rename from src/dialogs/tools/dialogcutarc.cpp rename to src/app/dialogs/tools/dialogcutarc.cpp diff --git a/src/dialogs/tools/dialogcutarc.h b/src/app/dialogs/tools/dialogcutarc.h similarity index 100% rename from src/dialogs/tools/dialogcutarc.h rename to src/app/dialogs/tools/dialogcutarc.h diff --git a/src/dialogs/tools/dialogcutarc.ui b/src/app/dialogs/tools/dialogcutarc.ui similarity index 100% rename from src/dialogs/tools/dialogcutarc.ui rename to src/app/dialogs/tools/dialogcutarc.ui diff --git a/src/dialogs/tools/dialogcutspline.cpp b/src/app/dialogs/tools/dialogcutspline.cpp similarity index 100% rename from src/dialogs/tools/dialogcutspline.cpp rename to src/app/dialogs/tools/dialogcutspline.cpp diff --git a/src/dialogs/tools/dialogcutspline.h b/src/app/dialogs/tools/dialogcutspline.h similarity index 100% rename from src/dialogs/tools/dialogcutspline.h rename to src/app/dialogs/tools/dialogcutspline.h diff --git a/src/dialogs/tools/dialogcutspline.ui b/src/app/dialogs/tools/dialogcutspline.ui similarity index 100% rename from src/dialogs/tools/dialogcutspline.ui rename to src/app/dialogs/tools/dialogcutspline.ui diff --git a/src/dialogs/tools/dialogcutsplinepath.cpp b/src/app/dialogs/tools/dialogcutsplinepath.cpp similarity index 100% rename from src/dialogs/tools/dialogcutsplinepath.cpp rename to src/app/dialogs/tools/dialogcutsplinepath.cpp diff --git a/src/dialogs/tools/dialogcutsplinepath.h b/src/app/dialogs/tools/dialogcutsplinepath.h similarity index 100% rename from src/dialogs/tools/dialogcutsplinepath.h rename to src/app/dialogs/tools/dialogcutsplinepath.h diff --git a/src/dialogs/tools/dialogcutsplinepath.ui b/src/app/dialogs/tools/dialogcutsplinepath.ui similarity index 100% rename from src/dialogs/tools/dialogcutsplinepath.ui rename to src/app/dialogs/tools/dialogcutsplinepath.ui diff --git a/src/dialogs/tools/dialogdetail.cpp b/src/app/dialogs/tools/dialogdetail.cpp similarity index 100% rename from src/dialogs/tools/dialogdetail.cpp rename to src/app/dialogs/tools/dialogdetail.cpp diff --git a/src/dialogs/tools/dialogdetail.h b/src/app/dialogs/tools/dialogdetail.h similarity index 100% rename from src/dialogs/tools/dialogdetail.h rename to src/app/dialogs/tools/dialogdetail.h diff --git a/src/dialogs/tools/dialogdetail.ui b/src/app/dialogs/tools/dialogdetail.ui similarity index 100% rename from src/dialogs/tools/dialogdetail.ui rename to src/app/dialogs/tools/dialogdetail.ui diff --git a/src/dialogs/tools/dialogendline.cpp b/src/app/dialogs/tools/dialogendline.cpp similarity index 100% rename from src/dialogs/tools/dialogendline.cpp rename to src/app/dialogs/tools/dialogendline.cpp diff --git a/src/dialogs/tools/dialogendline.h b/src/app/dialogs/tools/dialogendline.h similarity index 100% rename from src/dialogs/tools/dialogendline.h rename to src/app/dialogs/tools/dialogendline.h diff --git a/src/dialogs/tools/dialogendline.ui b/src/app/dialogs/tools/dialogendline.ui similarity index 100% rename from src/dialogs/tools/dialogendline.ui rename to src/app/dialogs/tools/dialogendline.ui diff --git a/src/dialogs/tools/dialogheight.cpp b/src/app/dialogs/tools/dialogheight.cpp similarity index 100% rename from src/dialogs/tools/dialogheight.cpp rename to src/app/dialogs/tools/dialogheight.cpp diff --git a/src/dialogs/tools/dialogheight.h b/src/app/dialogs/tools/dialogheight.h similarity index 100% rename from src/dialogs/tools/dialogheight.h rename to src/app/dialogs/tools/dialogheight.h diff --git a/src/dialogs/tools/dialogheight.ui b/src/app/dialogs/tools/dialogheight.ui similarity index 100% rename from src/dialogs/tools/dialogheight.ui rename to src/app/dialogs/tools/dialogheight.ui diff --git a/src/dialogs/tools/dialogline.cpp b/src/app/dialogs/tools/dialogline.cpp similarity index 100% rename from src/dialogs/tools/dialogline.cpp rename to src/app/dialogs/tools/dialogline.cpp diff --git a/src/dialogs/tools/dialogline.h b/src/app/dialogs/tools/dialogline.h similarity index 100% rename from src/dialogs/tools/dialogline.h rename to src/app/dialogs/tools/dialogline.h diff --git a/src/dialogs/tools/dialogline.ui b/src/app/dialogs/tools/dialogline.ui similarity index 100% rename from src/dialogs/tools/dialogline.ui rename to src/app/dialogs/tools/dialogline.ui diff --git a/src/dialogs/tools/dialoglineintersect.cpp b/src/app/dialogs/tools/dialoglineintersect.cpp similarity index 100% rename from src/dialogs/tools/dialoglineintersect.cpp rename to src/app/dialogs/tools/dialoglineintersect.cpp diff --git a/src/dialogs/tools/dialoglineintersect.h b/src/app/dialogs/tools/dialoglineintersect.h similarity index 100% rename from src/dialogs/tools/dialoglineintersect.h rename to src/app/dialogs/tools/dialoglineintersect.h diff --git a/src/dialogs/tools/dialoglineintersect.ui b/src/app/dialogs/tools/dialoglineintersect.ui similarity index 100% rename from src/dialogs/tools/dialoglineintersect.ui rename to src/app/dialogs/tools/dialoglineintersect.ui diff --git a/src/dialogs/tools/dialognormal.cpp b/src/app/dialogs/tools/dialognormal.cpp similarity index 100% rename from src/dialogs/tools/dialognormal.cpp rename to src/app/dialogs/tools/dialognormal.cpp diff --git a/src/dialogs/tools/dialognormal.h b/src/app/dialogs/tools/dialognormal.h similarity index 100% rename from src/dialogs/tools/dialognormal.h rename to src/app/dialogs/tools/dialognormal.h diff --git a/src/dialogs/tools/dialognormal.ui b/src/app/dialogs/tools/dialognormal.ui similarity index 100% rename from src/dialogs/tools/dialognormal.ui rename to src/app/dialogs/tools/dialognormal.ui diff --git a/src/dialogs/tools/dialogpointofcontact.cpp b/src/app/dialogs/tools/dialogpointofcontact.cpp similarity index 100% rename from src/dialogs/tools/dialogpointofcontact.cpp rename to src/app/dialogs/tools/dialogpointofcontact.cpp diff --git a/src/dialogs/tools/dialogpointofcontact.h b/src/app/dialogs/tools/dialogpointofcontact.h similarity index 100% rename from src/dialogs/tools/dialogpointofcontact.h rename to src/app/dialogs/tools/dialogpointofcontact.h diff --git a/src/dialogs/tools/dialogpointofcontact.ui b/src/app/dialogs/tools/dialogpointofcontact.ui similarity index 100% rename from src/dialogs/tools/dialogpointofcontact.ui rename to src/app/dialogs/tools/dialogpointofcontact.ui diff --git a/src/dialogs/tools/dialogpointofintersection.cpp b/src/app/dialogs/tools/dialogpointofintersection.cpp similarity index 100% rename from src/dialogs/tools/dialogpointofintersection.cpp rename to src/app/dialogs/tools/dialogpointofintersection.cpp diff --git a/src/dialogs/tools/dialogpointofintersection.h b/src/app/dialogs/tools/dialogpointofintersection.h similarity index 100% rename from src/dialogs/tools/dialogpointofintersection.h rename to src/app/dialogs/tools/dialogpointofintersection.h diff --git a/src/dialogs/tools/dialogpointofintersection.ui b/src/app/dialogs/tools/dialogpointofintersection.ui similarity index 100% rename from src/dialogs/tools/dialogpointofintersection.ui rename to src/app/dialogs/tools/dialogpointofintersection.ui diff --git a/src/dialogs/tools/dialogshoulderpoint.cpp b/src/app/dialogs/tools/dialogshoulderpoint.cpp similarity index 100% rename from src/dialogs/tools/dialogshoulderpoint.cpp rename to src/app/dialogs/tools/dialogshoulderpoint.cpp diff --git a/src/dialogs/tools/dialogshoulderpoint.h b/src/app/dialogs/tools/dialogshoulderpoint.h similarity index 100% rename from src/dialogs/tools/dialogshoulderpoint.h rename to src/app/dialogs/tools/dialogshoulderpoint.h diff --git a/src/dialogs/tools/dialogshoulderpoint.ui b/src/app/dialogs/tools/dialogshoulderpoint.ui similarity index 100% rename from src/dialogs/tools/dialogshoulderpoint.ui rename to src/app/dialogs/tools/dialogshoulderpoint.ui diff --git a/src/dialogs/tools/dialogsinglepoint.cpp b/src/app/dialogs/tools/dialogsinglepoint.cpp similarity index 100% rename from src/dialogs/tools/dialogsinglepoint.cpp rename to src/app/dialogs/tools/dialogsinglepoint.cpp diff --git a/src/dialogs/tools/dialogsinglepoint.h b/src/app/dialogs/tools/dialogsinglepoint.h similarity index 100% rename from src/dialogs/tools/dialogsinglepoint.h rename to src/app/dialogs/tools/dialogsinglepoint.h diff --git a/src/dialogs/tools/dialogsinglepoint.ui b/src/app/dialogs/tools/dialogsinglepoint.ui similarity index 100% rename from src/dialogs/tools/dialogsinglepoint.ui rename to src/app/dialogs/tools/dialogsinglepoint.ui diff --git a/src/dialogs/tools/dialogspline.cpp b/src/app/dialogs/tools/dialogspline.cpp similarity index 100% rename from src/dialogs/tools/dialogspline.cpp rename to src/app/dialogs/tools/dialogspline.cpp diff --git a/src/dialogs/tools/dialogspline.h b/src/app/dialogs/tools/dialogspline.h similarity index 100% rename from src/dialogs/tools/dialogspline.h rename to src/app/dialogs/tools/dialogspline.h diff --git a/src/dialogs/tools/dialogspline.ui b/src/app/dialogs/tools/dialogspline.ui similarity index 100% rename from src/dialogs/tools/dialogspline.ui rename to src/app/dialogs/tools/dialogspline.ui diff --git a/src/dialogs/tools/dialogsplinepath.cpp b/src/app/dialogs/tools/dialogsplinepath.cpp similarity index 100% rename from src/dialogs/tools/dialogsplinepath.cpp rename to src/app/dialogs/tools/dialogsplinepath.cpp diff --git a/src/dialogs/tools/dialogsplinepath.h b/src/app/dialogs/tools/dialogsplinepath.h similarity index 100% rename from src/dialogs/tools/dialogsplinepath.h rename to src/app/dialogs/tools/dialogsplinepath.h diff --git a/src/dialogs/tools/dialogsplinepath.ui b/src/app/dialogs/tools/dialogsplinepath.ui similarity index 100% rename from src/dialogs/tools/dialogsplinepath.ui rename to src/app/dialogs/tools/dialogsplinepath.ui diff --git a/src/dialogs/tools/dialogtool.cpp b/src/app/dialogs/tools/dialogtool.cpp similarity index 100% rename from src/dialogs/tools/dialogtool.cpp rename to src/app/dialogs/tools/dialogtool.cpp diff --git a/src/dialogs/tools/dialogtool.h b/src/app/dialogs/tools/dialogtool.h similarity index 100% rename from src/dialogs/tools/dialogtool.h rename to src/app/dialogs/tools/dialogtool.h diff --git a/src/dialogs/tools/dialogtriangle.cpp b/src/app/dialogs/tools/dialogtriangle.cpp similarity index 100% rename from src/dialogs/tools/dialogtriangle.cpp rename to src/app/dialogs/tools/dialogtriangle.cpp diff --git a/src/dialogs/tools/dialogtriangle.h b/src/app/dialogs/tools/dialogtriangle.h similarity index 100% rename from src/dialogs/tools/dialogtriangle.h rename to src/app/dialogs/tools/dialogtriangle.h diff --git a/src/dialogs/tools/dialogtriangle.ui b/src/app/dialogs/tools/dialogtriangle.ui similarity index 100% rename from src/dialogs/tools/dialogtriangle.ui rename to src/app/dialogs/tools/dialogtriangle.ui diff --git a/src/dialogs/tools/dialoguniondetails.cpp b/src/app/dialogs/tools/dialoguniondetails.cpp similarity index 100% rename from src/dialogs/tools/dialoguniondetails.cpp rename to src/app/dialogs/tools/dialoguniondetails.cpp diff --git a/src/dialogs/tools/dialoguniondetails.h b/src/app/dialogs/tools/dialoguniondetails.h similarity index 100% rename from src/dialogs/tools/dialoguniondetails.h rename to src/app/dialogs/tools/dialoguniondetails.h diff --git a/src/dialogs/tools/dialoguniondetails.ui b/src/app/dialogs/tools/dialoguniondetails.ui similarity index 100% rename from src/dialogs/tools/dialoguniondetails.ui rename to src/app/dialogs/tools/dialoguniondetails.ui diff --git a/src/app/exception/exception.pri b/src/app/exception/exception.pri new file mode 100644 index 000000000..d78a7f862 --- /dev/null +++ b/src/app/exception/exception.pri @@ -0,0 +1,15 @@ +HEADERS += \ + exception/vexceptionobjecterror.h \ + exception/vexceptionemptyparameter.h \ + exception/vexceptionconversionerror.h \ + exception/vexceptionbadid.h \ + exception/vexception.h \ + exception/vexceptionwrongid.h + +SOURCES += \ + exception/vexceptionobjecterror.cpp \ + exception/vexceptionemptyparameter.cpp \ + exception/vexceptionconversionerror.cpp \ + exception/vexceptionbadid.cpp \ + exception/vexception.cpp \ + exception/vexceptionwrongid.cpp diff --git a/src/exception/vexception.cpp b/src/app/exception/vexception.cpp similarity index 100% rename from src/exception/vexception.cpp rename to src/app/exception/vexception.cpp diff --git a/src/exception/vexception.h b/src/app/exception/vexception.h similarity index 100% rename from src/exception/vexception.h rename to src/app/exception/vexception.h diff --git a/src/exception/vexceptionbadid.cpp b/src/app/exception/vexceptionbadid.cpp similarity index 100% rename from src/exception/vexceptionbadid.cpp rename to src/app/exception/vexceptionbadid.cpp diff --git a/src/exception/vexceptionbadid.h b/src/app/exception/vexceptionbadid.h similarity index 100% rename from src/exception/vexceptionbadid.h rename to src/app/exception/vexceptionbadid.h diff --git a/src/exception/vexceptionconversionerror.cpp b/src/app/exception/vexceptionconversionerror.cpp similarity index 100% rename from src/exception/vexceptionconversionerror.cpp rename to src/app/exception/vexceptionconversionerror.cpp diff --git a/src/exception/vexceptionconversionerror.h b/src/app/exception/vexceptionconversionerror.h similarity index 100% rename from src/exception/vexceptionconversionerror.h rename to src/app/exception/vexceptionconversionerror.h diff --git a/src/exception/vexceptionemptyparameter.cpp b/src/app/exception/vexceptionemptyparameter.cpp similarity index 100% rename from src/exception/vexceptionemptyparameter.cpp rename to src/app/exception/vexceptionemptyparameter.cpp diff --git a/src/exception/vexceptionemptyparameter.h b/src/app/exception/vexceptionemptyparameter.h similarity index 100% rename from src/exception/vexceptionemptyparameter.h rename to src/app/exception/vexceptionemptyparameter.h diff --git a/src/exception/vexceptionobjecterror.cpp b/src/app/exception/vexceptionobjecterror.cpp similarity index 100% rename from src/exception/vexceptionobjecterror.cpp rename to src/app/exception/vexceptionobjecterror.cpp diff --git a/src/exception/vexceptionobjecterror.h b/src/app/exception/vexceptionobjecterror.h similarity index 100% rename from src/exception/vexceptionobjecterror.h rename to src/app/exception/vexceptionobjecterror.h diff --git a/src/exception/vexceptionwrongid.cpp b/src/app/exception/vexceptionwrongid.cpp similarity index 100% rename from src/exception/vexceptionwrongid.cpp rename to src/app/exception/vexceptionwrongid.cpp diff --git a/src/exception/vexceptionwrongid.h b/src/app/exception/vexceptionwrongid.h similarity index 100% rename from src/exception/vexceptionwrongid.h rename to src/app/exception/vexceptionwrongid.h diff --git a/src/app/geometry/geometry.pri b/src/app/geometry/geometry.pri new file mode 100644 index 000000000..a56d4f80e --- /dev/null +++ b/src/app/geometry/geometry.pri @@ -0,0 +1,21 @@ +HEADERS += \ + geometry/vsplinepoint.h \ + geometry/vsplinepath.h \ + geometry/vspline.h \ + geometry/vnodedetail.h \ + geometry/vdetail.h \ + geometry/varc.h \ + geometry/vgobject.h \ + geometry/vpointf.h \ + geometry/vequidistant.h + +SOURCES += \ + geometry/vsplinepoint.cpp \ + geometry/vsplinepath.cpp \ + geometry/vspline.cpp \ + geometry/vnodedetail.cpp \ + geometry/vdetail.cpp \ + geometry/varc.cpp \ + geometry/vgobject.cpp \ + geometry/vpointf.cpp \ + geometry/vequidistant.cpp diff --git a/src/geometry/varc.cpp b/src/app/geometry/varc.cpp similarity index 100% rename from src/geometry/varc.cpp rename to src/app/geometry/varc.cpp diff --git a/src/geometry/varc.h b/src/app/geometry/varc.h similarity index 100% rename from src/geometry/varc.h rename to src/app/geometry/varc.h diff --git a/src/geometry/vdetail.cpp b/src/app/geometry/vdetail.cpp similarity index 100% rename from src/geometry/vdetail.cpp rename to src/app/geometry/vdetail.cpp diff --git a/src/geometry/vdetail.h b/src/app/geometry/vdetail.h similarity index 100% rename from src/geometry/vdetail.h rename to src/app/geometry/vdetail.h diff --git a/src/geometry/vequidistant.cpp b/src/app/geometry/vequidistant.cpp similarity index 100% rename from src/geometry/vequidistant.cpp rename to src/app/geometry/vequidistant.cpp diff --git a/src/geometry/vequidistant.h b/src/app/geometry/vequidistant.h similarity index 100% rename from src/geometry/vequidistant.h rename to src/app/geometry/vequidistant.h diff --git a/src/geometry/vgobject.cpp b/src/app/geometry/vgobject.cpp similarity index 100% rename from src/geometry/vgobject.cpp rename to src/app/geometry/vgobject.cpp diff --git a/src/geometry/vgobject.h b/src/app/geometry/vgobject.h similarity index 100% rename from src/geometry/vgobject.h rename to src/app/geometry/vgobject.h diff --git a/src/geometry/vnodedetail.cpp b/src/app/geometry/vnodedetail.cpp similarity index 100% rename from src/geometry/vnodedetail.cpp rename to src/app/geometry/vnodedetail.cpp diff --git a/src/geometry/vnodedetail.h b/src/app/geometry/vnodedetail.h similarity index 100% rename from src/geometry/vnodedetail.h rename to src/app/geometry/vnodedetail.h diff --git a/src/geometry/vpointf.cpp b/src/app/geometry/vpointf.cpp similarity index 100% rename from src/geometry/vpointf.cpp rename to src/app/geometry/vpointf.cpp diff --git a/src/geometry/vpointf.h b/src/app/geometry/vpointf.h similarity index 100% rename from src/geometry/vpointf.h rename to src/app/geometry/vpointf.h diff --git a/src/geometry/vspline.cpp b/src/app/geometry/vspline.cpp similarity index 100% rename from src/geometry/vspline.cpp rename to src/app/geometry/vspline.cpp diff --git a/src/geometry/vspline.h b/src/app/geometry/vspline.h similarity index 100% rename from src/geometry/vspline.h rename to src/app/geometry/vspline.h diff --git a/src/geometry/vsplinepath.cpp b/src/app/geometry/vsplinepath.cpp similarity index 100% rename from src/geometry/vsplinepath.cpp rename to src/app/geometry/vsplinepath.cpp diff --git a/src/geometry/vsplinepath.h b/src/app/geometry/vsplinepath.h similarity index 100% rename from src/geometry/vsplinepath.h rename to src/app/geometry/vsplinepath.h diff --git a/src/geometry/vsplinepoint.cpp b/src/app/geometry/vsplinepoint.cpp similarity index 100% rename from src/geometry/vsplinepoint.cpp rename to src/app/geometry/vsplinepoint.cpp diff --git a/src/geometry/vsplinepoint.h b/src/app/geometry/vsplinepoint.h similarity index 100% rename from src/geometry/vsplinepoint.h rename to src/app/geometry/vsplinepoint.h diff --git a/src/main.cpp b/src/app/main.cpp similarity index 100% rename from src/main.cpp rename to src/app/main.cpp diff --git a/src/mainwindow.cpp b/src/app/mainwindow.cpp similarity index 100% rename from src/mainwindow.cpp rename to src/app/mainwindow.cpp diff --git a/src/mainwindow.h b/src/app/mainwindow.h similarity index 100% rename from src/mainwindow.h rename to src/app/mainwindow.h diff --git a/src/mainwindow.ui b/src/app/mainwindow.ui similarity index 100% rename from src/mainwindow.ui rename to src/app/mainwindow.ui diff --git a/src/options.h b/src/app/options.h similarity index 100% rename from src/options.h rename to src/app/options.h diff --git a/share/resources/cursor.qrc b/src/app/share/resources/cursor.qrc similarity index 100% rename from share/resources/cursor.qrc rename to src/app/share/resources/cursor.qrc diff --git a/share/resources/cursor/alongline_cursor.png b/src/app/share/resources/cursor/alongline_cursor.png similarity index 100% rename from share/resources/cursor/alongline_cursor.png rename to src/app/share/resources/cursor/alongline_cursor.png diff --git a/share/resources/cursor/arc_cursor.png b/src/app/share/resources/cursor/arc_cursor.png similarity index 100% rename from share/resources/cursor/arc_cursor.png rename to src/app/share/resources/cursor/arc_cursor.png diff --git a/share/resources/cursor/arc_cut_cursor.png b/src/app/share/resources/cursor/arc_cut_cursor.png similarity index 100% rename from share/resources/cursor/arc_cut_cursor.png rename to src/app/share/resources/cursor/arc_cut_cursor.png diff --git a/share/resources/cursor/bisector_cursor.png b/src/app/share/resources/cursor/bisector_cursor.png similarity index 100% rename from share/resources/cursor/bisector_cursor.png rename to src/app/share/resources/cursor/bisector_cursor.png diff --git a/share/resources/cursor/endline_cursor.png b/src/app/share/resources/cursor/endline_cursor.png similarity index 100% rename from share/resources/cursor/endline_cursor.png rename to src/app/share/resources/cursor/endline_cursor.png diff --git a/share/resources/cursor/height_cursor.png b/src/app/share/resources/cursor/height_cursor.png similarity index 100% rename from share/resources/cursor/height_cursor.png rename to src/app/share/resources/cursor/height_cursor.png diff --git a/share/resources/cursor/intersect_cursor.png b/src/app/share/resources/cursor/intersect_cursor.png similarity index 100% rename from share/resources/cursor/intersect_cursor.png rename to src/app/share/resources/cursor/intersect_cursor.png diff --git a/share/resources/cursor/line_cursor.png b/src/app/share/resources/cursor/line_cursor.png similarity index 100% rename from share/resources/cursor/line_cursor.png rename to src/app/share/resources/cursor/line_cursor.png diff --git a/share/resources/cursor/new_detail_cursor.png b/src/app/share/resources/cursor/new_detail_cursor.png similarity index 100% rename from share/resources/cursor/new_detail_cursor.png rename to src/app/share/resources/cursor/new_detail_cursor.png diff --git a/share/resources/cursor/normal_cursor.png b/src/app/share/resources/cursor/normal_cursor.png similarity index 100% rename from share/resources/cursor/normal_cursor.png rename to src/app/share/resources/cursor/normal_cursor.png diff --git a/share/resources/cursor/pointcontact_cursor.png b/src/app/share/resources/cursor/pointcontact_cursor.png similarity index 100% rename from share/resources/cursor/pointcontact_cursor.png rename to src/app/share/resources/cursor/pointcontact_cursor.png diff --git a/share/resources/cursor/pointofintersect_cursor.png b/src/app/share/resources/cursor/pointofintersect_cursor.png similarity index 100% rename from share/resources/cursor/pointofintersect_cursor.png rename to src/app/share/resources/cursor/pointofintersect_cursor.png diff --git a/share/resources/cursor/shoulder_cursor.png b/src/app/share/resources/cursor/shoulder_cursor.png similarity index 100% rename from share/resources/cursor/shoulder_cursor.png rename to src/app/share/resources/cursor/shoulder_cursor.png diff --git a/share/resources/cursor/spline_cursor.png b/src/app/share/resources/cursor/spline_cursor.png similarity index 100% rename from share/resources/cursor/spline_cursor.png rename to src/app/share/resources/cursor/spline_cursor.png diff --git a/share/resources/cursor/spline_cut_point_cursor.png b/src/app/share/resources/cursor/spline_cut_point_cursor.png similarity index 100% rename from share/resources/cursor/spline_cut_point_cursor.png rename to src/app/share/resources/cursor/spline_cut_point_cursor.png diff --git a/share/resources/cursor/splinepath_cursor.png b/src/app/share/resources/cursor/splinepath_cursor.png similarity index 100% rename from share/resources/cursor/splinepath_cursor.png rename to src/app/share/resources/cursor/splinepath_cursor.png diff --git a/share/resources/cursor/splinepath_cut_point_cursor.png b/src/app/share/resources/cursor/splinepath_cut_point_cursor.png similarity index 100% rename from share/resources/cursor/splinepath_cut_point_cursor.png rename to src/app/share/resources/cursor/splinepath_cut_point_cursor.png diff --git a/share/resources/cursor/triangle_cursor.png b/src/app/share/resources/cursor/triangle_cursor.png similarity index 100% rename from share/resources/cursor/triangle_cursor.png rename to src/app/share/resources/cursor/triangle_cursor.png diff --git a/share/resources/cursor/union_cursor.png b/src/app/share/resources/cursor/union_cursor.png similarity index 100% rename from share/resources/cursor/union_cursor.png rename to src/app/share/resources/cursor/union_cursor.png diff --git a/share/resources/icon.qrc b/src/app/share/resources/icon.qrc similarity index 100% rename from share/resources/icon.qrc rename to src/app/share/resources/icon.qrc diff --git a/share/resources/icon/16x16/mirror.png b/src/app/share/resources/icon/16x16/mirror.png similarity index 100% rename from share/resources/icon/16x16/mirror.png rename to src/app/share/resources/icon/16x16/mirror.png diff --git a/share/resources/icon/24x24/arrowDown.png b/src/app/share/resources/icon/24x24/arrowDown.png similarity index 100% rename from share/resources/icon/24x24/arrowDown.png rename to src/app/share/resources/icon/24x24/arrowDown.png diff --git a/share/resources/icon/24x24/arrowLeft.png b/src/app/share/resources/icon/24x24/arrowLeft.png similarity index 100% rename from share/resources/icon/24x24/arrowLeft.png rename to src/app/share/resources/icon/24x24/arrowLeft.png diff --git a/share/resources/icon/24x24/arrowLeftDown.png b/src/app/share/resources/icon/24x24/arrowLeftDown.png similarity index 100% rename from share/resources/icon/24x24/arrowLeftDown.png rename to src/app/share/resources/icon/24x24/arrowLeftDown.png diff --git a/share/resources/icon/24x24/arrowLeftUp.png b/src/app/share/resources/icon/24x24/arrowLeftUp.png similarity index 100% rename from share/resources/icon/24x24/arrowLeftUp.png rename to src/app/share/resources/icon/24x24/arrowLeftUp.png diff --git a/share/resources/icon/24x24/arrowRight.png b/src/app/share/resources/icon/24x24/arrowRight.png similarity index 100% rename from share/resources/icon/24x24/arrowRight.png rename to src/app/share/resources/icon/24x24/arrowRight.png diff --git a/share/resources/icon/24x24/arrowRightDown.png b/src/app/share/resources/icon/24x24/arrowRightDown.png similarity index 100% rename from share/resources/icon/24x24/arrowRightDown.png rename to src/app/share/resources/icon/24x24/arrowRightDown.png diff --git a/share/resources/icon/24x24/arrowRightUp.png b/src/app/share/resources/icon/24x24/arrowRightUp.png similarity index 100% rename from share/resources/icon/24x24/arrowRightUp.png rename to src/app/share/resources/icon/24x24/arrowRightUp.png diff --git a/share/resources/icon/24x24/arrowUp.png b/src/app/share/resources/icon/24x24/arrowUp.png similarity index 100% rename from share/resources/icon/24x24/arrowUp.png rename to src/app/share/resources/icon/24x24/arrowUp.png diff --git a/share/resources/icon/24x24/equal.png b/src/app/share/resources/icon/24x24/equal.png similarity index 100% rename from share/resources/icon/24x24/equal.png rename to src/app/share/resources/icon/24x24/equal.png diff --git a/share/resources/icon/24x24/putHere.png b/src/app/share/resources/icon/24x24/putHere.png similarity index 100% rename from share/resources/icon/24x24/putHere.png rename to src/app/share/resources/icon/24x24/putHere.png diff --git a/share/resources/icon/24x24/putHereLeft.png b/src/app/share/resources/icon/24x24/putHereLeft.png similarity index 100% rename from share/resources/icon/24x24/putHereLeft.png rename to src/app/share/resources/icon/24x24/putHereLeft.png diff --git a/share/resources/icon/32x32/along_line.png b/src/app/share/resources/icon/32x32/along_line.png similarity index 100% rename from share/resources/icon/32x32/along_line.png rename to src/app/share/resources/icon/32x32/along_line.png diff --git a/share/resources/icon/32x32/arc.png b/src/app/share/resources/icon/32x32/arc.png similarity index 100% rename from share/resources/icon/32x32/arc.png rename to src/app/share/resources/icon/32x32/arc.png diff --git a/share/resources/icon/32x32/arc_cut.png b/src/app/share/resources/icon/32x32/arc_cut.png similarity index 100% rename from share/resources/icon/32x32/arc_cut.png rename to src/app/share/resources/icon/32x32/arc_cut.png diff --git a/share/resources/icon/32x32/arrow_cursor.png b/src/app/share/resources/icon/32x32/arrow_cursor.png similarity index 100% rename from share/resources/icon/32x32/arrow_cursor.png rename to src/app/share/resources/icon/32x32/arrow_cursor.png diff --git a/share/resources/icon/32x32/bisector.png b/src/app/share/resources/icon/32x32/bisector.png similarity index 100% rename from share/resources/icon/32x32/bisector.png rename to src/app/share/resources/icon/32x32/bisector.png diff --git a/share/resources/icon/32x32/draw.png b/src/app/share/resources/icon/32x32/draw.png similarity index 100% rename from share/resources/icon/32x32/draw.png rename to src/app/share/resources/icon/32x32/draw.png diff --git a/share/resources/icon/32x32/height.png b/src/app/share/resources/icon/32x32/height.png similarity index 100% rename from share/resources/icon/32x32/height.png rename to src/app/share/resources/icon/32x32/height.png diff --git a/share/resources/icon/32x32/history.png b/src/app/share/resources/icon/32x32/history.png similarity index 100% rename from share/resources/icon/32x32/history.png rename to src/app/share/resources/icon/32x32/history.png diff --git a/share/resources/icon/32x32/intersect.png b/src/app/share/resources/icon/32x32/intersect.png similarity index 100% rename from share/resources/icon/32x32/intersect.png rename to src/app/share/resources/icon/32x32/intersect.png diff --git a/share/resources/icon/32x32/kontur.png b/src/app/share/resources/icon/32x32/kontur.png similarity index 100% rename from share/resources/icon/32x32/kontur.png rename to src/app/share/resources/icon/32x32/kontur.png diff --git a/share/resources/icon/32x32/layout.png b/src/app/share/resources/icon/32x32/layout.png similarity index 100% rename from share/resources/icon/32x32/layout.png rename to src/app/share/resources/icon/32x32/layout.png diff --git a/share/resources/icon/32x32/line.png b/src/app/share/resources/icon/32x32/line.png similarity index 100% rename from share/resources/icon/32x32/line.png rename to src/app/share/resources/icon/32x32/line.png diff --git a/share/resources/icon/32x32/new_detail.png b/src/app/share/resources/icon/32x32/new_detail.png similarity index 100% rename from share/resources/icon/32x32/new_detail.png rename to src/app/share/resources/icon/32x32/new_detail.png diff --git a/share/resources/icon/32x32/new_draw.png b/src/app/share/resources/icon/32x32/new_draw.png similarity index 100% rename from share/resources/icon/32x32/new_draw.png rename to src/app/share/resources/icon/32x32/new_draw.png diff --git a/share/resources/icon/32x32/normal.png b/src/app/share/resources/icon/32x32/normal.png similarity index 100% rename from share/resources/icon/32x32/normal.png rename to src/app/share/resources/icon/32x32/normal.png diff --git a/share/resources/icon/32x32/option_draw.png b/src/app/share/resources/icon/32x32/option_draw.png similarity index 100% rename from share/resources/icon/32x32/option_draw.png rename to src/app/share/resources/icon/32x32/option_draw.png diff --git a/share/resources/icon/32x32/point_of_contact.png b/src/app/share/resources/icon/32x32/point_of_contact.png similarity index 100% rename from share/resources/icon/32x32/point_of_contact.png rename to src/app/share/resources/icon/32x32/point_of_contact.png diff --git a/share/resources/icon/32x32/point_of_intersection.png b/src/app/share/resources/icon/32x32/point_of_intersection.png similarity index 100% rename from share/resources/icon/32x32/point_of_intersection.png rename to src/app/share/resources/icon/32x32/point_of_intersection.png diff --git a/share/resources/icon/32x32/put_after.png b/src/app/share/resources/icon/32x32/put_after.png similarity index 100% rename from share/resources/icon/32x32/put_after.png rename to src/app/share/resources/icon/32x32/put_after.png diff --git a/share/resources/icon/32x32/segment.png b/src/app/share/resources/icon/32x32/segment.png similarity index 100% rename from share/resources/icon/32x32/segment.png rename to src/app/share/resources/icon/32x32/segment.png diff --git a/share/resources/icon/32x32/shoulder.png b/src/app/share/resources/icon/32x32/shoulder.png similarity index 100% rename from share/resources/icon/32x32/shoulder.png rename to src/app/share/resources/icon/32x32/shoulder.png diff --git a/share/resources/icon/32x32/spline.png b/src/app/share/resources/icon/32x32/spline.png similarity index 100% rename from share/resources/icon/32x32/spline.png rename to src/app/share/resources/icon/32x32/spline.png diff --git a/share/resources/icon/32x32/splinePath.png b/src/app/share/resources/icon/32x32/splinePath.png similarity index 100% rename from share/resources/icon/32x32/splinePath.png rename to src/app/share/resources/icon/32x32/splinePath.png diff --git a/share/resources/icon/32x32/splinePath_cut_point.png b/src/app/share/resources/icon/32x32/splinePath_cut_point.png similarity index 100% rename from share/resources/icon/32x32/splinePath_cut_point.png rename to src/app/share/resources/icon/32x32/splinePath_cut_point.png diff --git a/share/resources/icon/32x32/spline_cut_point.png b/src/app/share/resources/icon/32x32/spline_cut_point.png similarity index 100% rename from share/resources/icon/32x32/spline_cut_point.png rename to src/app/share/resources/icon/32x32/spline_cut_point.png diff --git a/share/resources/icon/32x32/table.png b/src/app/share/resources/icon/32x32/table.png similarity index 100% rename from share/resources/icon/32x32/table.png rename to src/app/share/resources/icon/32x32/table.png diff --git a/share/resources/icon/32x32/triangle.png b/src/app/share/resources/icon/32x32/triangle.png similarity index 100% rename from share/resources/icon/32x32/triangle.png rename to src/app/share/resources/icon/32x32/triangle.png diff --git a/share/resources/icon/32x32/union.png b/src/app/share/resources/icon/32x32/union.png similarity index 100% rename from share/resources/icon/32x32/union.png rename to src/app/share/resources/icon/32x32/union.png diff --git a/share/resources/icon/64x64/icon64x64.ico b/src/app/share/resources/icon/64x64/icon64x64.ico similarity index 100% rename from share/resources/icon/64x64/icon64x64.ico rename to src/app/share/resources/icon/64x64/icon64x64.ico diff --git a/share/resources/icon/64x64/icon64x64.png b/src/app/share/resources/icon/64x64/icon64x64.png similarity index 100% rename from share/resources/icon/64x64/icon64x64.png rename to src/app/share/resources/icon/64x64/icon64x64.png diff --git a/share/resources/icon/Graduation.png b/src/app/share/resources/icon/Graduation.png similarity index 100% rename from share/resources/icon/Graduation.png rename to src/app/share/resources/icon/Graduation.png diff --git a/share/resources/icon/config.png b/src/app/share/resources/icon/config.png similarity index 100% rename from share/resources/icon/config.png rename to src/app/share/resources/icon/config.png diff --git a/share/resources/icon/flags/cs.png b/src/app/share/resources/icon/flags/cs.png similarity index 100% rename from share/resources/icon/flags/cs.png rename to src/app/share/resources/icon/flags/cs.png diff --git a/share/resources/icon/flags/de.png b/src/app/share/resources/icon/flags/de.png similarity index 100% rename from share/resources/icon/flags/de.png rename to src/app/share/resources/icon/flags/de.png diff --git a/share/resources/icon/flags/en.png b/src/app/share/resources/icon/flags/en.png similarity index 100% rename from share/resources/icon/flags/en.png rename to src/app/share/resources/icon/flags/en.png diff --git a/share/resources/icon/flags/fr.png b/src/app/share/resources/icon/flags/fr.png similarity index 100% rename from share/resources/icon/flags/fr.png rename to src/app/share/resources/icon/flags/fr.png diff --git a/share/resources/icon/flags/he_IL.png b/src/app/share/resources/icon/flags/he_IL.png similarity index 100% rename from share/resources/icon/flags/he_IL.png rename to src/app/share/resources/icon/flags/he_IL.png diff --git a/share/resources/icon/flags/ru.png b/src/app/share/resources/icon/flags/ru.png similarity index 100% rename from share/resources/icon/flags/ru.png rename to src/app/share/resources/icon/flags/ru.png diff --git a/share/resources/icon/flags/uk.png b/src/app/share/resources/icon/flags/uk.png similarity index 100% rename from share/resources/icon/flags/uk.png rename to src/app/share/resources/icon/flags/uk.png diff --git a/share/resources/icon/individual.png b/src/app/share/resources/icon/individual.png similarity index 100% rename from share/resources/icon/individual.png rename to src/app/share/resources/icon/individual.png diff --git a/share/resources/icon/logo.svg b/src/app/share/resources/icon/logo.svg similarity index 100% rename from share/resources/icon/logo.svg rename to src/app/share/resources/icon/logo.svg diff --git a/share/resources/icon/pattern_config.png b/src/app/share/resources/icon/pattern_config.png similarity index 100% rename from share/resources/icon/pattern_config.png rename to src/app/share/resources/icon/pattern_config.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/document-new.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-new.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/document-new.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/document-new.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/document-open.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-open.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/document-open.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/document-open.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/document-save-as.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-save-as.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/document-save-as.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/document-save-as.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/document-save.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/document-save.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/document-save.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/document-save.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/go-next.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/go-next.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/go-next.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/go-next.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/list-add.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/list-add.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/list-add.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/list-add.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/list-remove.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/list-remove.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/list-remove.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/list-remove.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/object-rotate-left.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/object-rotate-left.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/object-rotate-left.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/object-rotate-left.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/process-stop.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/process-stop.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/process-stop.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/process-stop.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/zoom-in.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/zoom-in.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/zoom-in.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/zoom-in.png diff --git a/share/resources/icons/win.icon.theme/16x16/actions/zoom-out.png b/src/app/share/resources/icons/win.icon.theme/16x16/actions/zoom-out.png similarity index 100% rename from share/resources/icons/win.icon.theme/16x16/actions/zoom-out.png rename to src/app/share/resources/icons/win.icon.theme/16x16/actions/zoom-out.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/document-new.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-new.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/document-new.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/document-new.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/document-open.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-open.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/document-open.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/document-open.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/document-save-as.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-save-as.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/document-save-as.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/document-save-as.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/document-save.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/document-save.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/document-save.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/document-save.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/go-next.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/go-next.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/go-next.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/go-next.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/list-add.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/list-add.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/list-add.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/list-add.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/list-remove.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/list-remove.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/list-remove.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/list-remove.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/object-rotate-left.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/object-rotate-left.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/object-rotate-left.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/object-rotate-left.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/process-stop.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/process-stop.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/process-stop.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/process-stop.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/zoom-in.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/zoom-in.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/zoom-in.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/zoom-in.png diff --git a/share/resources/icons/win.icon.theme/24x24/actions/zoom-out.png b/src/app/share/resources/icons/win.icon.theme/24x24/actions/zoom-out.png similarity index 100% rename from share/resources/icons/win.icon.theme/24x24/actions/zoom-out.png rename to src/app/share/resources/icons/win.icon.theme/24x24/actions/zoom-out.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/document-new.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-new.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/document-new.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/document-new.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/document-open.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-open.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/document-open.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/document-open.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/document-save-as.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-save-as.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/document-save-as.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/document-save-as.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/document-save.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/document-save.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/document-save.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/document-save.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/go-next.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/go-next.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/go-next.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/go-next.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/list-add.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/list-add.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/list-add.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/list-add.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/list-remove.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/list-remove.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/list-remove.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/list-remove.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/object-rotate-left.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/object-rotate-left.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/object-rotate-left.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/object-rotate-left.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/process-stop.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/process-stop.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/process-stop.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/process-stop.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/zoom-in.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/zoom-in.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/zoom-in.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/zoom-in.png diff --git a/share/resources/icons/win.icon.theme/32x32/actions/zoom-out.png b/src/app/share/resources/icons/win.icon.theme/32x32/actions/zoom-out.png similarity index 100% rename from share/resources/icons/win.icon.theme/32x32/actions/zoom-out.png rename to src/app/share/resources/icons/win.icon.theme/32x32/actions/zoom-out.png diff --git a/share/resources/icons/win.icon.theme/index.theme b/src/app/share/resources/icons/win.icon.theme/index.theme similarity index 100% rename from share/resources/icons/win.icon.theme/index.theme rename to src/app/share/resources/icons/win.icon.theme/index.theme diff --git a/share/resources/schema.qrc b/src/app/share/resources/schema.qrc similarity index 100% rename from share/resources/schema.qrc rename to src/app/share/resources/schema.qrc diff --git a/share/resources/schema/individual_measurements.xsd b/src/app/share/resources/schema/individual_measurements.xsd similarity index 100% rename from share/resources/schema/individual_measurements.xsd rename to src/app/share/resources/schema/individual_measurements.xsd diff --git a/share/resources/schema/pattern.xsd b/src/app/share/resources/schema/pattern.xsd similarity index 100% rename from share/resources/schema/pattern.xsd rename to src/app/share/resources/schema/pattern.xsd diff --git a/share/resources/schema/standard_measurements.xsd b/src/app/share/resources/schema/standard_measurements.xsd similarity index 100% rename from share/resources/schema/standard_measurements.xsd rename to src/app/share/resources/schema/standard_measurements.xsd diff --git a/share/resources/theme.qrc b/src/app/share/resources/theme.qrc similarity index 100% rename from share/resources/theme.qrc rename to src/app/share/resources/theme.qrc diff --git a/share/resources/valentina.rc b/src/app/share/resources/valentina.rc similarity index 100% rename from share/resources/valentina.rc rename to src/app/share/resources/valentina.rc diff --git a/share/tables/individual/indivindual_ru.vit b/src/app/share/tables/individual/indivindual_ru.vit similarity index 100% rename from share/tables/individual/indivindual_ru.vit rename to src/app/share/tables/individual/indivindual_ru.vit diff --git a/share/tables/standard/GOST_man_ru.vst b/src/app/share/tables/standard/GOST_man_ru.vst similarity index 100% rename from share/tables/standard/GOST_man_ru.vst rename to src/app/share/tables/standard/GOST_man_ru.vst diff --git a/share/translations/valentina.ts b/src/app/share/translations/valentina.ts similarity index 100% rename from share/translations/valentina.ts rename to src/app/share/translations/valentina.ts diff --git a/share/translations/valentina_cs.ts b/src/app/share/translations/valentina_cs.ts similarity index 100% rename from share/translations/valentina_cs.ts rename to src/app/share/translations/valentina_cs.ts diff --git a/share/translations/valentina_de.ts b/src/app/share/translations/valentina_de.ts similarity index 100% rename from share/translations/valentina_de.ts rename to src/app/share/translations/valentina_de.ts diff --git a/share/translations/valentina_fr.ts b/src/app/share/translations/valentina_fr.ts similarity index 100% rename from share/translations/valentina_fr.ts rename to src/app/share/translations/valentina_fr.ts diff --git a/share/translations/valentina_he_IL.ts b/src/app/share/translations/valentina_he_IL.ts similarity index 100% rename from share/translations/valentina_he_IL.ts rename to src/app/share/translations/valentina_he_IL.ts diff --git a/share/translations/valentina_ru.ts b/src/app/share/translations/valentina_ru.ts similarity index 100% rename from share/translations/valentina_ru.ts rename to src/app/share/translations/valentina_ru.ts diff --git a/share/translations/valentina_uk.ts b/src/app/share/translations/valentina_uk.ts similarity index 100% rename from share/translations/valentina_uk.ts rename to src/app/share/translations/valentina_uk.ts diff --git a/src/stable.cpp b/src/app/stable.cpp similarity index 100% rename from src/stable.cpp rename to src/app/stable.cpp diff --git a/src/stable.h b/src/app/stable.h similarity index 100% rename from src/stable.h rename to src/app/stable.h diff --git a/src/tablewindow.cpp b/src/app/tablewindow.cpp similarity index 100% rename from src/tablewindow.cpp rename to src/app/tablewindow.cpp diff --git a/src/tablewindow.h b/src/app/tablewindow.h similarity index 100% rename from src/tablewindow.h rename to src/app/tablewindow.h diff --git a/src/tablewindow.ui b/src/app/tablewindow.ui similarity index 100% rename from src/tablewindow.ui rename to src/app/tablewindow.ui diff --git a/src/tools/drawTools/drawtools.h b/src/app/tools/drawTools/drawtools.h similarity index 100% rename from src/tools/drawTools/drawtools.h rename to src/app/tools/drawTools/drawtools.h diff --git a/src/tools/drawTools/vabstractspline.cpp b/src/app/tools/drawTools/vabstractspline.cpp similarity index 100% rename from src/tools/drawTools/vabstractspline.cpp rename to src/app/tools/drawTools/vabstractspline.cpp diff --git a/src/tools/drawTools/vabstractspline.h b/src/app/tools/drawTools/vabstractspline.h similarity index 100% rename from src/tools/drawTools/vabstractspline.h rename to src/app/tools/drawTools/vabstractspline.h diff --git a/src/tools/drawTools/vdrawtool.cpp b/src/app/tools/drawTools/vdrawtool.cpp similarity index 100% rename from src/tools/drawTools/vdrawtool.cpp rename to src/app/tools/drawTools/vdrawtool.cpp diff --git a/src/tools/drawTools/vdrawtool.h b/src/app/tools/drawTools/vdrawtool.h similarity index 100% rename from src/tools/drawTools/vdrawtool.h rename to src/app/tools/drawTools/vdrawtool.h diff --git a/src/tools/drawTools/vtoolalongline.cpp b/src/app/tools/drawTools/vtoolalongline.cpp similarity index 100% rename from src/tools/drawTools/vtoolalongline.cpp rename to src/app/tools/drawTools/vtoolalongline.cpp diff --git a/src/tools/drawTools/vtoolalongline.h b/src/app/tools/drawTools/vtoolalongline.h similarity index 100% rename from src/tools/drawTools/vtoolalongline.h rename to src/app/tools/drawTools/vtoolalongline.h diff --git a/src/tools/drawTools/vtoolarc.cpp b/src/app/tools/drawTools/vtoolarc.cpp similarity index 100% rename from src/tools/drawTools/vtoolarc.cpp rename to src/app/tools/drawTools/vtoolarc.cpp diff --git a/src/tools/drawTools/vtoolarc.h b/src/app/tools/drawTools/vtoolarc.h similarity index 100% rename from src/tools/drawTools/vtoolarc.h rename to src/app/tools/drawTools/vtoolarc.h diff --git a/src/tools/drawTools/vtoolbisector.cpp b/src/app/tools/drawTools/vtoolbisector.cpp similarity index 100% rename from src/tools/drawTools/vtoolbisector.cpp rename to src/app/tools/drawTools/vtoolbisector.cpp diff --git a/src/tools/drawTools/vtoolbisector.h b/src/app/tools/drawTools/vtoolbisector.h similarity index 100% rename from src/tools/drawTools/vtoolbisector.h rename to src/app/tools/drawTools/vtoolbisector.h diff --git a/src/tools/drawTools/vtoolcutarc.cpp b/src/app/tools/drawTools/vtoolcutarc.cpp similarity index 100% rename from src/tools/drawTools/vtoolcutarc.cpp rename to src/app/tools/drawTools/vtoolcutarc.cpp diff --git a/src/tools/drawTools/vtoolcutarc.h b/src/app/tools/drawTools/vtoolcutarc.h similarity index 100% rename from src/tools/drawTools/vtoolcutarc.h rename to src/app/tools/drawTools/vtoolcutarc.h diff --git a/src/tools/drawTools/vtoolcutspline.cpp b/src/app/tools/drawTools/vtoolcutspline.cpp similarity index 100% rename from src/tools/drawTools/vtoolcutspline.cpp rename to src/app/tools/drawTools/vtoolcutspline.cpp diff --git a/src/tools/drawTools/vtoolcutspline.h b/src/app/tools/drawTools/vtoolcutspline.h similarity index 100% rename from src/tools/drawTools/vtoolcutspline.h rename to src/app/tools/drawTools/vtoolcutspline.h diff --git a/src/tools/drawTools/vtoolcutsplinepath.cpp b/src/app/tools/drawTools/vtoolcutsplinepath.cpp similarity index 100% rename from src/tools/drawTools/vtoolcutsplinepath.cpp rename to src/app/tools/drawTools/vtoolcutsplinepath.cpp diff --git a/src/tools/drawTools/vtoolcutsplinepath.h b/src/app/tools/drawTools/vtoolcutsplinepath.h similarity index 100% rename from src/tools/drawTools/vtoolcutsplinepath.h rename to src/app/tools/drawTools/vtoolcutsplinepath.h diff --git a/src/tools/drawTools/vtoolendline.cpp b/src/app/tools/drawTools/vtoolendline.cpp similarity index 100% rename from src/tools/drawTools/vtoolendline.cpp rename to src/app/tools/drawTools/vtoolendline.cpp diff --git a/src/tools/drawTools/vtoolendline.h b/src/app/tools/drawTools/vtoolendline.h similarity index 100% rename from src/tools/drawTools/vtoolendline.h rename to src/app/tools/drawTools/vtoolendline.h diff --git a/src/tools/drawTools/vtoolheight.cpp b/src/app/tools/drawTools/vtoolheight.cpp similarity index 100% rename from src/tools/drawTools/vtoolheight.cpp rename to src/app/tools/drawTools/vtoolheight.cpp diff --git a/src/tools/drawTools/vtoolheight.h b/src/app/tools/drawTools/vtoolheight.h similarity index 100% rename from src/tools/drawTools/vtoolheight.h rename to src/app/tools/drawTools/vtoolheight.h diff --git a/src/tools/drawTools/vtoolline.cpp b/src/app/tools/drawTools/vtoolline.cpp similarity index 100% rename from src/tools/drawTools/vtoolline.cpp rename to src/app/tools/drawTools/vtoolline.cpp diff --git a/src/tools/drawTools/vtoolline.h b/src/app/tools/drawTools/vtoolline.h similarity index 100% rename from src/tools/drawTools/vtoolline.h rename to src/app/tools/drawTools/vtoolline.h diff --git a/src/tools/drawTools/vtoollineintersect.cpp b/src/app/tools/drawTools/vtoollineintersect.cpp similarity index 100% rename from src/tools/drawTools/vtoollineintersect.cpp rename to src/app/tools/drawTools/vtoollineintersect.cpp diff --git a/src/tools/drawTools/vtoollineintersect.h b/src/app/tools/drawTools/vtoollineintersect.h similarity index 100% rename from src/tools/drawTools/vtoollineintersect.h rename to src/app/tools/drawTools/vtoollineintersect.h diff --git a/src/tools/drawTools/vtoollinepoint.cpp b/src/app/tools/drawTools/vtoollinepoint.cpp similarity index 100% rename from src/tools/drawTools/vtoollinepoint.cpp rename to src/app/tools/drawTools/vtoollinepoint.cpp diff --git a/src/tools/drawTools/vtoollinepoint.h b/src/app/tools/drawTools/vtoollinepoint.h similarity index 100% rename from src/tools/drawTools/vtoollinepoint.h rename to src/app/tools/drawTools/vtoollinepoint.h diff --git a/src/tools/drawTools/vtoolnormal.cpp b/src/app/tools/drawTools/vtoolnormal.cpp similarity index 100% rename from src/tools/drawTools/vtoolnormal.cpp rename to src/app/tools/drawTools/vtoolnormal.cpp diff --git a/src/tools/drawTools/vtoolnormal.h b/src/app/tools/drawTools/vtoolnormal.h similarity index 100% rename from src/tools/drawTools/vtoolnormal.h rename to src/app/tools/drawTools/vtoolnormal.h diff --git a/src/tools/drawTools/vtoolpoint.cpp b/src/app/tools/drawTools/vtoolpoint.cpp similarity index 100% rename from src/tools/drawTools/vtoolpoint.cpp rename to src/app/tools/drawTools/vtoolpoint.cpp diff --git a/src/tools/drawTools/vtoolpoint.h b/src/app/tools/drawTools/vtoolpoint.h similarity index 100% rename from src/tools/drawTools/vtoolpoint.h rename to src/app/tools/drawTools/vtoolpoint.h diff --git a/src/tools/drawTools/vtoolpointofcontact.cpp b/src/app/tools/drawTools/vtoolpointofcontact.cpp similarity index 100% rename from src/tools/drawTools/vtoolpointofcontact.cpp rename to src/app/tools/drawTools/vtoolpointofcontact.cpp diff --git a/src/tools/drawTools/vtoolpointofcontact.h b/src/app/tools/drawTools/vtoolpointofcontact.h similarity index 100% rename from src/tools/drawTools/vtoolpointofcontact.h rename to src/app/tools/drawTools/vtoolpointofcontact.h diff --git a/src/tools/drawTools/vtoolpointofintersection.cpp b/src/app/tools/drawTools/vtoolpointofintersection.cpp similarity index 100% rename from src/tools/drawTools/vtoolpointofintersection.cpp rename to src/app/tools/drawTools/vtoolpointofintersection.cpp diff --git a/src/tools/drawTools/vtoolpointofintersection.h b/src/app/tools/drawTools/vtoolpointofintersection.h similarity index 100% rename from src/tools/drawTools/vtoolpointofintersection.h rename to src/app/tools/drawTools/vtoolpointofintersection.h diff --git a/src/tools/drawTools/vtoolshoulderpoint.cpp b/src/app/tools/drawTools/vtoolshoulderpoint.cpp similarity index 100% rename from src/tools/drawTools/vtoolshoulderpoint.cpp rename to src/app/tools/drawTools/vtoolshoulderpoint.cpp diff --git a/src/tools/drawTools/vtoolshoulderpoint.h b/src/app/tools/drawTools/vtoolshoulderpoint.h similarity index 100% rename from src/tools/drawTools/vtoolshoulderpoint.h rename to src/app/tools/drawTools/vtoolshoulderpoint.h diff --git a/src/tools/drawTools/vtoolsinglepoint.cpp b/src/app/tools/drawTools/vtoolsinglepoint.cpp similarity index 100% rename from src/tools/drawTools/vtoolsinglepoint.cpp rename to src/app/tools/drawTools/vtoolsinglepoint.cpp diff --git a/src/tools/drawTools/vtoolsinglepoint.h b/src/app/tools/drawTools/vtoolsinglepoint.h similarity index 100% rename from src/tools/drawTools/vtoolsinglepoint.h rename to src/app/tools/drawTools/vtoolsinglepoint.h diff --git a/src/tools/drawTools/vtoolspline.cpp b/src/app/tools/drawTools/vtoolspline.cpp similarity index 100% rename from src/tools/drawTools/vtoolspline.cpp rename to src/app/tools/drawTools/vtoolspline.cpp diff --git a/src/tools/drawTools/vtoolspline.h b/src/app/tools/drawTools/vtoolspline.h similarity index 100% rename from src/tools/drawTools/vtoolspline.h rename to src/app/tools/drawTools/vtoolspline.h diff --git a/src/tools/drawTools/vtoolsplinepath.cpp b/src/app/tools/drawTools/vtoolsplinepath.cpp similarity index 100% rename from src/tools/drawTools/vtoolsplinepath.cpp rename to src/app/tools/drawTools/vtoolsplinepath.cpp diff --git a/src/tools/drawTools/vtoolsplinepath.h b/src/app/tools/drawTools/vtoolsplinepath.h similarity index 100% rename from src/tools/drawTools/vtoolsplinepath.h rename to src/app/tools/drawTools/vtoolsplinepath.h diff --git a/src/tools/drawTools/vtooltriangle.cpp b/src/app/tools/drawTools/vtooltriangle.cpp similarity index 100% rename from src/tools/drawTools/vtooltriangle.cpp rename to src/app/tools/drawTools/vtooltriangle.cpp diff --git a/src/tools/drawTools/vtooltriangle.h b/src/app/tools/drawTools/vtooltriangle.h similarity index 100% rename from src/tools/drawTools/vtooltriangle.h rename to src/app/tools/drawTools/vtooltriangle.h diff --git a/src/tools/nodeDetails/nodedetails.h b/src/app/tools/nodeDetails/nodedetails.h similarity index 100% rename from src/tools/nodeDetails/nodedetails.h rename to src/app/tools/nodeDetails/nodedetails.h diff --git a/src/tools/nodeDetails/vabstractnode.cpp b/src/app/tools/nodeDetails/vabstractnode.cpp similarity index 100% rename from src/tools/nodeDetails/vabstractnode.cpp rename to src/app/tools/nodeDetails/vabstractnode.cpp diff --git a/src/tools/nodeDetails/vabstractnode.h b/src/app/tools/nodeDetails/vabstractnode.h similarity index 100% rename from src/tools/nodeDetails/vabstractnode.h rename to src/app/tools/nodeDetails/vabstractnode.h diff --git a/src/tools/nodeDetails/vnodearc.cpp b/src/app/tools/nodeDetails/vnodearc.cpp similarity index 100% rename from src/tools/nodeDetails/vnodearc.cpp rename to src/app/tools/nodeDetails/vnodearc.cpp diff --git a/src/tools/nodeDetails/vnodearc.h b/src/app/tools/nodeDetails/vnodearc.h similarity index 100% rename from src/tools/nodeDetails/vnodearc.h rename to src/app/tools/nodeDetails/vnodearc.h diff --git a/src/tools/nodeDetails/vnodepoint.cpp b/src/app/tools/nodeDetails/vnodepoint.cpp similarity index 100% rename from src/tools/nodeDetails/vnodepoint.cpp rename to src/app/tools/nodeDetails/vnodepoint.cpp diff --git a/src/tools/nodeDetails/vnodepoint.h b/src/app/tools/nodeDetails/vnodepoint.h similarity index 100% rename from src/tools/nodeDetails/vnodepoint.h rename to src/app/tools/nodeDetails/vnodepoint.h diff --git a/src/tools/nodeDetails/vnodespline.cpp b/src/app/tools/nodeDetails/vnodespline.cpp similarity index 100% rename from src/tools/nodeDetails/vnodespline.cpp rename to src/app/tools/nodeDetails/vnodespline.cpp diff --git a/src/tools/nodeDetails/vnodespline.h b/src/app/tools/nodeDetails/vnodespline.h similarity index 100% rename from src/tools/nodeDetails/vnodespline.h rename to src/app/tools/nodeDetails/vnodespline.h diff --git a/src/tools/nodeDetails/vnodesplinepath.cpp b/src/app/tools/nodeDetails/vnodesplinepath.cpp similarity index 100% rename from src/tools/nodeDetails/vnodesplinepath.cpp rename to src/app/tools/nodeDetails/vnodesplinepath.cpp diff --git a/src/tools/nodeDetails/vnodesplinepath.h b/src/app/tools/nodeDetails/vnodesplinepath.h similarity index 100% rename from src/tools/nodeDetails/vnodesplinepath.h rename to src/app/tools/nodeDetails/vnodesplinepath.h diff --git a/src/tools/tools.h b/src/app/tools/tools.h similarity index 100% rename from src/tools/tools.h rename to src/app/tools/tools.h diff --git a/src/app/tools/tools.pri b/src/app/tools/tools.pri new file mode 100644 index 000000000..b9786ca3c --- /dev/null +++ b/src/app/tools/tools.pri @@ -0,0 +1,68 @@ +HEADERS += \ + tools/vtooldetail.h \ + tools/vdatatool.h \ + tools/vabstracttool.h \ + tools/tools.h \ + tools/drawTools/vtooltriangle.h \ + tools/drawTools/vtoolsplinepath.h \ + tools/drawTools/vtoolspline.h \ + tools/drawTools/vtoolsinglepoint.h \ + tools/drawTools/vtoolshoulderpoint.h \ + tools/drawTools/vtoolpointofintersection.h \ + tools/drawTools/vtoolpointofcontact.h \ + tools/drawTools/vtoolpoint.h \ + tools/drawTools/vtoolnormal.h \ + tools/drawTools/vtoollinepoint.h \ + tools/drawTools/vtoollineintersect.h \ + tools/drawTools/vtoolline.h \ + tools/drawTools/vtoolheight.h \ + tools/drawTools/vtoolendline.h \ + tools/drawTools/vtoolbisector.h \ + tools/drawTools/vtoolarc.h \ + tools/drawTools/vtoolalongline.h \ + tools/drawTools/vdrawtool.h \ + tools/drawTools/drawtools.h \ + tools/nodeDetails/vnodesplinepath.h \ + tools/nodeDetails/vnodespline.h \ + tools/nodeDetails/vnodepoint.h \ + tools/nodeDetails/vnodearc.h \ + tools/nodeDetails/vabstractnode.h \ + tools/nodeDetails/nodedetails.h \ + tools/drawTools/vtoolcutspline.h \ + tools/drawTools/vtoolcutsplinepath.h \ + tools/vtooluniondetails.h \ + tools/drawTools/vtoolcutarc.h \ + tools/drawTools/vabstractspline.h + +SOURCES += \ + tools/vtooldetail.cpp \ + tools/vdatatool.cpp \ + tools/vabstracttool.cpp \ + tools/drawTools/vtooltriangle.cpp \ + tools/drawTools/vtoolsplinepath.cpp \ + tools/drawTools/vtoolspline.cpp \ + tools/drawTools/vtoolsinglepoint.cpp \ + tools/drawTools/vtoolshoulderpoint.cpp \ + tools/drawTools/vtoolpointofintersection.cpp \ + tools/drawTools/vtoolpointofcontact.cpp \ + tools/drawTools/vtoolpoint.cpp \ + tools/drawTools/vtoolnormal.cpp \ + tools/drawTools/vtoollinepoint.cpp \ + tools/drawTools/vtoollineintersect.cpp \ + tools/drawTools/vtoolline.cpp \ + tools/drawTools/vtoolheight.cpp \ + tools/drawTools/vtoolendline.cpp \ + tools/drawTools/vtoolbisector.cpp \ + tools/drawTools/vtoolarc.cpp \ + tools/drawTools/vtoolalongline.cpp \ + tools/drawTools/vdrawtool.cpp \ + tools/nodeDetails/vnodesplinepath.cpp \ + tools/nodeDetails/vnodespline.cpp \ + tools/nodeDetails/vnodepoint.cpp \ + tools/nodeDetails/vnodearc.cpp \ + tools/nodeDetails/vabstractnode.cpp \ + tools/drawTools/vtoolcutspline.cpp \ + tools/drawTools/vtoolcutsplinepath.cpp \ + tools/vtooluniondetails.cpp \ + tools/drawTools/vtoolcutarc.cpp \ + tools/drawTools/vabstractspline.cpp diff --git a/src/tools/vabstracttool.cpp b/src/app/tools/vabstracttool.cpp similarity index 100% rename from src/tools/vabstracttool.cpp rename to src/app/tools/vabstracttool.cpp diff --git a/src/tools/vabstracttool.h b/src/app/tools/vabstracttool.h similarity index 100% rename from src/tools/vabstracttool.h rename to src/app/tools/vabstracttool.h diff --git a/src/tools/vdatatool.cpp b/src/app/tools/vdatatool.cpp similarity index 100% rename from src/tools/vdatatool.cpp rename to src/app/tools/vdatatool.cpp diff --git a/src/tools/vdatatool.h b/src/app/tools/vdatatool.h similarity index 100% rename from src/tools/vdatatool.h rename to src/app/tools/vdatatool.h diff --git a/src/tools/vtooldetail.cpp b/src/app/tools/vtooldetail.cpp similarity index 100% rename from src/tools/vtooldetail.cpp rename to src/app/tools/vtooldetail.cpp diff --git a/src/tools/vtooldetail.h b/src/app/tools/vtooldetail.h similarity index 100% rename from src/tools/vtooldetail.h rename to src/app/tools/vtooldetail.h diff --git a/src/tools/vtooluniondetails.cpp b/src/app/tools/vtooluniondetails.cpp similarity index 100% rename from src/tools/vtooluniondetails.cpp rename to src/app/tools/vtooluniondetails.cpp diff --git a/src/tools/vtooluniondetails.h b/src/app/tools/vtooluniondetails.h similarity index 100% rename from src/tools/vtooluniondetails.h rename to src/app/tools/vtooluniondetails.h diff --git a/src/version.cpp b/src/app/version.cpp similarity index 100% rename from src/version.cpp rename to src/app/version.cpp diff --git a/src/version.h b/src/app/version.h similarity index 100% rename from src/version.h rename to src/app/version.h diff --git a/src/widgets/doubledelegate.cpp b/src/app/widgets/doubledelegate.cpp similarity index 100% rename from src/widgets/doubledelegate.cpp rename to src/app/widgets/doubledelegate.cpp diff --git a/src/widgets/doubledelegate.h b/src/app/widgets/doubledelegate.h similarity index 100% rename from src/widgets/doubledelegate.h rename to src/app/widgets/doubledelegate.h diff --git a/src/widgets/textdelegate.cpp b/src/app/widgets/textdelegate.cpp similarity index 100% rename from src/widgets/textdelegate.cpp rename to src/app/widgets/textdelegate.cpp diff --git a/src/widgets/textdelegate.h b/src/app/widgets/textdelegate.h similarity index 100% rename from src/widgets/textdelegate.h rename to src/app/widgets/textdelegate.h diff --git a/src/widgets/vapplication.cpp b/src/app/widgets/vapplication.cpp similarity index 100% rename from src/widgets/vapplication.cpp rename to src/app/widgets/vapplication.cpp diff --git a/src/widgets/vapplication.h b/src/app/widgets/vapplication.h similarity index 100% rename from src/widgets/vapplication.h rename to src/app/widgets/vapplication.h diff --git a/src/widgets/vcontrolpointspline.cpp b/src/app/widgets/vcontrolpointspline.cpp similarity index 100% rename from src/widgets/vcontrolpointspline.cpp rename to src/app/widgets/vcontrolpointspline.cpp diff --git a/src/widgets/vcontrolpointspline.h b/src/app/widgets/vcontrolpointspline.h similarity index 100% rename from src/widgets/vcontrolpointspline.h rename to src/app/widgets/vcontrolpointspline.h diff --git a/src/widgets/vgraphicssimpletextitem.cpp b/src/app/widgets/vgraphicssimpletextitem.cpp similarity index 100% rename from src/widgets/vgraphicssimpletextitem.cpp rename to src/app/widgets/vgraphicssimpletextitem.cpp diff --git a/src/widgets/vgraphicssimpletextitem.h b/src/app/widgets/vgraphicssimpletextitem.h similarity index 100% rename from src/widgets/vgraphicssimpletextitem.h rename to src/app/widgets/vgraphicssimpletextitem.h diff --git a/src/widgets/vitem.cpp b/src/app/widgets/vitem.cpp similarity index 100% rename from src/widgets/vitem.cpp rename to src/app/widgets/vitem.cpp diff --git a/src/widgets/vitem.h b/src/app/widgets/vitem.h similarity index 100% rename from src/widgets/vitem.h rename to src/app/widgets/vitem.h diff --git a/src/widgets/vmaingraphicsscene.cpp b/src/app/widgets/vmaingraphicsscene.cpp similarity index 100% rename from src/widgets/vmaingraphicsscene.cpp rename to src/app/widgets/vmaingraphicsscene.cpp diff --git a/src/widgets/vmaingraphicsscene.h b/src/app/widgets/vmaingraphicsscene.h similarity index 100% rename from src/widgets/vmaingraphicsscene.h rename to src/app/widgets/vmaingraphicsscene.h diff --git a/src/widgets/vmaingraphicsview.cpp b/src/app/widgets/vmaingraphicsview.cpp similarity index 100% rename from src/widgets/vmaingraphicsview.cpp rename to src/app/widgets/vmaingraphicsview.cpp diff --git a/src/widgets/vmaingraphicsview.h b/src/app/widgets/vmaingraphicsview.h similarity index 100% rename from src/widgets/vmaingraphicsview.h rename to src/app/widgets/vmaingraphicsview.h diff --git a/src/widgets/vsimplearc.cpp b/src/app/widgets/vsimplearc.cpp similarity index 100% rename from src/widgets/vsimplearc.cpp rename to src/app/widgets/vsimplearc.cpp diff --git a/src/widgets/vsimplearc.h b/src/app/widgets/vsimplearc.h similarity index 100% rename from src/widgets/vsimplearc.h rename to src/app/widgets/vsimplearc.h diff --git a/src/widgets/vsimplespline.cpp b/src/app/widgets/vsimplespline.cpp similarity index 100% rename from src/widgets/vsimplespline.cpp rename to src/app/widgets/vsimplespline.cpp diff --git a/src/widgets/vsimplespline.h b/src/app/widgets/vsimplespline.h similarity index 100% rename from src/widgets/vsimplespline.h rename to src/app/widgets/vsimplespline.h diff --git a/src/widgets/vsimplesplinepath.cpp b/src/app/widgets/vsimplesplinepath.cpp similarity index 100% rename from src/widgets/vsimplesplinepath.cpp rename to src/app/widgets/vsimplesplinepath.cpp diff --git a/src/widgets/vsimplesplinepath.h b/src/app/widgets/vsimplesplinepath.h similarity index 100% rename from src/widgets/vsimplesplinepath.h rename to src/app/widgets/vsimplesplinepath.h diff --git a/src/widgets/vtablegraphicsview.cpp b/src/app/widgets/vtablegraphicsview.cpp similarity index 100% rename from src/widgets/vtablegraphicsview.cpp rename to src/app/widgets/vtablegraphicsview.cpp diff --git a/src/widgets/vtablegraphicsview.h b/src/app/widgets/vtablegraphicsview.h similarity index 100% rename from src/widgets/vtablegraphicsview.h rename to src/app/widgets/vtablegraphicsview.h diff --git a/src/app/widgets/widgets.pri b/src/app/widgets/widgets.pri new file mode 100644 index 000000000..e8e5343b5 --- /dev/null +++ b/src/app/widgets/widgets.pri @@ -0,0 +1,27 @@ +HEADERS += \ + widgets/vtablegraphicsview.h \ + widgets/vmaingraphicsview.h \ + widgets/vmaingraphicsscene.h \ + widgets/vitem.h \ + widgets/vgraphicssimpletextitem.h \ + widgets/vcontrolpointspline.h \ + widgets/vapplication.h \ + widgets/doubledelegate.h \ + widgets/vsimplespline.h \ + widgets/vsimplesplinepath.h \ + widgets/vsimplearc.h \ + widgets/textdelegate.h + +SOURCES += \ + widgets/vtablegraphicsview.cpp \ + widgets/vmaingraphicsview.cpp \ + widgets/vmaingraphicsscene.cpp \ + widgets/vitem.cpp \ + widgets/vgraphicssimpletextitem.cpp \ + widgets/vcontrolpointspline.cpp \ + widgets/vapplication.cpp \ + widgets/doubledelegate.cpp \ + widgets/vsimplespline.cpp \ + widgets/vsimplesplinepath.cpp \ + widgets/vsimplearc.cpp \ + widgets/textdelegate.cpp diff --git a/src/xml/vdomdocument.cpp b/src/app/xml/vdomdocument.cpp similarity index 100% rename from src/xml/vdomdocument.cpp rename to src/app/xml/vdomdocument.cpp diff --git a/src/xml/vdomdocument.h b/src/app/xml/vdomdocument.h similarity index 100% rename from src/xml/vdomdocument.h rename to src/app/xml/vdomdocument.h diff --git a/src/xml/vindividualmeasurements.cpp b/src/app/xml/vindividualmeasurements.cpp similarity index 100% rename from src/xml/vindividualmeasurements.cpp rename to src/app/xml/vindividualmeasurements.cpp diff --git a/src/xml/vindividualmeasurements.h b/src/app/xml/vindividualmeasurements.h similarity index 100% rename from src/xml/vindividualmeasurements.h rename to src/app/xml/vindividualmeasurements.h diff --git a/src/xml/vpattern.cpp b/src/app/xml/vpattern.cpp similarity index 100% rename from src/xml/vpattern.cpp rename to src/app/xml/vpattern.cpp diff --git a/src/xml/vpattern.h b/src/app/xml/vpattern.h similarity index 100% rename from src/xml/vpattern.h rename to src/app/xml/vpattern.h diff --git a/src/xml/vstandardmeasurements.cpp b/src/app/xml/vstandardmeasurements.cpp similarity index 100% rename from src/xml/vstandardmeasurements.cpp rename to src/app/xml/vstandardmeasurements.cpp diff --git a/src/xml/vstandardmeasurements.h b/src/app/xml/vstandardmeasurements.h similarity index 100% rename from src/xml/vstandardmeasurements.h rename to src/app/xml/vstandardmeasurements.h diff --git a/src/xml/vtoolrecord.cpp b/src/app/xml/vtoolrecord.cpp similarity index 100% rename from src/xml/vtoolrecord.cpp rename to src/app/xml/vtoolrecord.cpp diff --git a/src/xml/vtoolrecord.h b/src/app/xml/vtoolrecord.h similarity index 100% rename from src/xml/vtoolrecord.h rename to src/app/xml/vtoolrecord.h diff --git a/src/app/xml/xml.pri b/src/app/xml/xml.pri new file mode 100644 index 000000000..d9b56eea9 --- /dev/null +++ b/src/app/xml/xml.pri @@ -0,0 +1,13 @@ +HEADERS += \ + xml/vtoolrecord.h \ + xml/vdomdocument.h \ + xml/vpattern.h \ + xml/vstandardmeasurements.h \ + xml/vindividualmeasurements.h + +SOURCES += \ + xml/vtoolrecord.cpp \ + xml/vdomdocument.cpp \ + xml/vpattern.cpp \ + xml/vstandardmeasurements.cpp \ + xml/vindividualmeasurements.cpp diff --git a/src/container/container.pri b/src/container/container.pri deleted file mode 100644 index fcd3ba862..000000000 --- a/src/container/container.pri +++ /dev/null @@ -1,11 +0,0 @@ -SOURCES += \ - src/container/vcontainer.cpp \ - src/container/calculator.cpp \ - src/container/vmeasurement.cpp \ - src/container/vincrement.cpp - -HEADERS += \ - src/container/vcontainer.h \ - src/container/calculator.h \ - src/container/vmeasurement.h \ - src/container/vincrement.h diff --git a/src/dialogs/dialogs.pri b/src/dialogs/dialogs.pri deleted file mode 100644 index 99388667c..000000000 --- a/src/dialogs/dialogs.pri +++ /dev/null @@ -1,90 +0,0 @@ -HEADERS += \ - src/dialogs/dialogs.h \ - src/dialogs/tools/dialogtriangle.h \ - src/dialogs/tools/dialogtool.h \ - src/dialogs/tools/dialogsplinepath.h \ - src/dialogs/tools/dialogspline.h \ - src/dialogs/tools/dialogsinglepoint.h \ - src/dialogs/tools/dialogshoulderpoint.h \ - src/dialogs/tools/dialogpointofintersection.h \ - src/dialogs/tools/dialogpointofcontact.h \ - src/dialogs/tools/dialognormal.h \ - src/dialogs/tools/dialoglineintersect.h \ - src/dialogs/tools/dialogline.h \ - src/dialogs/tools/dialogheight.h \ - src/dialogs/tools/dialogendline.h \ - src/dialogs/tools/dialogdetail.h \ - src/dialogs/tools/dialogbisector.h \ - src/dialogs/tools/dialogarc.h \ - src/dialogs/tools/dialogalongline.h \ - src/dialogs/tools/dialogcutspline.h \ - src/dialogs/tools/dialogcutsplinepath.h \ - src/dialogs/tools/dialoguniondetails.h \ - src/dialogs/tools/dialogcutarc.h \ - src/dialogs/app/dialogincrements.h \ - src/dialogs/app/dialoghistory.h \ - src/dialogs/app/configdialog.h \ - src/dialogs/app/pages.h \ - src/dialogs/app/dialogpatternproperties.h \ - src/dialogs/app/dialogmeasurements.h \ - src/dialogs/app/dialogstandardmeasurements.h \ - src/dialogs/app/dialogindividualmeasurements.h - -SOURCES += \ - src/dialogs/tools/dialogtriangle.cpp \ - src/dialogs/tools/dialogtool.cpp \ - src/dialogs/tools/dialogsplinepath.cpp \ - src/dialogs/tools/dialogspline.cpp \ - src/dialogs/tools/dialogsinglepoint.cpp \ - src/dialogs/tools/dialogshoulderpoint.cpp \ - src/dialogs/tools/dialogpointofintersection.cpp \ - src/dialogs/tools/dialogpointofcontact.cpp \ - src/dialogs/tools/dialognormal.cpp \ - src/dialogs/tools/dialoglineintersect.cpp \ - src/dialogs/tools/dialogline.cpp \ - src/dialogs/tools/dialogheight.cpp \ - src/dialogs/tools/dialogendline.cpp \ - src/dialogs/tools/dialogdetail.cpp \ - src/dialogs/tools/dialogbisector.cpp \ - src/dialogs/tools/dialogarc.cpp \ - src/dialogs/tools/dialogalongline.cpp \ - src/dialogs/tools/dialogcutspline.cpp \ - src/dialogs/tools/dialogcutsplinepath.cpp \ - src/dialogs/tools/dialoguniondetails.cpp \ - src/dialogs/tools/dialogcutarc.cpp \ - src/dialogs/app/dialogincrements.cpp \ - src/dialogs/app/dialoghistory.cpp \ - src/dialogs/app/configdialog.cpp \ - src/dialogs/app/pages.cpp \ - src/dialogs/app/dialogpatternproperties.cpp \ - src/dialogs/app/dialogmeasurements.cpp \ - src/dialogs/app/dialogstandardmeasurements.cpp \ - src/dialogs/app/dialogindividualmeasurements.cpp - -FORMS += \ - src/dialogs/tools/dialogtriangle.ui \ - src/dialogs/tools/dialogsplinepath.ui \ - src/dialogs/tools/dialogspline.ui \ - src/dialogs/tools/dialogsinglepoint.ui \ - src/dialogs/tools/dialogshoulderpoint.ui \ - src/dialogs/tools/dialogpointofintersection.ui \ - src/dialogs/tools/dialogpointofcontact.ui \ - src/dialogs/tools/dialognormal.ui \ - src/dialogs/tools/dialoglineintersect.ui \ - src/dialogs/tools/dialogline.ui \ - src/dialogs/tools/dialogheight.ui \ - src/dialogs/tools/dialogendline.ui \ - src/dialogs/tools/dialogdetail.ui \ - src/dialogs/tools/dialogbisector.ui \ - src/dialogs/tools/dialogarc.ui \ - src/dialogs/tools/dialogalongline.ui \ - src/dialogs/tools/dialogcutspline.ui \ - src/dialogs/tools/dialogcutsplinepath.ui \ - src/dialogs/tools/dialoguniondetails.ui \ - src/dialogs/tools/dialogcutarc.ui \ - src/dialogs/app/dialogincrements.ui \ - src/dialogs/app/dialoghistory.ui \ - src/dialogs/app/dialogpatternproperties.ui \ - src/dialogs/app/dialogmeasurements.ui \ - src/dialogs/app/dialogstandardmeasurements.ui \ - src/dialogs/app/dialogindividualmeasurements.ui diff --git a/src/exception/exception.pri b/src/exception/exception.pri deleted file mode 100644 index a743115fc..000000000 --- a/src/exception/exception.pri +++ /dev/null @@ -1,15 +0,0 @@ -HEADERS += \ - src/exception/vexceptionobjecterror.h \ - src/exception/vexceptionemptyparameter.h \ - src/exception/vexceptionconversionerror.h \ - src/exception/vexceptionbadid.h \ - src/exception/vexception.h \ - src/exception/vexceptionwrongid.h - -SOURCES += \ - src/exception/vexceptionobjecterror.cpp \ - src/exception/vexceptionemptyparameter.cpp \ - src/exception/vexceptionconversionerror.cpp \ - src/exception/vexceptionbadid.cpp \ - src/exception/vexception.cpp \ - src/exception/vexceptionwrongid.cpp diff --git a/src/geometry/geometry.pri b/src/geometry/geometry.pri deleted file mode 100644 index 40815e6cf..000000000 --- a/src/geometry/geometry.pri +++ /dev/null @@ -1,21 +0,0 @@ -HEADERS += \ - src/geometry/vsplinepoint.h \ - src/geometry/vsplinepath.h \ - src/geometry/vspline.h \ - src/geometry/vnodedetail.h \ - src/geometry/vdetail.h \ - src/geometry/varc.h \ - src/geometry/vgobject.h \ - src/geometry/vpointf.h \ - src/geometry/vequidistant.h - -SOURCES += \ - src/geometry/vsplinepoint.cpp \ - src/geometry/vsplinepath.cpp \ - src/geometry/vspline.cpp \ - src/geometry/vnodedetail.cpp \ - src/geometry/vdetail.cpp \ - src/geometry/varc.cpp \ - src/geometry/vgobject.cpp \ - src/geometry/vpointf.cpp \ - src/geometry/vequidistant.cpp diff --git a/src/src.pri b/src/src.pri deleted file mode 100644 index 31e8d0c14..000000000 --- a/src/src.pri +++ /dev/null @@ -1,14 +0,0 @@ -SOURCES += src/main.cpp \ - src/mainwindow.cpp \ - src/tablewindow.cpp \ - src/stable.cpp \ - src/version.cpp - -HEADERS += src/mainwindow.h \ - src/options.h \ - src/tablewindow.h \ - src/stable.h \ - src/version.h - -FORMS += src/mainwindow.ui \ - src/tablewindow.ui diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 000000000..7a8600add --- /dev/null +++ b/src/src.pro @@ -0,0 +1,50 @@ +TEMPLATE = subdirs +#SUBDIRS = sub_lib sub_tests sub_app +SUBDIRS = sub_app + +#sub_lib.subdir = lib +#sub_tests.file = tests/proj.pro +#sub_tests.depends = sub_lib +sub_app.subdir = app +sub_app.file = app/app.pro +#sub_app.depends = sub_lib + +#This makes it possible to use make -j 4 on your fancy quad-core system with a project that consists of several +#components that depend on each other. To simplify the process a bit, the following test function can be defined: + +# addSubdirs(subdirs,deps): Adds directories to the project that depend on +# other directories +defineTest(addSubdirs) { + for(subdirs, 1) { + entries = $$files($$subdirs) + for(entry, entries) { + name = $$replace(entry, [/\\\\], _) + SUBDIRS += $$name + eval ($${name}.subdir = $$entry) + for(dep, 2):eval ($${name}.depends += $$replace(dep, [/\\\\], _)) + export ($${name}.subdir) + export ($${name}.depends) + } + } + export (SUBDIRS) +} +#You can then use it like to define a project that has: + +#several contributed modules that should be compiled first +#addSubdirs (contrib/*) + +#a kernel lib for non-gui related stuff that depends on some contrib modules +#addSubdirs (src/lib/kernel, contrib/module1 contrib/module2) + +#a gui lib that depends on the kernel lib and some other contrib modules +#addSubdirs (src/lib/gui, src/lib/kernel contrib/module3 contrib/module4) + +#test benches for the kernel and gui libs +#addSubdirs (src/tests/kernel, src/lib/kernel) +#addSubdirs (src/tests/gui, src/lib/gui) + +#a main program that uses the gui and kernel libs +#addSubdirs (src/main, src/lib/gui src/lib/kernel) + +#several modules that only depend on the kernel lib +#addSubdirs (src/modules/*, src/lib/kernel) diff --git a/src/tools/tools.pri b/src/tools/tools.pri deleted file mode 100644 index 6e5924a6a..000000000 --- a/src/tools/tools.pri +++ /dev/null @@ -1,68 +0,0 @@ -HEADERS += \ - src/tools/vtooldetail.h \ - src/tools/vdatatool.h \ - src/tools/vabstracttool.h \ - src/tools/tools.h \ - src/tools/drawTools/vtooltriangle.h \ - src/tools/drawTools/vtoolsplinepath.h \ - src/tools/drawTools/vtoolspline.h \ - src/tools/drawTools/vtoolsinglepoint.h \ - src/tools/drawTools/vtoolshoulderpoint.h \ - src/tools/drawTools/vtoolpointofintersection.h \ - src/tools/drawTools/vtoolpointofcontact.h \ - src/tools/drawTools/vtoolpoint.h \ - src/tools/drawTools/vtoolnormal.h \ - src/tools/drawTools/vtoollinepoint.h \ - src/tools/drawTools/vtoollineintersect.h \ - src/tools/drawTools/vtoolline.h \ - src/tools/drawTools/vtoolheight.h \ - src/tools/drawTools/vtoolendline.h \ - src/tools/drawTools/vtoolbisector.h \ - src/tools/drawTools/vtoolarc.h \ - src/tools/drawTools/vtoolalongline.h \ - src/tools/drawTools/vdrawtool.h \ - src/tools/drawTools/drawtools.h \ - src/tools/nodeDetails/vnodesplinepath.h \ - src/tools/nodeDetails/vnodespline.h \ - src/tools/nodeDetails/vnodepoint.h \ - src/tools/nodeDetails/vnodearc.h \ - src/tools/nodeDetails/vabstractnode.h \ - src/tools/nodeDetails/nodedetails.h \ - src/tools/drawTools/vtoolcutspline.h \ - src/tools/drawTools/vtoolcutsplinepath.h \ - src/tools/vtooluniondetails.h \ - src/tools/drawTools/vtoolcutarc.h \ - src/tools/drawTools/vabstractspline.h - -SOURCES += \ - src/tools/vtooldetail.cpp \ - src/tools/vdatatool.cpp \ - src/tools/vabstracttool.cpp \ - src/tools/drawTools/vtooltriangle.cpp \ - src/tools/drawTools/vtoolsplinepath.cpp \ - src/tools/drawTools/vtoolspline.cpp \ - src/tools/drawTools/vtoolsinglepoint.cpp \ - src/tools/drawTools/vtoolshoulderpoint.cpp \ - src/tools/drawTools/vtoolpointofintersection.cpp \ - src/tools/drawTools/vtoolpointofcontact.cpp \ - src/tools/drawTools/vtoolpoint.cpp \ - src/tools/drawTools/vtoolnormal.cpp \ - src/tools/drawTools/vtoollinepoint.cpp \ - src/tools/drawTools/vtoollineintersect.cpp \ - src/tools/drawTools/vtoolline.cpp \ - src/tools/drawTools/vtoolheight.cpp \ - src/tools/drawTools/vtoolendline.cpp \ - src/tools/drawTools/vtoolbisector.cpp \ - src/tools/drawTools/vtoolarc.cpp \ - src/tools/drawTools/vtoolalongline.cpp \ - src/tools/drawTools/vdrawtool.cpp \ - src/tools/nodeDetails/vnodesplinepath.cpp \ - src/tools/nodeDetails/vnodespline.cpp \ - src/tools/nodeDetails/vnodepoint.cpp \ - src/tools/nodeDetails/vnodearc.cpp \ - src/tools/nodeDetails/vabstractnode.cpp \ - src/tools/drawTools/vtoolcutspline.cpp \ - src/tools/drawTools/vtoolcutsplinepath.cpp \ - src/tools/vtooluniondetails.cpp \ - src/tools/drawTools/vtoolcutarc.cpp \ - src/tools/drawTools/vabstractspline.cpp diff --git a/src/widgets/widgets.pri b/src/widgets/widgets.pri deleted file mode 100644 index afb5dceab..000000000 --- a/src/widgets/widgets.pri +++ /dev/null @@ -1,27 +0,0 @@ -HEADERS += \ - src/widgets/vtablegraphicsview.h \ - src/widgets/vmaingraphicsview.h \ - src/widgets/vmaingraphicsscene.h \ - src/widgets/vitem.h \ - src/widgets/vgraphicssimpletextitem.h \ - src/widgets/vcontrolpointspline.h \ - src/widgets/vapplication.h \ - src/widgets/doubledelegate.h \ - src/widgets/vsimplespline.h \ - src/widgets/vsimplesplinepath.h \ - src/widgets/vsimplearc.h \ - src/widgets/textdelegate.h - -SOURCES += \ - src/widgets/vtablegraphicsview.cpp \ - src/widgets/vmaingraphicsview.cpp \ - src/widgets/vmaingraphicsscene.cpp \ - src/widgets/vitem.cpp \ - src/widgets/vgraphicssimpletextitem.cpp \ - src/widgets/vcontrolpointspline.cpp \ - src/widgets/vapplication.cpp \ - src/widgets/doubledelegate.cpp \ - src/widgets/vsimplespline.cpp \ - src/widgets/vsimplesplinepath.cpp \ - src/widgets/vsimplearc.cpp \ - src/widgets/textdelegate.cpp diff --git a/src/xml/xml.pri b/src/xml/xml.pri deleted file mode 100644 index fd858fb2b..000000000 --- a/src/xml/xml.pri +++ /dev/null @@ -1,13 +0,0 @@ -HEADERS += \ - src/xml/vtoolrecord.h \ - src/xml/vdomdocument.h \ - src/xml/vpattern.h \ - src/xml/vstandardmeasurements.h \ - src/xml/vindividualmeasurements.h - -SOURCES += \ - src/xml/vtoolrecord.cpp \ - src/xml/vdomdocument.cpp \ - src/xml/vpattern.cpp \ - src/xml/vstandardmeasurements.cpp \ - src/xml/vindividualmeasurements.cpp From 0b4d69f8216acbb757ba9aa03f9a5c0d9842256a Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 25 Apr 2014 15:58:14 +0300 Subject: [PATCH 02/26] Successful build after adding muParser library. --HG-- branch : feature --- src/app/app.pro | 6 + src/app/stable.h | 6 +- src/libs/qmuparser/License.txt | 29 + src/libs/qmuparser/doc/Doxyfile | 1563 ++++++++++++++++ src/libs/qmuparser/qmuparser.cpp | 383 ++++ src/libs/qmuparser/qmuparser.h | 110 ++ src/libs/qmuparser/qmuparser.pro | 112 ++ src/libs/qmuparser/qmuparser_global.h | 34 + src/libs/qmuparser/qmuparserbase.cpp | 1772 +++++++++++++++++++ src/libs/qmuparser/qmuparserbase.h | 309 ++++ src/libs/qmuparser/qmuparserbytecode.cpp | 583 ++++++ src/libs/qmuparser/qmuparserbytecode.h | 139 ++ src/libs/qmuparser/qmuparsercallback.cpp | 460 +++++ src/libs/qmuparser/qmuparsercallback.h | 115 ++ src/libs/qmuparser/qmuparserdef.h | 366 ++++ src/libs/qmuparser/qmuparsererror.cpp | 334 ++++ src/libs/qmuparser/qmuparsererror.h | 171 ++ src/libs/qmuparser/qmuparserfixes.h | 59 + src/libs/qmuparser/qmuparserint.cpp | 277 +++ src/libs/qmuparser/qmuparserint.h | 132 ++ src/libs/qmuparser/qmuparserstack.h | 122 ++ src/libs/qmuparser/qmuparsertemplatemagic.h | 150 ++ src/libs/qmuparser/qmuparsertest.cpp | 1447 +++++++++++++++ src/libs/qmuparser/qmuparsertest.h | 207 +++ src/libs/qmuparser/qmuparsertoken.h | 396 +++++ src/libs/qmuparser/qmuparsertokenreader.cpp | 953 ++++++++++ src/libs/qmuparser/qmuparsertokenreader.h | 158 ++ src/libs/qmuparser/stable.cpp | 30 + src/libs/qmuparser/stable.h | 46 + src/src.pro | 9 +- 30 files changed, 10471 insertions(+), 7 deletions(-) create mode 100644 src/libs/qmuparser/License.txt create mode 100644 src/libs/qmuparser/doc/Doxyfile create mode 100644 src/libs/qmuparser/qmuparser.cpp create mode 100644 src/libs/qmuparser/qmuparser.h create mode 100644 src/libs/qmuparser/qmuparser.pro create mode 100644 src/libs/qmuparser/qmuparser_global.h create mode 100644 src/libs/qmuparser/qmuparserbase.cpp create mode 100644 src/libs/qmuparser/qmuparserbase.h create mode 100644 src/libs/qmuparser/qmuparserbytecode.cpp create mode 100644 src/libs/qmuparser/qmuparserbytecode.h create mode 100644 src/libs/qmuparser/qmuparsercallback.cpp create mode 100644 src/libs/qmuparser/qmuparsercallback.h create mode 100644 src/libs/qmuparser/qmuparserdef.h create mode 100644 src/libs/qmuparser/qmuparsererror.cpp create mode 100644 src/libs/qmuparser/qmuparsererror.h create mode 100644 src/libs/qmuparser/qmuparserfixes.h create mode 100644 src/libs/qmuparser/qmuparserint.cpp create mode 100644 src/libs/qmuparser/qmuparserint.h create mode 100644 src/libs/qmuparser/qmuparserstack.h create mode 100644 src/libs/qmuparser/qmuparsertemplatemagic.h create mode 100644 src/libs/qmuparser/qmuparsertest.cpp create mode 100644 src/libs/qmuparser/qmuparsertest.h create mode 100644 src/libs/qmuparser/qmuparsertoken.h create mode 100644 src/libs/qmuparser/qmuparsertokenreader.cpp create mode 100644 src/libs/qmuparser/qmuparsertokenreader.h create mode 100644 src/libs/qmuparser/stable.cpp create mode 100644 src/libs/qmuparser/stable.h diff --git a/src/app/app.pro b/src/app/app.pro index f691e6641..797def619 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -232,3 +232,9 @@ for(DIR, INSTALL_INDIVIDUAL_MEASHUREMENTS) { copyToDestdir($$ind_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/individual)) +win32:CONFIG(release, debug|release): LIBS += -L../libs/qmuparser/bin -lqmuparser +else:win32:CONFIG(debug, debug|release): LIBS += -L../libs/qmuparser/bin -lqmuparser +else:unix: LIBS += -L../libs/qmuparser/bin -lqmuparser + +INCLUDEPATH += ../libs/qmuparser +DEPENDPATH += ../libs/qmuparser diff --git a/src/app/stable.h b/src/app/stable.h index d220aab6a..3e556d0ab 100644 --- a/src/app/stable.h +++ b/src/app/stable.h @@ -29,10 +29,8 @@ #ifndef STABLE_H #define STABLE_H -/* I like to include this pragma too, -so the build log indicates if pre-compiled headers -were in use. */ -#pragma message("Compiling precompiled headers.\n") +/* I like to include this pragma too, so the build log indicates if pre-compiled headers were in use. */ +#pragma message("Compiling precompiled headers for Valentina.\n") /* Add C includes here */ diff --git a/src/libs/qmuparser/License.txt b/src/libs/qmuparser/License.txt new file mode 100644 index 000000000..c66f0cbce --- /dev/null +++ b/src/libs/qmuparser/License.txt @@ -0,0 +1,29 @@ +####################################################################### +# # +# # +# Fast math parser Library # +# # +# Copyright (C) 2011 Ingo Berg # +# # +# Web: muparser.beltoforion.de # +# e-mail: muparser@beltoforion.de # +# # +# # +####################################################################### + + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libs/qmuparser/doc/Doxyfile b/src/libs/qmuparser/doc/Doxyfile new file mode 100644 index 000000000..b5903a675 --- /dev/null +++ b/src/libs/qmuparser/doc/Doxyfile @@ -0,0 +1,1563 @@ +# Doxyfile 1.6.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "qmuParser API -" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.35 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = html/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 16 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = html/misc/Main.txt \ + html/misc/example.txt \ + ../src/ \ + ../include/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = html/misc/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = NO + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = classdocu/ + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = html/misc/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = jpg + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = "C:\Program Files (x86)\Graphviz2.20\bin" + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp new file mode 100644 index 000000000..8d24a909e --- /dev/null +++ b/src/libs/qmuparser/qmuparser.cpp @@ -0,0 +1,383 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparser.h" +#include "qmuparsertemplatemagic.h" + +//--- Standard includes ------------------------------------------------------------------------ +#include +#include +#include + +/** \brief Pi (what else?). */ +#define QmuParser_CONST_PI 3.141592653589793238462643 + +/** \brief The eulerian number. */ +#define QmuParser_CONST_E 2.718281828459045235360287 + +using namespace std; + +/** \file + \brief Implementation of the standard floating point QmuParser. +*/ + + + +/** \brief Namespace for mathematical applications. */ +namespace qmu +{ + + + //--------------------------------------------------------------------------- + // Trigonometric function + value_type QmuParser::Sin(value_type v) { return MathImpl::Sin(v); } + value_type QmuParser::Cos(value_type v) { return MathImpl::Cos(v); } + value_type QmuParser::Tan(value_type v) { return MathImpl::Tan(v); } + value_type QmuParser::ASin(value_type v) { return MathImpl::ASin(v); } + value_type QmuParser::ACos(value_type v) { return MathImpl::ACos(v); } + value_type QmuParser::ATan(value_type v) { return MathImpl::ATan(v); } + value_type QmuParser::ATan2(value_type v1, value_type v2) { return MathImpl::ATan2(v1, v2); } + value_type QmuParser::Sinh(value_type v) { return MathImpl::Sinh(v); } + value_type QmuParser::Cosh(value_type v) { return MathImpl::Cosh(v); } + value_type QmuParser::Tanh(value_type v) { return MathImpl::Tanh(v); } + value_type QmuParser::ASinh(value_type v) { return MathImpl::ASinh(v); } + value_type QmuParser::ACosh(value_type v) { return MathImpl::ACosh(v); } + value_type QmuParser::ATanh(value_type v) { return MathImpl::ATanh(v); } + + //--------------------------------------------------------------------------- + // Logarithm functions + + // Logarithm base 2 + value_type QmuParser::Log2(value_type v) + { + #ifdef MUP_MATH_EXCEPTIONS + if (v<=0) + throw QmuParserError(ecDOMAIN_ERROR, _T("Log2")); + #endif + + return MathImpl::Log2(v); + } + + // Logarithm base 10 + value_type QmuParser::Log10(value_type v) + { + #ifdef MUP_MATH_EXCEPTIONS + if (v<=0) + throw QmuParserError(ecDOMAIN_ERROR, _T("Log10")); + #endif + + return MathImpl::Log10(v); + } + +// Logarithm base e (natural logarithm) + value_type QmuParser::Ln(value_type v) + { + #ifdef MUP_MATH_EXCEPTIONS + if (v<=0) + throw QmuParserError(ecDOMAIN_ERROR, _T("Ln")); + #endif + + return MathImpl::Log(v); + } + + //--------------------------------------------------------------------------- + // misc + value_type QmuParser::Exp(value_type v) { return MathImpl::Exp(v); } + value_type QmuParser::Abs(value_type v) { return MathImpl::Abs(v); } + value_type QmuParser::Sqrt(value_type v) + { + #ifdef MUP_MATH_EXCEPTIONS + if (v<0) + throw QmuParserError(ecDOMAIN_ERROR, _T("sqrt")); + #endif + + return MathImpl::Sqrt(v); + } + value_type QmuParser::Rint(value_type v) { return MathImpl::Rint(v); } + value_type QmuParser::Sign(value_type v) { return MathImpl::Sign(v); } + + //--------------------------------------------------------------------------- + /** \brief Callback for the unary minus operator. + \param v The value to negate + \return -v + */ + value_type QmuParser::UnaryMinus(value_type v) + { + return -v; + } + + //--------------------------------------------------------------------------- + /** \brief Callback for adding multiple values. + \param [in] a_afArg Vector with the function arguments + \param [in] a_iArgc The size of a_afArg + */ + value_type QmuParser::Sum(const value_type *a_afArg, int a_iArgc) + { + if (!a_iArgc) + throw exception_type(_T("too few arguments for function sum.")); + + value_type fRes=0; + for (int i=0; i> fVal; + stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading + + if (iEnd==(stringstream_type::pos_type)-1) + return 0; + + *a_iPos += (int)iEnd; + *a_fVal = fVal; + return 1; + } + + + //--------------------------------------------------------------------------- + /** \brief Constructor. + + Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization. + */ + QmuParser::QmuParser() + :QmuParserBase() + { + AddValIdent(IsVal); + + InitCharSets(); + InitFun(); + InitConst(); + InitOprt(); + } + + //--------------------------------------------------------------------------- + /** \brief Define the character sets. + \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars + + This function is used for initializing the default character sets that define + the characters to be useable in function and variable names and operators. + */ + void QmuParser::InitCharSets() + { + DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") ); + DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") ); + DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") ); + } + + //--------------------------------------------------------------------------- + /** \brief Initialize the default functions. */ + void QmuParser::InitFun() + { + if (qmu::TypeInfo::IsInteger()) + { + // When setting MUP_BASETYPE to an integer type + // Place functions for dealing with integer values here + // ... + // ... + // ... + } + else + { + // trigonometric functions + DefineFun(_T("sin"), Sin); + DefineFun(_T("cos"), Cos); + DefineFun(_T("tan"), Tan); + // arcus functions + DefineFun(_T("asin"), ASin); + DefineFun(_T("acos"), ACos); + DefineFun(_T("atan"), ATan); + DefineFun(_T("atan2"), ATan2); + // hyperbolic functions + DefineFun(_T("sinh"), Sinh); + DefineFun(_T("cosh"), Cosh); + DefineFun(_T("tanh"), Tanh); + // arcus hyperbolic functions + DefineFun(_T("asinh"), ASinh); + DefineFun(_T("acosh"), ACosh); + DefineFun(_T("atanh"), ATanh); + // Logarithm functions + DefineFun(_T("log2"), Log2); + DefineFun(_T("log10"), Log10); + DefineFun(_T("log"), Log10); + DefineFun(_T("ln"), Ln); + // misc + DefineFun(_T("exp"), Exp); + DefineFun(_T("sqrt"), Sqrt); + DefineFun(_T("sign"), Sign); + DefineFun(_T("rint"), Rint); + DefineFun(_T("abs"), Abs); + // Functions with variable number of arguments + DefineFun(_T("sum"), Sum); + DefineFun(_T("avg"), Avg); + DefineFun(_T("min"), Min); + DefineFun(_T("max"), Max); + } + } + + //--------------------------------------------------------------------------- + /** \brief Initialize constants. + + By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian + number ("_e"). + */ + void QmuParser::InitConst() + { + DefineConst(_T("_pi"), (value_type)QmuParser_CONST_PI); + DefineConst(_T("_e"), (value_type)QmuParser_CONST_E); + } + + //--------------------------------------------------------------------------- + /** \brief Initialize operators. + + By default only the unary minus operator is added. + */ + void QmuParser::InitOprt() + { + DefineInfixOprt(_T("-"), UnaryMinus); + } + + //--------------------------------------------------------------------------- + void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) + { + // this is just sample code to illustrate modifying variable names on the fly. + // I'm not sure anyone really needs such a feature... + /* + + + string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd); + string sRepl = std::string("_") + sVar + "_"; + + int nOrigVarEnd = nEnd; + cout << "variable detected!\n"; + cout << " Expr: " << *pExpr << "\n"; + cout << " Start: " << nStart << "\n"; + cout << " End: " << nEnd << "\n"; + cout << " Var: \"" << sVar << "\"\n"; + cout << " Repl: \"" << sRepl << "\"\n"; + nEnd = nStart + sRepl.length(); + cout << " End: " << nEnd << "\n"; + pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl); + cout << " New expr: " << *pExpr << "\n"; + */ + } + + //--------------------------------------------------------------------------- + /** \brief Numerically differentiate with regard to a variable. + \param [in] a_Var Pointer to the differentiation variable. + \param [in] a_fPos Position at which the differentiation should take place. + \param [in] a_fEpsilon Epsilon used for the numerical differentiation. + + Numerical differentiation uses a 5 point operator yielding a 4th order + formula. The default value for epsilon is 0.00074 which is + numeric_limits::epsilon() ^ (1/5) as suggested in the muQmuParser + forum: + + http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 + */ + value_type QmuParser::Diff(value_type *a_Var, + value_type a_fPos, + value_type a_fEpsilon) const + { + value_type fRes(0), + fBuf(*a_Var), + f[4] = {0,0,0,0}, + fEpsilon(a_fEpsilon); + + // Backwards compatible calculation of epsilon inc case the user doesnt provide + // his own epsilon + if (fEpsilon==0) + fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos; + + *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); + *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); + *a_Var = a_fPos-1 * fEpsilon; f[2] = Eval(); + *a_Var = a_fPos-2 * fEpsilon; f[3] = Eval(); + *a_Var = fBuf; // restore variable + + fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon); + return fRes; + } +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h new file mode 100644 index 000000000..07a1b8c3a --- /dev/null +++ b/src/libs/qmuparser/qmuparser.h @@ -0,0 +1,110 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSER_H +#define QMUPARSER_H + +#include "qmuparser_global.h" + +//--- Standard includes ------------------------------------------------------------------------ +#include + +//--- Parser includes -------------------------------------------------------------------------- +#include "qmuparserbase.h" +#include "qmuparsertemplatemagic.h" + +/** \file + \brief Definition of the standard floating point parser. +*/ + +namespace qmu +{ + /** \brief Mathematical expressions parser. + + Standard implementation of the mathematical expressions parser. + Can be used as a reference implementation for subclassing the parser. + + + (C) 2011 Ingo Berg
+ muparser(at)gmx.de +
+ */ +/* final */ class QMUPARSERSHARED_EXPORT QmuParser : public QmuParserBase +{ + +public: + QmuParser(); + virtual void InitCharSets(); + virtual void InitFun(); + virtual void InitConst(); + virtual void InitOprt(); + virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + + value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon = 0) const; +protected: + + // Trigonometric functions + static value_type Sin(value_type); + static value_type Cos(value_type); + static value_type Tan(value_type); + static value_type Tan2(value_type, value_type); + // arcus functions + static value_type ASin(value_type); + static value_type ACos(value_type); + static value_type ATan(value_type); + static value_type ATan2(value_type, value_type); + + // hyperbolic functions + static value_type Sinh(value_type); + static value_type Cosh(value_type); + static value_type Tanh(value_type); + // arcus hyperbolic functions + static value_type ASinh(value_type); + static value_type ACosh(value_type); + static value_type ATanh(value_type); + // Logarithm functions + static value_type Log2(value_type); // Logarithm Base 2 + static value_type Log10(value_type); // Logarithm Base 10 + static value_type Ln(value_type); // Logarithm Base e (natural logarithm) + // misc + static value_type Exp(value_type); + static value_type Abs(value_type); + static value_type Sqrt(value_type); + static value_type Rint(value_type); + static value_type Sign(value_type); + + // Prefix operators + // !!! Unary Minus is a MUST if you want to use negative signs !!! + static value_type UnaryMinus(value_type); + + // Functions with variable number of arguments + static value_type Sum(const value_type*, int); // sum + static value_type Avg(const value_type*, int); // mean value + static value_type Min(const value_type*, int); // minimum + static value_type Max(const value_type*, int); // maximum + + static int IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal); +}; + +} // namespace qmu + +#endif // QMUPARSER_H diff --git a/src/libs/qmuparser/qmuparser.pro b/src/libs/qmuparser/qmuparser.pro new file mode 100644 index 000000000..31b59f338 --- /dev/null +++ b/src/libs/qmuparser/qmuparser.pro @@ -0,0 +1,112 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-04-25T12:01:49 +# +#------------------------------------------------- + +QT -= gui + +TARGET = qmuparser +TEMPLATE = lib + +CONFIG -= debug_and_release debug_and_release_target +CONFIG += c++11 + +DEFINES += QMUPARSER_LIBRARY + +# directory for executable file +DESTDIR = bin + +# files created moc +MOC_DIR = moc + +# objecs files +OBJECTS_DIR = obj + +# files created rcc +RCC_DIR = rcc + +# files created uic +UI_DIR = uic + +SOURCES += \ + qmuparser.cpp \ + qmuparsertokenreader.cpp \ + qmuparsererror.cpp \ + qmuparsercallback.cpp \ + qmuparserbytecode.cpp \ + qmuparserbase.cpp \ + qmuparsertest.cpp \ + qmuparserint.cpp \ + stable.cpp + +HEADERS += \ + qmuparser.h\ + qmuparser_global.h \ + qmuparsertokenreader.h \ + qmuparsertoken.h \ + qmuparserstack.h \ + qmuparserfixes.h \ + qmuparsererror.h \ + qmuparserdef.h \ + qmuparsercallback.h \ + qmuparserbytecode.h \ + qmuparserbase.h \ + qmuparsertest.h \ + qmuparsertemplatemagic.h \ + qmuparserint.h \ + stable.h + +VERSION = 2.2.3 + +unix { + target.path = /usr/lib + INSTALLS += target + + QMAKE_CXX = ccache g++ +} + +CONFIG += precompile_header +# Precompiled headers (PCH) +PRECOMPILED_HEADER = stable.h +win32-msvc* { + PRECOMPILED_SOURCE = stable.cpp +} + +CONFIG(debug, debug|release){ + # Debug + unix { + *-g++{ + QMAKE_CXXFLAGS += -isystem "/usr/include/qt5" -isystem "/usr/include/qt5/QtCore" -isystem "$${UI_DIR}" \ + -isystem "$${MOC_DIR}" -isystem "$${RCC_DIR}" \ + -O0 -Wall -Wextra -pedantic -Weffc++ -Woverloaded-virtual -Wctor-dtor-privacy \ + -Wnon-virtual-dtor -Wold-style-cast -Wconversion -Winit-self -Wstack-protector \ + -Wunreachable-code -Wcast-align -Wcast-qual -Wdisabled-optimization -Wfloat-equal \ + -Wformat=2 -Wimport \ + -Winvalid-pch -Wunsafe-loop-optimizations -Wlong-long -Wmissing-format-attribute \ + -Wmissing-include-dirs -Wpacked -Wredundant-decls -Winline \ + -Wswitch-default -Wswitch-enum -Wuninitialized -Wvariadic-macros \ + -Wlogical-op -Wnoexcept -Wmissing-noreturn -Wpointer-arith\ + -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 + -ftrapv + } + } else { + *-g++{#Don't use additional GCC keys on Windows system. + QMAKE_CXXFLAGS += -O0 -Wall -Wextra -pedantic + } + } +}else{ + # Release + *-g++{ + QMAKE_CXXFLAGS += -O2 + } + + DEFINES += QT_NO_DEBUG_OUTPUT +} + +# Remove generated files at cleaning +QMAKE_DISTCLEAN += $${DESTDIR}/* \ + $${OBJECTS_DIR}/* \ + $${UI_DIR}/* \ + $${MOC_DIR}/* \ + $${RCC_DIR}/* diff --git a/src/libs/qmuparser/qmuparser_global.h b/src/libs/qmuparser/qmuparser_global.h new file mode 100644 index 000000000..c20d95488 --- /dev/null +++ b/src/libs/qmuparser/qmuparser_global.h @@ -0,0 +1,34 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSER_GLOBAL_H +#define QMUPARSER_GLOBAL_H + +#include + +#if defined(QMUPARSER_LIBRARY) +# define QMUPARSERSHARED_EXPORT Q_DECL_EXPORT +#else +# define QMUPARSERSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // QMUPARSER_GLOBAL_H diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp new file mode 100644 index 000000000..fa8a7c2a1 --- /dev/null +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -0,0 +1,1772 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparserbase.h" +#include "qmuparsertemplatemagic.h" + +//--- Standard includes ------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include +#include + +#ifdef QMUP_USE_OPENMP + #include +#endif + +using namespace std; + +/** \file + \brief This file contains the basic implementation of the muparser engine. +*/ + +namespace qmu +{ + std::locale QmuParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep('.')); + + bool QmuParserBase::g_DbgDumpCmdCode = false; + bool QmuParserBase::g_DbgDumpStack = false; + + //------------------------------------------------------------------------------ + /** \brief Identifiers for built in binary operators. + + When defining custom binary operators with #AddOprt(...) make sure not to choose + names conflicting with these definitions. + */ + const char_type* QmuParserBase::c_DefaultOprt[] = + { + _T("<="), _T(">="), _T("!="), + _T("=="), _T("<"), _T(">"), + _T("+"), _T("-"), _T("*"), + _T("/"), _T("^"), _T("&&"), + _T("||"), _T("="), _T("("), + _T(")"), _T("?"), _T(":"), 0 + }; + + //------------------------------------------------------------------------------ + /** \brief Constructor. + \param a_szFormula the formula to interpret. + \throw ParserException if a_szFormula is null. + */ + QmuParserBase::QmuParserBase() + :m_pParseFormula(&QmuParserBase::ParseString) + ,m_vRPN() + ,m_vStringBuf() + ,m_pTokenReader() + ,m_FunDef() + ,m_PostOprtDef() + ,m_InfixOprtDef() + ,m_OprtDef() + ,m_ConstDef() + ,m_StrVarDef() + ,m_VarDef() + ,m_bBuiltInOp(true) + ,m_sNameChars() + ,m_sOprtChars() + ,m_sInfixOprtChars() + ,m_nIfElseCounter(0) + ,m_vStackBuffer() + ,m_nFinalResultIdx(0) + { + InitTokenReader(); + } + + //--------------------------------------------------------------------------- + /** \brief Copy constructor. + + Tha parser can be safely copy constructed but the bytecode is reset during + copy construction. + */ + QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) + :m_pParseFormula(&QmuParserBase::ParseString) + ,m_vRPN() + ,m_vStringBuf() + ,m_pTokenReader() + ,m_FunDef() + ,m_PostOprtDef() + ,m_InfixOprtDef() + ,m_OprtDef() + ,m_ConstDef() + ,m_StrVarDef() + ,m_VarDef() + ,m_bBuiltInOp(true) + ,m_sNameChars() + ,m_sOprtChars() + ,m_sInfixOprtChars() + ,m_nIfElseCounter(0) + { + m_pTokenReader.reset(new token_reader_type(this)); + Assign(a_Parser); + } + + //--------------------------------------------------------------------------- + QmuParserBase::~QmuParserBase() + {} + + //--------------------------------------------------------------------------- + /** \brief Assignement operator. + + Implemented by calling Assign(a_Parser). Self assignement is suppressed. + \param a_Parser Object to copy to this. + \return *this + \throw nothrow + */ + QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) + { + Assign(a_Parser); + return *this; + } + + //--------------------------------------------------------------------------- + /** \brief Copy state of a parser object to this. + + Clears Variables and Functions of this parser. + Copies the states of all internal variables. + Resets parse function to string parse mode. + + \param a_Parser the source object. + */ + void QmuParserBase::Assign(const QmuParserBase &a_Parser) + { + if (&a_Parser==this) + return; + + // Don't copy bytecode instead cause the parser to create new bytecode + // by resetting the parse function. + ReInit(); + + m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants + m_VarDef = a_Parser.m_VarDef; // Copy user defined variables + m_bBuiltInOp = a_Parser.m_bBuiltInOp; + m_vStringBuf = a_Parser.m_vStringBuf; + m_vStackBuffer = a_Parser.m_vStackBuffer; + m_nFinalResultIdx = a_Parser.m_nFinalResultIdx; + m_StrVarDef = a_Parser.m_StrVarDef; + m_vStringVarBuf = a_Parser.m_vStringVarBuf; + m_nIfElseCounter = a_Parser.m_nIfElseCounter; + m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this)); + + // Copy function and operator callbacks + m_FunDef = a_Parser.m_FunDef; // Copy function definitions + m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators + m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation + m_OprtDef = a_Parser.m_OprtDef; // binary operators + + m_sNameChars = a_Parser.m_sNameChars; + m_sOprtChars = a_Parser.m_sOprtChars; + m_sInfixOprtChars = a_Parser.m_sInfixOprtChars; + } + + //--------------------------------------------------------------------------- + /** \brief Set the decimal separator. + \param cDecSep Decimal separator as a character value. + \sa SetThousandsSep + + By default muparser uses the "C" locale. The decimal separator of this + locale is overwritten by the one provided here. + */ + void QmuParserBase::SetDecSep(char_type cDecSep) + { + char_type cThousandsSep = std::use_facet< change_dec_sep >(s_locale).thousands_sep(); + s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); + } + + //--------------------------------------------------------------------------- + /** \brief Sets the thousands operator. + \param cThousandsSep The thousands separator as a character + \sa SetDecSep + + By default muparser uses the "C" locale. The thousands separator of this + locale is overwritten by the one provided here. + */ + void QmuParserBase::SetThousandsSep(char_type cThousandsSep) + { + char_type cDecSep = std::use_facet< change_dec_sep >(s_locale).decimal_point(); + s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); + } + + //--------------------------------------------------------------------------- + /** \brief Resets the locale. + + The default locale used "." as decimal separator, no thousands separator and + "," as function argument separator. + */ + void QmuParserBase::ResetLocale() + { + s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); + SetArgSep(','); + } + + //--------------------------------------------------------------------------- + /** \brief Initialize the token reader. + + Create new token reader object and submit pointers to function, operator, + constant and variable definitions. + + \post m_pTokenReader.get()!=0 + \throw nothrow + */ + void QmuParserBase::InitTokenReader() + { + m_pTokenReader.reset(new token_reader_type(this)); + } + + //--------------------------------------------------------------------------- + /** \brief Reset parser to string parsing mode and clear internal buffers. + + Clear bytecode, reset the token reader. + \throw nothrow + */ + void QmuParserBase::ReInit() const + { + m_pParseFormula = &QmuParserBase::ParseString; + m_vStringBuf.clear(); + m_vRPN.clear(); + m_pTokenReader->ReInit(); + m_nIfElseCounter = 0; + } + + //--------------------------------------------------------------------------- + void QmuParserBase::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) + {} + + //--------------------------------------------------------------------------- + /** \brief Returns the version of muparser. + \param eInfo A flag indicating whether the full version info should be + returned or not. + + Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS + are returned only if eInfo==pviFULL. + */ + string_type QmuParserBase::GetVersion(EParserVersionInfo eInfo) const + { + string_type sCompileTimeSettings; + + stringstream_type ss; + + ss << MUP_VERSION; + + if (eInfo==pviFULL) + { + ss << _T(" (") << MUP_VERSION_DATE; + ss << std::dec << _T("; ") << sizeof(void*)*8 << _T("BIT"); + +#ifdef _DEBUG + ss << _T("; DEBUG"); +#else + ss << _T("; RELEASE"); +#endif + +#ifdef _UNICODE + ss << _T("; UNICODE"); +#else + #ifdef _MBCS + ss << _T("; MBCS"); + #else + ss << _T("; ASCII"); + #endif +#endif + +#ifdef MUP_USE_OPENMP + ss << _T("; OPENMP"); +//#else +// ss << _T("; NO_OPENMP"); +#endif + +#if defined(MUP_MATH_EXCEPTIONS) + ss << _T("; MATHEXC"); +//#else +// ss << _T("; NO_MATHEXC"); +#endif + + ss << _T(")"); + } + + return ss.str(); + } + + //--------------------------------------------------------------------------- + /** \brief Add a value parsing function. + + When parsing an expression muParser tries to detect values in the expression + string using different valident callbacks. Thuis it's possible to parse + for hex values, binary values and floating point values. + */ + void QmuParserBase::AddValIdent(identfun_type a_pCallback) + { + m_pTokenReader->AddValIdent(a_pCallback); + } + + //--------------------------------------------------------------------------- + /** \brief Set a function that can create variable pointer for unknown expression variables. + \param a_pFactory A pointer to the variable factory. + \param pUserData A user defined context pointer. + */ + void QmuParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData) + { + m_pTokenReader->SetVarCreator(a_pFactory, pUserData); + } + + //--------------------------------------------------------------------------- + /** \brief Add a function or operator callback to the parser. */ + void QmuParserBase::AddCallback(const string_type &a_strName, + const QmuParserCallback &a_Callback, + funmap_type &a_Storage, + const char_type *a_szCharSet ) + { + if (a_Callback.GetAddr()==0) + Error(ecINVALID_FUN_PTR); + + const funmap_type *pFunMap = &a_Storage; + + // Check for conflicting operator or function names + if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() ) + Error(ecNAME_CONFLICT, -1, a_strName); + + if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() ) + Error(ecNAME_CONFLICT, -1, a_strName); + + if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() ) + Error(ecNAME_CONFLICT, -1, a_strName); + + if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() ) + Error(ecNAME_CONFLICT, -1, a_strName); + + CheckOprt(a_strName, a_Callback, a_szCharSet); + a_Storage[a_strName] = a_Callback; + ReInit(); + } + + //--------------------------------------------------------------------------- + /** \brief Check if a name contains invalid characters. + + \throw ParserException if the name contains invalid charakters. + */ + void QmuParserBase::CheckOprt(const string_type &a_sName, + const QmuParserCallback &a_Callback, + const string_type &a_szCharSet) const + { + if ( !a_sName.length() || + (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) || + (a_sName[0]>='0' && a_sName[0]<='9')) + { + switch(a_Callback.GetCode()) + { + case cmOPRT_POSTFIX: Error(ecINVALID_POSTFIX_IDENT, -1, a_sName); + case cmOPRT_INFIX: Error(ecINVALID_INFIX_IDENT, -1, a_sName); + default: Error(ecINVALID_NAME, -1, a_sName); + } + } + } + + //--------------------------------------------------------------------------- + /** \brief Check if a name contains invalid characters. + + \throw ParserException if the name contains invalid charakters. + */ + void QmuParserBase::CheckName(const string_type &a_sName, + const string_type &a_szCharSet) const + { + if ( !a_sName.length() || + (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) || + (a_sName[0]>='0' && a_sName[0]<='9')) + { + Error(ecINVALID_NAME); + } + } + + //--------------------------------------------------------------------------- + /** \brief Set the formula. + \param a_strFormula Formula as string_type + \throw ParserException in case of syntax errors. + + Triggers first time calculation thus the creation of the bytecode and + scanning of used variables. + */ + void QmuParserBase::SetExpr(const string_type &a_sExpr) + { + // Check locale compatibility + std::locale loc; + if (m_pTokenReader->GetArgSep()==std::use_facet >(loc).decimal_point()) + Error(ecLOCALE); + + // 20060222: Bugfix for Borland-Kylix: + // adding a space to the expression will keep Borlands KYLIX from going wild + // when calling tellg on a stringstream created from the expression after + // reading a value at the end of an expression. (mu::Parser::IsVal function) + // (tellg returns -1 otherwise causing the parser to ignore the value) + string_type sBuf(a_sExpr + _T(" ") ); + m_pTokenReader->SetFormula(sBuf); + ReInit(); + } + + //--------------------------------------------------------------------------- + /** \brief Get the default symbols used for the built in operators. + \sa c_DefaultOprt + */ + const char_type** QmuParserBase::GetOprtDef() const + { + return (const char_type **)(&c_DefaultOprt[0]); + } + + //--------------------------------------------------------------------------- + /** \brief Define the set of valid characters to be used in names of + functions, variables, constants. + */ + void QmuParserBase::DefineNameChars(const char_type *a_szCharset) + { + m_sNameChars = a_szCharset; + } + + //--------------------------------------------------------------------------- + /** \brief Define the set of valid characters to be used in names of + binary operators and postfix operators. + */ + void QmuParserBase::DefineOprtChars(const char_type *a_szCharset) + { + m_sOprtChars = a_szCharset; + } + + //--------------------------------------------------------------------------- + /** \brief Define the set of valid characters to be used in names of + infix operators. + */ + void QmuParserBase::DefineInfixOprtChars(const char_type *a_szCharset) + { + m_sInfixOprtChars = a_szCharset; + } + + //--------------------------------------------------------------------------- + /** \brief Virtual function that defines the characters allowed in name identifiers. + \sa #ValidOprtChars, #ValidPrefixOprtChars + */ + const char_type* QmuParserBase::ValidNameChars() const + { + assert(m_sNameChars.size()); + return m_sNameChars.c_str(); + } + + //--------------------------------------------------------------------------- + /** \brief Virtual function that defines the characters allowed in operator definitions. + \sa #ValidNameChars, #ValidPrefixOprtChars + */ + const char_type* QmuParserBase::ValidOprtChars() const + { + assert(m_sOprtChars.size()); + return m_sOprtChars.c_str(); + } + + //--------------------------------------------------------------------------- + /** \brief Virtual function that defines the characters allowed in infix operator definitions. + \sa #ValidNameChars, #ValidOprtChars + */ + const char_type* QmuParserBase::ValidInfixOprtChars() const + { + assert(m_sInfixOprtChars.size()); + return m_sInfixOprtChars.c_str(); + } + + //--------------------------------------------------------------------------- + /** \brief Add a user defined operator. + \post Will reset the Parser to string parsing mode. + */ + void QmuParserBase::DefinePostfixOprt(const string_type &a_sName, + fun_type1 a_pFun, + bool a_bAllowOpt) + { + AddCallback(a_sName, + QmuParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX), + m_PostOprtDef, + ValidOprtChars() ); + } + + //--------------------------------------------------------------------------- + /** \brief Initialize user defined functions. + + Calls the virtual functions InitFun(), InitConst() and InitOprt(). + */ + void QmuParserBase::Init() + { + InitCharSets(); + InitFun(); + InitConst(); + InitOprt(); + } + + //--------------------------------------------------------------------------- + /** \brief Add a user defined operator. + \post Will reset the Parser to string parsing mode. + \param [in] a_sName operator Identifier + \param [in] a_pFun Operator callback function + \param [in] a_iPrec Operator Precedence (default=prSIGN) + \param [in] a_bAllowOpt True if operator is volatile (default=false) + \sa EPrec + */ + void QmuParserBase::DefineInfixOprt(const string_type &a_sName, + fun_type1 a_pFun, + int a_iPrec, + bool a_bAllowOpt) + { + AddCallback(a_sName, + QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), + m_InfixOprtDef, + ValidInfixOprtChars() ); + } + + + //--------------------------------------------------------------------------- + /** \brief Define a binary operator. + \param [in] a_sName The identifier of the operator. + \param [in] a_pFun Pointer to the callback function. + \param [in] a_iPrec Precedence of the operator. + \param [in] a_eAssociativity The associativity of the operator. + \param [in] a_bAllowOpt If this is true the operator may be optimized away. + + Adds a new Binary operator the the parser instance. + */ + void QmuParserBase::DefineOprt( const string_type &a_sName, + fun_type2 a_pFun, + unsigned a_iPrec, + EOprtAssociativity a_eAssociativity, + bool a_bAllowOpt ) + { + // Check for conflicts with built in operator names + for (int i=0; m_bBuiltInOp && iIgnoreUndefVar(true); + CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it + // may contain references to nonexisting variables. + m_pParseFormula = &QmuParserBase::ParseString; + m_pTokenReader->IgnoreUndefVar(false); + } + catch(exception_type &e) + { + // Make sure to stay in string parse mode, dont call ReInit() + // because it deletes the array with the used variables + m_pParseFormula = &QmuParserBase::ParseString; + m_pTokenReader->IgnoreUndefVar(false); + throw e; + } + + return m_pTokenReader->GetUsedVar(); + } + + //--------------------------------------------------------------------------- + /** \brief Return a map containing the used variables only. */ + const varmap_type& QmuParserBase::GetVar() const + { + return m_VarDef; + } + + //--------------------------------------------------------------------------- + /** \brief Return a map containing all parser constants. */ + const valmap_type& QmuParserBase::GetConst() const + { + return m_ConstDef; + } + + //--------------------------------------------------------------------------- + /** \brief Return prototypes of all parser functions. + \return #m_FunDef + \sa FunProt + \throw nothrow + + The return type is a map of the public type #funmap_type containing the prototype + definitions for all numerical parser functions. String functions are not part of + this map. The Prototype definition is encapsulated in objects of the class FunProt + one per parser function each associated with function names via a map construct. + */ + const funmap_type& QmuParserBase::GetFunDef() const + { + return m_FunDef; + } + + //--------------------------------------------------------------------------- + /** \brief Retrieve the formula. */ + const string_type& QmuParserBase::GetExpr() const + { + return m_pTokenReader->GetExpr(); + } + + //--------------------------------------------------------------------------- + /** \brief Execute a function that takes a single string argument. + \param a_FunTok Function token. + \throw exception_type If the function token is not a string function + */ + QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, + const std::vector &a_vArg) const + { + if (a_vArg.back().GetCode()!=cmSTRING) + Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); + + token_type valTok; + generic_fun_type pFunc = a_FunTok.GetFuncAddr(); + assert(pFunc); + + try + { + // Check function arguments; write dummy value into valtok to represent the result + switch(a_FunTok.GetArgCount()) + { + case 0: valTok.SetVal(1); a_vArg[0].GetAsString(); break; + case 1: valTok.SetVal(1); a_vArg[1].GetAsString(); a_vArg[0].GetVal(); break; + case 2: valTok.SetVal(1); a_vArg[2].GetAsString(); a_vArg[1].GetVal(); a_vArg[0].GetVal(); break; + default: Error(ecINTERNAL_ERROR); + } + } + catch(QmuParserError& ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); + } + + // string functions won't be optimized + m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx()); + + // Push dummy value representing the function result to the stack + return valTok; + } + + //--------------------------------------------------------------------------- + /** \brief Apply a function token. + \param iArgCount Number of Arguments actually gathered used only for multiarg functions. + \post The result is pushed to the value stack + \post The function token is removed from the stack + \throw exception_type if Argument count does not mach function requirements. + */ + void QmuParserBase::ApplyFunc( QmuParserStack &a_stOpt, + QmuParserStack &a_stVal, + int a_iArgCount) const + { + assert(m_pTokenReader.get()); + + // Operator stack empty or does not contain tokens with callback functions + if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 ) + return; + + token_type funTok = a_stOpt.pop(); + assert(funTok.GetFuncAddr()); + + // Binary operators must rely on their internal operator number + // since counting of operators relies on commas for function arguments + // binary operators do not have commas in their expression + int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount; + + // determine how many parameters the function needs. To remember iArgCount includes the + // string parameter whilst GetArgCount() counts only numeric parameters. + int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0); + + // Thats the number of numerical parameters + int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0); + + if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1) + Error(ecINTERNAL_ERROR); + + if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) + Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); + + if (funTok.GetCode()!=cmOPRT_BIN && iArgCountGetPos()-1, funTok.GetAsString()); + + if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired ) + Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); + + // Collect the numeric function arguments from the value stack and store them + // in a vector + std::vector stArg; + for (int i=0; iGetPos(), funTok.GetAsString()); + } + + switch(funTok.GetCode()) + { + case cmFUNC_STR: + stArg.push_back(a_stVal.pop()); + + if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); + + ApplyStrFunc(funTok, stArg); + break; + + case cmFUNC_BULK: + m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); + break; + + case cmOPRT_BIN: + case cmOPRT_POSTFIX: + case cmOPRT_INFIX: + case cmFUNC: + if (funTok.GetArgCount()==-1 && iArgCount==0) + Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); + + m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); + break; + } + + // Push dummy value representing the function result to the stack + token_type token; + token.SetVal(1); + a_stVal.push(token); + } + + //--------------------------------------------------------------------------- + void QmuParserBase::ApplyIfElse(QmuParserStack &a_stOpt, + QmuParserStack &a_stVal) const + { + // Check if there is an if Else clause to be calculated + while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) + { + token_type opElse = a_stOpt.pop(); + MUP_ASSERT(a_stOpt.size()>0); + + // Take the value associated with the else branch from the value stack + token_type vVal2 = a_stVal.pop(); + + MUP_ASSERT(a_stOpt.size()>0); + MUP_ASSERT(a_stVal.size()>=2); + + // it then else is a ternary operator Pop all three values from the value s + // tack and just return the right value + token_type vVal1 = a_stVal.pop(); + token_type vExpr = a_stVal.pop(); + + a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2); + + token_type opIf = a_stOpt.pop(); + MUP_ASSERT(opElse.GetCode()==cmELSE); + MUP_ASSERT(opIf.GetCode()==cmIF); + + m_vRPN.AddIfElse(cmENDIF); + } // while pending if-else-clause found + } + + //--------------------------------------------------------------------------- + /** \brief Performs the necessary steps to write code for + the execution of binary operators into the bytecode. + */ + void QmuParserBase::ApplyBinOprt(QmuParserStack &a_stOpt, + QmuParserStack &a_stVal) const + { + // is it a user defined binary operator? + if (a_stOpt.top().GetCode()==cmOPRT_BIN) + { + ApplyFunc(a_stOpt, a_stVal, 2); + } + else + { + MUP_ASSERT(a_stVal.size()>=2); + token_type valTok1 = a_stVal.pop(), + valTok2 = a_stVal.pop(), + optTok = a_stOpt.pop(), + resTok; + + if ( valTok1.GetType()!=valTok2.GetType() || + (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) ) + Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString()); + + if (optTok.GetCode()==cmASSIGN) + { + if (valTok2.GetCode()!=cmVAR) + Error(ecUNEXPECTED_OPERATOR, -1, _T("=")); + + m_vRPN.AddAssignOp(valTok2.GetVar()); + } + else + m_vRPN.AddOp(optTok.GetCode()); + + resTok.SetVal(1); + a_stVal.push(resTok); + } + } + + //--------------------------------------------------------------------------- + /** \brief Apply a binary operator. + \param a_stOpt The operator stack + \param a_stVal The value stack + */ + void QmuParserBase::ApplyRemainingOprt(QmuParserStack &stOpt, + QmuParserStack &stVal) const + { + while (stOpt.size() && + stOpt.top().GetCode() != cmBO && + stOpt.top().GetCode() != cmIF) + { + token_type tok = stOpt.top(); + switch (tok.GetCode()) + { + case cmOPRT_INFIX: + case cmOPRT_BIN: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmLT: + case cmGT: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmLAND: + case cmLOR: + case cmASSIGN: + if (stOpt.top().GetCode()==cmOPRT_INFIX) + ApplyFunc(stOpt, stVal, 1); + else + ApplyBinOprt(stOpt, stVal); + break; + + case cmELSE: + ApplyIfElse(stOpt, stVal); + break; + + default: + Error(ecINTERNAL_ERROR); + } + } + } + + //--------------------------------------------------------------------------- + /** \brief Parse the command code. + \sa ParseString(...) + + Command code contains precalculated stack positions of the values and the + associated operators. The Stack is filled beginning from index one the + value at index zero is not used at all. + */ + value_type QmuParserBase::ParseCmdCode() const + { + return ParseCmdCodeBulk(0, 0); + } + + //--------------------------------------------------------------------------- + /** \brief Evaluate the RPN. + \param nOffset The offset added to variable addresses (for bulk mode) + \param nThreadID OpenMP Thread id of the calling thread + */ + value_type QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const + { + assert(nThreadID<=s_MaxNumOpenMPThreads); + + // Note: The check for nOffset==0 and nThreadID here is not necessary but + // brings a minor performance gain when not in bulk mode. + value_type *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; + value_type buf; + int sidx(0); + for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) + { + switch (pTok->Cmd) + { + // built in binary operators + case cmLE: --sidx; Stack[sidx] = Stack[sidx] <= Stack[sidx+1]; continue; + case cmGE: --sidx; Stack[sidx] = Stack[sidx] >= Stack[sidx+1]; continue; + case cmNEQ: --sidx; Stack[sidx] = Stack[sidx] != Stack[sidx+1]; continue; + case cmEQ: --sidx; Stack[sidx] = Stack[sidx] == Stack[sidx+1]; continue; + case cmLT: --sidx; Stack[sidx] = Stack[sidx] < Stack[sidx+1]; continue; + case cmGT: --sidx; Stack[sidx] = Stack[sidx] > Stack[sidx+1]; continue; + case cmADD: --sidx; Stack[sidx] += Stack[1+sidx]; continue; + case cmSUB: --sidx; Stack[sidx] -= Stack[1+sidx]; continue; + case cmMUL: --sidx; Stack[sidx] *= Stack[1+sidx]; continue; + case cmDIV: --sidx; + + #if defined(MUP_MATH_EXCEPTIONS) + if (Stack[1+sidx]==0) + Error(ecDIV_BY_ZERO); + #endif + Stack[sidx] /= Stack[1+sidx]; + continue; + + case cmPOW: + --sidx; Stack[sidx] = MathImpl::Pow(Stack[sidx], Stack[1+sidx]); + continue; + + case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue; + case cmLOR: --sidx; Stack[sidx] = Stack[sidx] || Stack[sidx+1]; continue; + + case cmASSIGN: + --sidx; Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; continue; + + //case cmBO: // unused, listed for compiler optimization purposes + //case cmBC: + // MUP_FAIL(INVALID_CODE_IN_BYTECODE); + // continue; + + case cmIF: + if (Stack[sidx--]==0) + pTok += pTok->Oprt.offset; + continue; + + case cmELSE: + pTok += pTok->Oprt.offset; + continue; + + case cmENDIF: + continue; + + //case cmARG_SEP: + // MUP_FAIL(INVALID_CODE_IN_BYTECODE); + // continue; + + // value and variable tokens + case cmVAR: Stack[++sidx] = *(pTok->Val.ptr + nOffset); continue; + case cmVAL: Stack[++sidx] = pTok->Val.data2; continue; + + case cmVARPOW2: buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf; + continue; + + case cmVARPOW3: buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf*buf; + continue; + + case cmVARPOW4: buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf*buf*buf; + continue; + + case cmVARMUL: Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2; + continue; + + // Next is treatment of numeric functions + case cmFUNC: + { + int iArgCount = pTok->Fun.argc; + + // switch according to argument count + switch(iArgCount) + { + case 0: sidx += 1; Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); continue; + case 1: Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); continue; + case 2: sidx -= 1; Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); continue; + case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue; + case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue; + case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; + case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; + case 7: sidx -= 6; Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; + case 8: sidx -= 7; Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue; + case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue; + case 10:sidx -= 9; Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue; + default: + if (iArgCount>0) // function with variable arguments store the number as a negative value + Error(ecINTERNAL_ERROR, 1); + + sidx -= -iArgCount - 1; + Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount); + continue; + } + } + + // Next is treatment of string functions + case cmFUNC_STR: + { + sidx -= pTok->Fun.argc -1; + + // The index of the string argument in the string table + int iIdxStack = pTok->Fun.idx; + MUP_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); + + switch(pTok->Fun.argc) // switch according to argument count + { + case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue; + case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue; + case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue; + } + + continue; + } + + case cmFUNC_BULK: + { + int iArgCount = pTok->Fun.argc; + + // switch according to argument count + switch(iArgCount) + { + case 0: sidx += 1; Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); continue; + case 1: Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); continue; + case 2: sidx -= 1; Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue; + case 3: sidx -= 2; Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue; + case 4: sidx -= 3; Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue; + case 5: sidx -= 4; Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; + case 6: sidx -= 5; Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; + case 7: sidx -= 6; Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; + case 8: sidx -= 7; Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue; + case 9: sidx -= 8; Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue; + case 10:sidx -= 9; Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue; + default: + Error(ecINTERNAL_ERROR, 2); + continue; + } + } + + //case cmSTRING: + //case cmOPRT_BIN: + //case cmOPRT_POSTFIX: + //case cmOPRT_INFIX: + // MUP_FAIL(INVALID_CODE_IN_BYTECODE); + // continue; + + //case cmEND: + // return Stack[m_nFinalResultIdx]; + + default: + Error(ecINTERNAL_ERROR, 3); + return 0; + } // switch CmdCode + } // for all bytecode tokens + + return Stack[m_nFinalResultIdx]; + } + + //--------------------------------------------------------------------------- + void QmuParserBase::CreateRPN() const + { + if (!m_pTokenReader->GetExpr().length()) + Error(ecUNEXPECTED_EOF, 0); + + QmuParserStack stOpt, stVal; + QmuParserStack stArgCount; + token_type opta, opt; // for storing operators + token_type val, tval; // for storing value + string_type strBuf; // buffer for string function arguments + + ReInit(); + + // The outermost counter counts the number of seperated items + // such as in "a=10,b=20,c=c+a" + stArgCount.push(1); + + for(;;) + { + opt = m_pTokenReader->ReadNextToken(); + + switch (opt.GetCode()) + { + // + // Next three are different kind of value entries + // + case cmSTRING: + opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token + stVal.push(opt); + m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer + break; + + case cmVAR: + stVal.push(opt); + m_vRPN.AddVar( static_cast(opt.GetVar()) ); + break; + + case cmVAL: + stVal.push(opt); + m_vRPN.AddVal( opt.GetVal() ); + break; + + case cmELSE: + m_nIfElseCounter--; + if (m_nIfElseCounter<0) + Error(ecMISPLACED_COLON, m_pTokenReader->GetPos()); + + ApplyRemainingOprt(stOpt, stVal); + m_vRPN.AddIfElse(cmELSE); + stOpt.push(opt); + break; + + + case cmARG_SEP: + if (stArgCount.empty()) + Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); + + ++stArgCount.top(); + // fallthrough intentional (no break!) + + case cmEND: + ApplyRemainingOprt(stOpt, stVal); + break; + + case cmBC: + { + // The argument count for parameterless functions is zero + // by default an opening bracket sets parameter count to 1 + // in preparation of arguments to come. If the last token + // was an opening bracket we know better... + if (opta.GetCode()==cmBO) + --stArgCount.top(); + + ApplyRemainingOprt(stOpt, stVal); + + // Check if the bracket content has been evaluated completely + if (stOpt.size() && stOpt.top().GetCode()==cmBO) + { + // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check + // if there is either a function or a sign pending + // neither the opening nor the closing bracket will be pushed back to + // the operator stack + // Check if a function is standing in front of the opening bracket, + // if yes evaluate it afterwards check for infix operators + assert(stArgCount.size()); + int iArgCount = stArgCount.pop(); + + stOpt.pop(); // Take opening bracket from stack + + if (iArgCount>1 && ( stOpt.size()==0 || + (stOpt.top().GetCode()!=cmFUNC && + stOpt.top().GetCode()!=cmFUNC_BULK && + stOpt.top().GetCode()!=cmFUNC_STR) ) ) + Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos()); + + // The opening bracket was popped from the stack now check if there + // was a function before this bracket + if (stOpt.size() && + stOpt.top().GetCode()!=cmOPRT_INFIX && + stOpt.top().GetCode()!=cmOPRT_BIN && + stOpt.top().GetFuncAddr()!=0) + { + ApplyFunc(stOpt, stVal, iArgCount); + } + } + } // if bracket content is evaluated + break; + + // + // Next are the binary operator entries + // + //case cmAND: // built in binary operators + //case cmOR: + //case cmXOR: + case cmIF: + m_nIfElseCounter++; + // fallthrough intentional (no break!) + + case cmLAND: + case cmLOR: + case cmLT: + case cmGT: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmASSIGN: + case cmOPRT_BIN: + + // A binary operator (user defined or built in) has been found. + while ( stOpt.size() && + stOpt.top().GetCode() != cmBO && + stOpt.top().GetCode() != cmELSE && + stOpt.top().GetCode() != cmIF) + { + int nPrec1 = GetOprtPrecedence(stOpt.top()), + nPrec2 = GetOprtPrecedence(opt); + + if (stOpt.top().GetCode()==opt.GetCode()) + { + + // Deal with operator associativity + EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt); + if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || + (eOprtAsct==oaLEFT && (nPrec1 < nPrec2)) ) + { + break; + } + } + else if (nPrec1 < nPrec2) + { + // In case the operators are not equal the precedence decides alone... + break; + } + + if (stOpt.top().GetCode()==cmOPRT_INFIX) + ApplyFunc(stOpt, stVal, 1); + else + ApplyBinOprt(stOpt, stVal); + } // while ( ... ) + + if (opt.GetCode()==cmIF) + m_vRPN.AddIfElse(opt.GetCode()); + + // The operator can't be evaluated right now, push back to the operator stack + stOpt.push(opt); + break; + + // + // Last section contains functions and operators implicitely mapped to functions + // + case cmBO: + stArgCount.push(1); + stOpt.push(opt); + break; + + case cmOPRT_INFIX: + case cmFUNC: + case cmFUNC_BULK: + case cmFUNC_STR: + stOpt.push(opt); + break; + + case cmOPRT_POSTFIX: + stOpt.push(opt); + ApplyFunc(stOpt, stVal, 1); // this is the postfix operator + break; + + default: Error(ecINTERNAL_ERROR, 3); + } // end of switch operator-token + + opta = opt; + + if ( opt.GetCode() == cmEND ) + { + m_vRPN.Finalize(); + break; + } + + if (QmuParserBase::g_DbgDumpStack) + { + StackDump(stVal, stOpt); + m_vRPN.AsciiDump(); + } + } // while (true) + + if (QmuParserBase::g_DbgDumpCmdCode) + m_vRPN.AsciiDump(); + + if (m_nIfElseCounter>0) + Error(ecMISSING_ELSE_CLAUSE); + + // get the last value (= final result) from the stack + MUP_ASSERT(stArgCount.size()==1); + m_nFinalResultIdx = stArgCount.top(); + if (m_nFinalResultIdx==0) + Error(ecINTERNAL_ERROR, 9); + + if (stVal.size()==0) + Error(ecEMPTY_EXPRESSION); + + if (stVal.top().GetType()!=tpDBL) + Error(ecSTR_RESULT); + + m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads); + } + + //--------------------------------------------------------------------------- + /** \brief One of the two main parse functions. + \sa ParseCmdCode(...) + + Parse expression from input string. Perform syntax checking and create + bytecode. After parsing the string and creating the bytecode the function + pointer #m_pParseFormula will be changed to the second parse routine the + uses bytecode instead of string parsing. + */ + value_type QmuParserBase::ParseString() const + { + try + { + CreateRPN(); + m_pParseFormula = &QmuParserBase::ParseCmdCode; + return (this->*m_pParseFormula)(); + } + catch(QmuParserError &exc) + { + exc.SetFormula(m_pTokenReader->GetExpr()); + throw; + } + } + + //--------------------------------------------------------------------------- + /** \brief Create an error containing the parse error position. + + This function will create an Parser Exception object containing the error text and + its position. + + \param a_iErrc [in] The error code of type #EErrorCodes. + \param a_iPos [in] The position where the error was detected. + \param a_strTok [in] The token string representation associated with the error. + \throw ParserException always throws thats the only purpose of this function. + */ + void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const + { + throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); + } + + //------------------------------------------------------------------------------ + /** \brief Clear all user defined variables. + \throw nothrow + + Resets the parser to string parsing mode by calling #ReInit. + */ + void QmuParserBase::ClearVar() + { + m_VarDef.clear(); + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Remove a variable from internal storage. + \throw nothrow + + Removes a variable if it exists. If the Variable does not exist nothing will be done. + */ + void QmuParserBase::RemoveVar(const string_type &a_strVarName) + { + varmap_type::iterator item = m_VarDef.find(a_strVarName); + if (item!=m_VarDef.end()) + { + m_VarDef.erase(item); + ReInit(); + } + } + + //------------------------------------------------------------------------------ + /** \brief Clear all functions. + \post Resets the parser to string parsing mode. + \throw nothrow + */ + void QmuParserBase::ClearFun() + { + m_FunDef.clear(); + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Clear all user defined constants. + + Both numeric and string constants will be removed from the internal storage. + \post Resets the parser to string parsing mode. + \throw nothrow + */ + void QmuParserBase::ClearConst() + { + m_ConstDef.clear(); + m_StrVarDef.clear(); + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Clear all user defined postfix operators. + \post Resets the parser to string parsing mode. + \throw nothrow + */ + void QmuParserBase::ClearPostfixOprt() + { + m_PostOprtDef.clear(); + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Clear all user defined binary operators. + \post Resets the parser to string parsing mode. + \throw nothrow + */ + void QmuParserBase::ClearOprt() + { + m_OprtDef.clear(); + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Clear the user defined Prefix operators. + \post Resets the parser to string parser mode. + \throw nothrow + */ + void QmuParserBase::ClearInfixOprt() + { + m_InfixOprtDef.clear(); + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Enable or disable the formula optimization feature. + \post Resets the parser to string parser mode. + \throw nothrow + */ + void QmuParserBase::EnableOptimizer(bool a_bIsOn) + { + m_vRPN.EnableOptimizer(a_bIsOn); + ReInit(); + } + + //--------------------------------------------------------------------------- + /** \brief Enable the dumping of bytecode amd stack content on the console. + \param bDumpCmd Flag to enable dumping of the current bytecode to the console. + \param bDumpStack Flag to enable dumping of the stack content is written to the console. + + This function is for debug purposes only! + */ + void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) + { + QmuParserBase::g_DbgDumpCmdCode = bDumpCmd; + QmuParserBase::g_DbgDumpStack = bDumpStack; + } + + //------------------------------------------------------------------------------ + /** \brief Enable or disable the built in binary operators. + \throw nothrow + \sa m_bBuiltInOp, ReInit() + + If you disable the built in binary operators there will be no binary operators + defined. Thus you must add them manually one by one. It is not possible to + disable built in operators selectively. This function will Reinitialize the + parser by calling ReInit(). + */ + void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) + { + m_bBuiltInOp = a_bIsOn; + ReInit(); + } + + //------------------------------------------------------------------------------ + /** \brief Query status of built in variables. + \return #m_bBuiltInOp; true if built in operators are enabled. + \throw nothrow + */ + bool QmuParserBase::HasBuiltInOprt() const + { + return m_bBuiltInOp; + } + + //------------------------------------------------------------------------------ + /** \brief Get the argument separator character. + */ + char_type QmuParserBase::GetArgSep() const + { + return m_pTokenReader->GetArgSep(); + } + + //------------------------------------------------------------------------------ + /** \brief Set argument separator. + \param cArgSep the argument separator character. + */ + void QmuParserBase::SetArgSep(char_type cArgSep) + { + m_pTokenReader->SetArgSep(cArgSep); + } + + //------------------------------------------------------------------------------ + /** \brief Dump stack content. + + This function is used for debugging only. + */ + void QmuParserBase::StackDump(const QmuParserStack &a_stVal, + const QmuParserStack &a_stOprt) const + { + QmuParserStack stOprt(a_stOprt), + stVal(a_stVal); + + mu::console() << _T("\nValue stack:\n"); + while ( !stVal.empty() ) + { + token_type val = stVal.pop(); + if (val.GetType()==tpSTR) + mu::console() << _T(" \"") << val.GetAsString() << _T("\" "); + else + mu::console() << _T(" ") << val.GetVal() << _T(" "); + } + mu::console() << "\nOperator stack:\n"; + + while ( !stOprt.empty() ) + { + if (stOprt.top().GetCode()<=cmASSIGN) + { + mu::console() << _T("OPRT_INTRNL \"") + << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] + << _T("\" \n"); + } + else + { + switch(stOprt.top().GetCode()) + { + case cmVAR: mu::console() << _T("VAR\n"); break; + case cmVAL: mu::console() << _T("VAL\n"); break; + case cmFUNC: mu::console() << _T("FUNC \"") + << stOprt.top().GetAsString() + << _T("\"\n"); break; + case cmFUNC_BULK: mu::console() << _T("FUNC_BULK \"") + << stOprt.top().GetAsString() + << _T("\"\n"); break; + case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"") + << stOprt.top().GetAsString() + << _T("\"\n"); break; + case cmOPRT_BIN: mu::console() << _T("OPRT_BIN \"") + << stOprt.top().GetAsString() + << _T("\"\n"); break; + case cmFUNC_STR: mu::console() << _T("FUNC_STR\n"); break; + case cmEND: mu::console() << _T("END\n"); break; + case cmUNKNOWN: mu::console() << _T("UNKNOWN\n"); break; + case cmBO: mu::console() << _T("BRACKET \"(\"\n"); break; + case cmBC: mu::console() << _T("BRACKET \")\"\n"); break; + case cmIF: mu::console() << _T("IF\n"); break; + case cmELSE: mu::console() << _T("ELSE\n"); break; + case cmENDIF: mu::console() << _T("ENDIF\n"); break; + default: mu::console() << stOprt.top().GetCode() << _T(" "); break; + } + } + stOprt.pop(); + } + + mu::console() << dec << endl; + } + + //------------------------------------------------------------------------------ + /** \brief Evaluate an expression containing comma seperated subexpressions + \param [out] nStackSize The total number of results available + \return Pointer to the array containing all expression results + + This member function can be used to retriev all results of an expression + made up of multiple comma seperated subexpressions (i.e. "x+y,sin(x),cos(y)") + */ + value_type* QmuParserBase::Eval(int &nStackSize) const + { + (this->*m_pParseFormula)(); + nStackSize = m_nFinalResultIdx; + + // (for historic reasons the stack starts at position 1) + return &m_vStackBuffer[1]; + } + + //--------------------------------------------------------------------------- + /** \brief Return the number of results on the calculation stack. + + If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). + There mey be more than one return value. This function returns the number of + available results. + */ + int QmuParserBase::GetNumResults() const + { + return m_nFinalResultIdx; + } + + //--------------------------------------------------------------------------- + /** \brief Calculate the result. + + A note on const correctness: + I consider it important that Calc is a const function. + Due to caching operations Calc changes only the state of internal variables with one exception + m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making + Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. + + \pre A formula must be set. + \pre Variables must have been set (if needed) + + \sa #m_pParseFormula + \return The evaluation result + \throw ParseException if no Formula is set or in case of any other error related to the formula. + */ + value_type QmuParserBase::Eval() const + { + return (this->*m_pParseFormula)(); + } + + //--------------------------------------------------------------------------- + void QmuParserBase::Eval(value_type *results, int nBulkSize) + { + CreateRPN(); + + int i = 0; + +#ifdef MUP_USE_OPENMP +//#define DEBUG_OMP_STUFF + #ifdef DEBUG_OMP_STUFF + int *pThread = new int[nBulkSize]; + int *pIdx = new int[nBulkSize]; + #endif + + int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads); + int nThreadID, ct=0; + omp_set_num_threads(nMaxThreads); + + #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) + for (i=0; i + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUQPARSERBASE_H +#define QMUQPARSERBASE_H + +//--- Standard includes ------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include + +//--- Parser includes -------------------------------------------------------------------------- +#include "qmuparserdef.h" +#include "qmuparserstack.h" +#include "qmuparsertokenreader.h" +#include "qmuparserbytecode.h" +#include "qmuparsererror.h" + + +namespace qmu +{ +/** \file + \brief This file contains the class definition of the qmuparser engine. +*/ + +//-------------------------------------------------------------------------------------------------- +/** \brief Mathematical expressions parser (base parser engine). + \author (C) 2013 Ingo Berg + + This is the implementation of a bytecode based mathematical expressions parser. + The formula will be parsed from string and converted into a bytecode. + Future calculations will be done with the bytecode instead the formula string + resulting in a significant performance increase. + Complementary to a set of internally implemented functions the parser is able to handle + user defined functions and variables. +*/ +class QmuParserBase +{ +friend class QmuParserTokenReader; + +private: + + /** \brief Typedef for the parse functions. + + The parse function do the actual work. The parser exchanges + the function pointer to the parser function depending on + which state it is in. (i.e. bytecode parser vs. string parser) + */ + typedef value_type (QmuParserBase::*ParseFunction)() const; + + /** \brief Type used for storing an array of values. */ + typedef std::vector valbuf_type; + + /** \brief Type for a vector of strings. */ + typedef std::vector stringbuf_type; + + /** \brief Typedef for the token reader. */ + typedef QmuParserTokenReader token_reader_type; + + /** \brief Type used for parser tokens. */ + typedef QmuParserToken token_type; + + /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */ + static const int s_MaxNumOpenMPThreads = 4; + + public: + + /** \brief Type of the error class. + + Included for backwards compatibility. + */ + typedef QmuParserError exception_type; + + static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); + + QmuParserBase(); + QmuParserBase(const QmuParserBase &a_Parser); + QmuParserBase& operator=(const QmuParserBase &a_Parser); + + virtual ~QmuParserBase(); + + value_type Eval() const; + value_type* Eval(int &nStackSize) const; + void Eval(value_type *results, int nBulkSize); + + int GetNumResults() const; + + void SetExpr(const string_type &a_sExpr); + void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); + + void SetDecSep(char_type cDecSep); + void SetThousandsSep(char_type cThousandsSep = 0); + void ResetLocale(); + + void EnableOptimizer(bool a_bIsOn=true); + void EnableBuiltInOprt(bool a_bIsOn=true); + + bool HasBuiltInOprt() const; + void AddValIdent(identfun_type a_pCallback); + + /** \fn void mu::QParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) + \brief Define a parser function without arguments. + \param a_strName Name of the function + \param a_pFun Pointer to the callback function + \param a_bAllowOpt A flag indicating this function may be optimized + */ + template + void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true) + { + AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); + } + + void DefineOprt(const string_type &a_strName, + fun_type2 a_pFun, + unsigned a_iPri=0, + EOprtAssociativity a_eAssociativity = oaLEFT, + bool a_bAllowOpt = false); + void DefineConst(const string_type &a_sName, value_type a_fVal); + void DefineStrConst(const string_type &a_sName, const string_type &a_strVal); + void DefineVar(const string_type &a_sName, value_type *a_fVar); + void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); + void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); + + // Clear user defined variables, constants or functions + void ClearVar(); + void ClearFun(); + void ClearConst(); + void ClearInfixOprt(); + void ClearPostfixOprt(); + void ClearOprt(); + + void RemoveVar(const string_type &a_strVarName); + const varmap_type& GetUsedVar() const; + const varmap_type& GetVar() const; + const valmap_type& GetConst() const; + const string_type& GetExpr() const; + const funmap_type& GetFunDef() const; + string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const; + + const char_type ** GetOprtDef() const; + void DefineNameChars(const char_type *a_szCharset); + void DefineOprtChars(const char_type *a_szCharset); + void DefineInfixOprtChars(const char_type *a_szCharset); + + const char_type* ValidNameChars() const; + const char_type* ValidOprtChars() const; + const char_type* ValidInfixOprtChars() const; + + void SetArgSep(char_type cArgSep); + char_type GetArgSep() const; + + void Error(EErrorCodes a_iErrc, + int a_iPos = (int)qmu::string_type::npos, + const string_type &a_strTok = string_type() ) const; + + protected: + + void Init(); + + virtual void InitCharSets() = 0; + virtual void InitFun() = 0; + virtual void InitConst() = 0; + virtual void InitOprt() = 0; + + virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + + static const char_type *c_DefaultOprt[]; + static std::locale s_locale; ///< The locale used by the parser + static bool g_DbgDumpCmdCode; + static bool g_DbgDumpStack; + + /** \brief A facet class used to change decimal and thousands separator. */ + template + class change_dec_sep : public std::numpunct + { + public: + + explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) + :std::numpunct() + ,m_nGroup(nGroup) + ,m_cDecPoint(cDecSep) + ,m_cThousandsSep(cThousandsSep) + {} + + protected: + + virtual char_type do_decimal_point() const + { + return m_cDecPoint; + } + + virtual char_type do_thousands_sep() const + { + return m_cThousandsSep; + } + + virtual std::string do_grouping() const + { + return std::string(1, m_nGroup); + } + + private: + + int m_nGroup; + char_type m_cDecPoint; + char_type m_cThousandsSep; + }; + + private: + + void Assign(const QmuParserBase &a_Parser); + void InitTokenReader(); + void ReInit() const; + + void AddCallback( const string_type &a_strName, + const QmuParserCallback &a_Callback, + funmap_type &a_Storage, + const char_type *a_szCharSet ); + + void ApplyRemainingOprt(QmuParserStack &a_stOpt, + QmuParserStack &a_stVal) const; + void ApplyBinOprt(QmuParserStack &a_stOpt, + QmuParserStack &a_stVal) const; + + void ApplyIfElse(QmuParserStack &a_stOpt, + QmuParserStack &a_stVal) const; + + void ApplyFunc(QmuParserStack &a_stOpt, + QmuParserStack &a_stVal, + int iArgCount) const; + + token_type ApplyStrFunc(const token_type &a_FunTok, + const std::vector &a_vArg) const; + + int GetOprtPrecedence(const token_type &a_Tok) const; + EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; + + void CreateRPN() const; + + value_type ParseString() const; + value_type ParseCmdCode() const; + value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const; + + void CheckName(const string_type &a_strName, const string_type &a_CharSet) const; + void CheckOprt(const string_type &a_sName, + const QmuParserCallback &a_Callback, + const string_type &a_szCharSet) const; + + void StackDump(const QmuParserStack &a_stVal, + const QmuParserStack &a_stOprt) const; + + /** \brief Pointer to the parser function. + + Eval() calls the function whose address is stored there. + */ + mutable ParseFunction m_pParseFormula; + mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. + mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments + stringbuf_type m_vStringVarBuf; + + std::auto_ptr m_pTokenReader; ///< Managed pointer to the token reader object. + + funmap_type m_FunDef; ///< Map of function names and pointers. + funmap_type m_PostOprtDef; ///< Postfix operator callbacks + funmap_type m_InfixOprtDef; ///< unary infix operator. + funmap_type m_OprtDef; ///< Binary operator callbacks + valmap_type m_ConstDef; ///< user constants. + strmap_type m_StrVarDef; ///< user defined string constants + varmap_type m_VarDef; ///< user defind variables. + + bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off + + string_type m_sNameChars; ///< Charset for names + string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens + string_type m_sInfixOprtChars; ///< Charset for infix operator tokens + + mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses + + // items merely used for caching state information + mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine + mutable int m_nFinalResultIdx; +}; + +} // namespace qmu + +#endif + diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp new file mode 100644 index 000000000..222c1db0a --- /dev/null +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -0,0 +1,583 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparserbytecode.h" + +#include +#include +#include +#include +#include + +#include "qmuparserdef.h" +#include "qmuparsererror.h" +#include "qmuparsertoken.h" +#include "qmuparserstack.h" +#include "qmuparsertemplatemagic.h" + + +namespace qmu +{ + //--------------------------------------------------------------------------- + /** \brief Bytecode default constructor. */ + QmuParserByteCode::QmuParserByteCode() + :m_iStackPos(0) + ,m_iMaxStackSize(0) + ,m_vRPN() + ,m_bEnableOptimizer(true) + { + m_vRPN.reserve(50); + } + + //--------------------------------------------------------------------------- + /** \brief Copy constructor. + + Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) + */ + QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) + { + Assign(a_ByteCode); + } + + //--------------------------------------------------------------------------- + /** \brief Assignment operator. + + Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) + */ + QmuParserByteCode& QmuParserByteCode::operator=(const QmuParserByteCode &a_ByteCode) + { + Assign(a_ByteCode); + return *this; + } + + //--------------------------------------------------------------------------- + void QmuParserByteCode::EnableOptimizer(bool bStat) + { + m_bEnableOptimizer = bStat; + } + + //--------------------------------------------------------------------------- + /** \brief Copy state of another object to this. + + \throw nowthrow + */ + void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) + { + if (this==&a_ByteCode) + return; + + m_iStackPos = a_ByteCode.m_iStackPos; + m_vRPN = a_ByteCode.m_vRPN; + m_iMaxStackSize = a_ByteCode.m_iMaxStackSize; + } + + //--------------------------------------------------------------------------- + /** \brief Add a Variable pointer to bytecode. + \param a_pVar Pointer to be added. + \throw nothrow + */ + void QmuParserByteCode::AddVar(value_type *a_pVar) + { + ++m_iStackPos; + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + // optimization does not apply + SToken tok; + tok.Cmd = cmVAR; + tok.Val.ptr = a_pVar; + tok.Val.data = 1; + tok.Val.data2 = 0; + m_vRPN.push_back(tok); + } + + //--------------------------------------------------------------------------- + /** \brief Add a Variable pointer to bytecode. + + Value entries in byte code consist of: +
    +
  • value array position of the value
  • +
  • the operator code according to ParserToken::cmVAL
  • +
  • the value stored in #mc_iSizeVal number of bytecode entries.
  • +
+ + \param a_pVal Value to be added. + \throw nothrow + */ + void QmuParserByteCode::AddVal(value_type a_fVal) + { + ++m_iStackPos; + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + // If optimization does not apply + SToken tok; + tok.Cmd = cmVAL; + tok.Val.ptr = NULL; + tok.Val.data = 0; + tok.Val.data2 = a_fVal; + m_vRPN.push_back(tok); + } + + //--------------------------------------------------------------------------- + void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) + { + std::size_t sz = m_vRPN.size(); + value_type &x = m_vRPN[sz-2].Val.data2, + &y = m_vRPN[sz-1].Val.data2; + switch (a_Oprt) + { + case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break; + case cmLOR: x = (int)x || (int)y; m_vRPN.pop_back(); break; + case cmLT: x = x < y; m_vRPN.pop_back(); break; + case cmGT: x = x > y; m_vRPN.pop_back(); break; + case cmLE: x = x <= y; m_vRPN.pop_back(); break; + case cmGE: x = x >= y; m_vRPN.pop_back(); break; + case cmNEQ: x = x != y; m_vRPN.pop_back(); break; + case cmEQ: x = x == y; m_vRPN.pop_back(); break; + case cmADD: x = x + y; m_vRPN.pop_back(); break; + case cmSUB: x = x - y; m_vRPN.pop_back(); break; + case cmMUL: x = x * y; m_vRPN.pop_back(); break; + case cmDIV: + +#if defined(MUP_MATH_EXCEPTIONS) + if (y==0) + throw ParserError(ecDIV_BY_ZERO, _T("0")); +#endif + + x = x / y; + m_vRPN.pop_back(); + break; + + case cmPOW: x = MathImpl::Pow(x, y); + m_vRPN.pop_back(); + break; + + default: + break; + } // switch opcode + } + + //--------------------------------------------------------------------------- + /** \brief Add an operator identifier to bytecode. + + Operator entries in byte code consist of: +
    +
  • value array position of the result
  • +
  • the operator code according to ParserToken::ECmdCode
  • +
+ + \sa ParserToken::ECmdCode + */ + void QmuParserByteCode::AddOp(ECmdCode a_Oprt) + { + bool bOptimized = false; + + if (m_bEnableOptimizer) + { + std::size_t sz = m_vRPN.size(); + + // Check for foldable constants like: + // cmVAL cmVAL cmADD + // where cmADD can stand fopr any binary operator applied to + // two constant values. + if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL) + { + ConstantFolding(a_Oprt); + bOptimized = true; + } + else + { + switch(a_Oprt) + { + case cmPOW: + // Optimization for ploynomials of low order + if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) + { + if (m_vRPN[sz-1].Val.data2==2) + m_vRPN[sz-2].Cmd = cmVARPOW2; + else if (m_vRPN[sz-1].Val.data2==3) + m_vRPN[sz-2].Cmd = cmVARPOW3; + else if (m_vRPN[sz-1].Val.data2==4) + m_vRPN[sz-2].Cmd = cmVARPOW4; + else + break; + + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + case cmSUB: + case cmADD: + // Simple optimization based on pattern recognition for a shitload of different + // bytecode combinations of addition/subtraction + if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) + { + assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) || + (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || + (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); + + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable + m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset + m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + case cmMUL: + if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) + { + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 = 0; + m_vRPN.pop_back(); + bOptimized = true; + } + else if ( (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ) + { + // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); + if (m_vRPN[sz-1].Cmd == cmVAL) + { + m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2; + } + else + { + m_vRPN[sz-2].Val.data = m_vRPN[sz-1].Val.data * m_vRPN[sz-2].Val.data2; + m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2; + } + m_vRPN.pop_back(); + bOptimized = true; + } + else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr) + { + // Optimization: a*a -> a^2 + m_vRPN[sz-2].Cmd = cmVARPOW2; + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + case cmDIV: + if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0) + { + // Optimization: 4*a/2 -> 2*a + m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + } // switch a_Oprt + } + } + + // If optimization can't be applied just write the value + if (!bOptimized) + { + --m_iStackPos; + SToken tok; + tok.Cmd = a_Oprt; + m_vRPN.push_back(tok); + } + } + + //--------------------------------------------------------------------------- + void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt) + { + SToken tok; + tok.Cmd = a_Oprt; + m_vRPN.push_back(tok); + } + + //--------------------------------------------------------------------------- + /** \brief Add an assignement operator + + Operator entries in byte code consist of: +
    +
  • cmASSIGN code
  • +
  • the pointer of the destination variable
  • +
+ + \sa ParserToken::ECmdCode + */ + void QmuParserByteCode::AddAssignOp(value_type *a_pVar) + { + --m_iStackPos; + + SToken tok; + tok.Cmd = cmASSIGN; + tok.Val.ptr = a_pVar; + m_vRPN.push_back(tok); + } + + //--------------------------------------------------------------------------- + /** \brief Add function to bytecode. + + \param a_iArgc Number of arguments, negative numbers indicate multiarg functions. + \param a_pFun Pointer to function callback. + */ + void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) + { + if (a_iArgc>=0) + { + m_iStackPos = m_iStackPos - a_iArgc + 1; + } + else + { + // function with unlimited number of arguments + m_iStackPos = m_iStackPos + a_iArgc + 1; + } + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + SToken tok; + tok.Cmd = cmFUNC; + tok.Fun.argc = a_iArgc; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); + } + + //--------------------------------------------------------------------------- + /** \brief Add a bulk function to bytecode. + + \param a_iArgc Number of arguments, negative numbers indicate multiarg functions. + \param a_pFun Pointer to function callback. + */ + void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) + { + m_iStackPos = m_iStackPos - a_iArgc + 1; + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + SToken tok; + tok.Cmd = cmFUNC_BULK; + tok.Fun.argc = a_iArgc; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); + } + + //--------------------------------------------------------------------------- + /** \brief Add Strung function entry to the parser bytecode. + \throw nothrow + + A string function entry consists of the stack position of the return value, + followed by a cmSTRFUNC code, the function pointer and an index into the + string buffer maintained by the parser. + */ + void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) + { + m_iStackPos = m_iStackPos - a_iArgc + 1; + + SToken tok; + tok.Cmd = cmFUNC_STR; + tok.Fun.argc = a_iArgc; + tok.Fun.idx = a_iIdx; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); + + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + } + + //--------------------------------------------------------------------------- + /** \brief Add end marker to bytecode. + + \throw nothrow + */ + void QmuParserByteCode::Finalize() + { + SToken tok; + tok.Cmd = cmEND; + m_vRPN.push_back(tok); + rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit + + // Determine the if-then-else jump offsets + QmuParserStack stIf, stElse; + int idx; + for (int i=0; i<(int)m_vRPN.size(); ++i) + { + switch(m_vRPN[i].Cmd) + { + case cmIF: + stIf.push(i); + break; + + case cmELSE: + stElse.push(i); + idx = stIf.pop(); + m_vRPN[idx].Oprt.offset = i - idx; + break; + + case cmENDIF: + idx = stElse.pop(); + m_vRPN[idx].Oprt.offset = i - idx; + break; + + default: + break; + } + } + } + + //--------------------------------------------------------------------------- + const SToken* QmuParserByteCode::GetBase() const + { + if (m_vRPN.size()==0) + throw QmuParserError(ecINTERNAL_ERROR); + else + return &m_vRPN[0]; + } + + //--------------------------------------------------------------------------- + std::size_t QmuParserByteCode::GetMaxStackSize() const + { + return m_iMaxStackSize+1; + } + + //--------------------------------------------------------------------------- + /** \brief Returns the number of entries in the bytecode. */ + std::size_t QmuParserByteCode::GetSize() const + { + return m_vRPN.size(); + } + + //--------------------------------------------------------------------------- + /** \brief Delete the bytecode. + + \throw nothrow + + The name of this function is a violation of my own coding guidelines + but this way it's more in line with the STL functions thus more + intuitive. + */ + void QmuParserByteCode::clear() + { + m_vRPN.clear(); + m_iStackPos = 0; + m_iMaxStackSize = 0; + } + + //--------------------------------------------------------------------------- + /** \brief Dump bytecode (for debugging only!). */ + void QmuParserByteCode::AsciiDump() + { + if (!m_vRPN.size()) + { + mu::console() << _T("No bytecode available\n"); + return; + } + + mu::console() << _T("Number of RPN tokens:") << (int)m_vRPN.size() << _T("\n"); + for (std::size_t i=0; i + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERBYTECODE_H +#define QMUPARSERBYTECODE_H + +#include +#include +#include +#include + +#include "qmuparserdef.h" +#include "qmuparsererror.h" +#include "qmuparsertoken.h" + +/** \file + \brief Definition of the parser bytecode class. +*/ + + +namespace qmu +{ + struct SToken + { + ECmdCode Cmd; + int StackPos; + + union + { + struct //SValData + { + value_type *ptr; + value_type data; + value_type data2; + } Val; + + struct //SFunData + { + // Note: generic_fun_type is merely a placeholder. The real type could be + // anything between gun_type1 and fun_type9. I can't use a void + // pointer due to constraints in the ANSI standard which allows + // data pointers and function pointers to differ in size. + generic_fun_type ptr; + int argc; + int idx; + } Fun; + + struct //SOprtData + { + value_type *ptr; + int offset; + } Oprt; + }; + }; + + + /** \brief Bytecode implementation of the Math Parser. + + The bytecode contains the formula converted to revers polish notation stored in a continious + memory area. Associated with this data are operator codes, variable pointers, constant + values and function pointers. Those are necessary in order to calculate the result. + All those data items will be casted to the underlying datatype of the bytecode. + + \author (C) 2004-2013 Ingo Berg +*/ +class QmuParserByteCode +{ +private: + + /** \brief Token type for internal use only. */ + typedef QmuParserToken token_type; + + /** \brief Token vector for storing the RPN. */ + typedef std::vector rpn_type; + + /** \brief Position in the Calculation array. */ + unsigned m_iStackPos; + + /** \brief Maximum size needed for the stack. */ + std::size_t m_iMaxStackSize; + + /** \brief The actual rpn storage. */ + rpn_type m_vRPN; + + bool m_bEnableOptimizer; + + void ConstantFolding(ECmdCode a_Oprt); + +public: + + QmuParserByteCode(); + QmuParserByteCode(const QmuParserByteCode &a_ByteCode); + QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); + void Assign(const QmuParserByteCode &a_ByteCode); + + void AddVar(value_type *a_pVar); + void AddVal(value_type a_fVal); + void AddOp(ECmdCode a_Oprt); + void AddIfElse(ECmdCode a_Oprt); + void AddAssignOp(value_type *a_pVar); + void AddFun(generic_fun_type a_pFun, int a_iArgc); + void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); + void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); + + void EnableOptimizer(bool bStat); + + void Finalize(); + void clear(); + std::size_t GetMaxStackSize() const; + std::size_t GetSize() const; + + const SToken* GetBase() const; + void AsciiDump(); +}; + +} // namespace qmu + +#endif + + diff --git a/src/libs/qmuparser/qmuparsercallback.cpp b/src/libs/qmuparser/qmuparsercallback.cpp new file mode 100644 index 000000000..08bc21f2d --- /dev/null +++ b/src/libs/qmuparser/qmuparsercallback.cpp @@ -0,0 +1,460 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsercallback.h" + +/** \file + \brief Implementation of the parser callback class. +*/ + + +namespace qmu +{ + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(0) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode) + :m_pFun((void*)a_pFun) + ,m_iArgc(1) + ,m_iPri(a_iPrec) + ,m_eOprtAsct(oaNONE) + ,m_iCode(a_iCode) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + /** \brief Constructor for constructing funcstion callbacks taking two arguments. + \throw nothrow + */ + QmuParserCallback::QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(2) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + /** \brief Constructor for constructing binary operator callbacks. + \param a_pFun Pointer to a static function taking two arguments + \param a_bAllowOpti A flag indicating this funcation can be optimized + \param a_iPrec The operator precedence + \param a_eOprtAsct The operators associativity + \throw nothrow + */ + QmuParserCallback::QmuParserCallback(fun_type2 a_pFun, + bool a_bAllowOpti, + int a_iPrec, + EOprtAssociativity a_eOprtAsct) + :m_pFun((void*)a_pFun) + ,m_iArgc(2) + ,m_iPri(a_iPrec) + ,m_eOprtAsct(a_eOprtAsct) + ,m_iCode(cmOPRT_BIN) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(3) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(4) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(5) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(6) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(7) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(8) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(9) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(10) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(0) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(1) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + /** \brief Constructor for constructing funcstion callbacks taking two arguments. + \throw nothrow + */ + QmuParserCallback::QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(2) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(3) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(4) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(5) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(6) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(7) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(8) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(9) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(10) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_BULK) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(-1) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC) + ,m_iType(tpDBL) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(0) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_STR) + ,m_iType(tpSTR) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(1) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_STR) + ,m_iType(tpSTR) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + QmuParserCallback::QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti) + :m_pFun((void*)a_pFun) + ,m_iArgc(2) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmFUNC_STR) + ,m_iType(tpSTR) + ,m_bAllowOpti(a_bAllowOpti) + {} + + + //--------------------------------------------------------------------------- + /** \brief Default constructor. + \throw nothrow + */ + QmuParserCallback::QmuParserCallback() + :m_pFun(0) + ,m_iArgc(0) + ,m_iPri(-1) + ,m_eOprtAsct(oaNONE) + ,m_iCode(cmUNKNOWN) + ,m_iType(tpVOID) + ,m_bAllowOpti(0) + {} + + + //--------------------------------------------------------------------------- + /** \brief Copy constructor. + \throw nothrow + */ + QmuParserCallback::QmuParserCallback(const QmuParserCallback &ref) + { + m_pFun = ref.m_pFun; + m_iArgc = ref.m_iArgc; + m_bAllowOpti = ref.m_bAllowOpti; + m_iCode = ref.m_iCode; + m_iType = ref.m_iType; + m_iPri = ref.m_iPri; + m_eOprtAsct = ref.m_eOprtAsct; + } + + //--------------------------------------------------------------------------- + /** \brief Clone this instance and return a pointer to the new instance. */ + QmuParserCallback* QmuParserCallback::Clone() const + { + return new QmuParserCallback(*this); + } + + //--------------------------------------------------------------------------- + /** \brief Return tru if the function is conservative. + + Conservative functions return always the same result for the same argument. + \throw nothrow + */ + bool QmuParserCallback::IsOptimizable() const + { + return m_bAllowOpti; + } + + //--------------------------------------------------------------------------- + /** \brief Get the callback address for the parser function. + + The type of the address is void. It needs to be recasted according to the + argument number to the right type. + + \throw nothrow + \return #pFun + */ + void* QmuParserCallback::GetAddr() const + { + return m_pFun; + } + + //--------------------------------------------------------------------------- + /** \brief Return the callback code. */ + ECmdCode QmuParserCallback::GetCode() const + { + return m_iCode; + } + + //--------------------------------------------------------------------------- + ETypeCode QmuParserCallback::GetType() const + { + return m_iType; + } + + + //--------------------------------------------------------------------------- + /** \brief Return the operator precedence. + \throw nothrown + + Only valid if the callback token is an operator token (binary or infix). + */ + int QmuParserCallback::GetPri() const + { + return m_iPri; + } + + //--------------------------------------------------------------------------- + /** \brief Return the operators associativity. + \throw nothrown + + Only valid if the callback token is a binary operator token. + */ + EOprtAssociativity QmuParserCallback::GetAssociativity() const + { + return m_eOprtAsct; + } + + //--------------------------------------------------------------------------- + /** \brief Returns the number of function Arguments. */ + int QmuParserCallback::GetArgc() const + { + return m_iArgc; + } +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparsercallback.h b/src/libs/qmuparser/qmuparsercallback.h new file mode 100644 index 000000000..2aa6d3a77 --- /dev/null +++ b/src/libs/qmuparser/qmuparsercallback.h @@ -0,0 +1,115 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERCALLBACK_H +#define QMUPARSERCALLBACK_H + +#include "qmuparserdef.h" + +/** \file + \brief Definition of the parser callback class. +*/ + +namespace qmu +{ + +/** \brief Encapsulation of prototypes for a numerical parser function. + + Encapsulates the prototyp for numerical parser functions. The class + stores the number of arguments for parser functions as well + as additional flags indication the function is non optimizeable. + The pointer to the callback function pointer is stored as void* + and needs to be casted according to the argument count. + Negative argument counts indicate a parser function with a variable number + of arguments. + + \author (C) 2004-2011 Ingo Berg +*/ +class QmuParserCallback +{ +public: + QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC); + QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity); + QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti); + + QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti); + + QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti); + QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti); + QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti); + QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti); + QmuParserCallback(); + QmuParserCallback(const QmuParserCallback &a_Fun); + + QmuParserCallback* Clone() const; + + bool IsOptimizable() const; + void* GetAddr() const; + ECmdCode GetCode() const; + ETypeCode GetType() const; + int GetPri() const; + EOprtAssociativity GetAssociativity() const; + int GetArgc() const; + +private: + void *m_pFun; ///< Pointer to the callback function, casted to void + + /** \brief Number of numeric function arguments + + This number is negative for functions with variable number of arguments. in this cases + they represent the actual number of arguments found. + */ + int m_iArgc; + int m_iPri; ///< Valid only for binary and infix operators; Operator precedence. + EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators + ECmdCode m_iCode; + ETypeCode m_iType; + bool m_bAllowOpti; ///< Flag indication optimizeability +}; + +//------------------------------------------------------------------------------ +/** \brief Container for Callback objects. */ +typedef std::map funmap_type; + +} // namespace qmu + +#endif + diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h new file mode 100644 index 000000000..40d7de54d --- /dev/null +++ b/src/libs/qmuparser/qmuparserdef.h @@ -0,0 +1,366 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPDEF_H +#define QMUPDEF_H + +#include +#include +#include +#include + +#include "qmuparserfixes.h" + +/** \file + \brief This file contains standard definitions used by the parser. +*/ + +#define QMUP_VERSION _T("2.2.3") +#define QMUP_VERSION_DATE _T("20121222; SF") + +#define QMUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + +/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */ +//#define MUP_MATH_EXCEPTIONS + +/** \brief Define the base datatype for values. + + This datatype must be a built in value type. You can not use custom classes. + It should be working with all types except "int"! +*/ +#define QMUP_BASETYPE double + +/** \brief Activate this option in order to compile with OpenMP support. + + OpenMP is used only in the bulk mode it may increase the performance a bit. +*/ +//#define MUP_USE_OPENMP + +#if defined(_UNICODE) + /** \brief Definition of the basic parser string type. */ + #define MUP_STRING_TYPE std::wstring + + #if !defined(_T) + #define _T(x) L##x + #endif // not defined _T +#else + #ifndef _T + #define _T(x) x + #endif + + /** \brief Definition of the basic parser string type. */ + #define MUP_STRING_TYPE std::string +#endif + +#if defined(_DEBUG) + /** \brief Debug macro to force an abortion of the programm with a certain message. + */ + #define MUP_FAIL(MSG) \ + { \ + bool MSG=false; \ + assert(MSG); \ + } + + /** \brief An assertion that does not kill the program. + + This macro is neutralised in UNICODE builds. It's + too difficult to translate. + */ + #define MUP_ASSERT(COND) \ + if (!(COND)) \ + { \ + stringstream_type ss; \ + ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \ + << __FILE__ << _T(" line ") \ + << __LINE__ << _T("."); \ + throw ParserError( ss.str() ); \ + } +#else + #define MUP_FAIL(MSG) + #define MUP_ASSERT(COND) +#endif + + +namespace qmu +{ +#if defined(_UNICODE) + + //------------------------------------------------------------------------------ + /** \brief Encapsulate wcout. */ + inline std::wostream& console() + { + return std::wcout; + } + + /** \brief Encapsulate cin. */ + inline std::wistream& console_in() + { + return std::wcin; + } + +#else + + /** \brief Encapsulate cout. + + Used for supporting UNICODE more easily. + */ + inline std::ostream& console() + { + return std::cout; + } + + /** \brief Encapsulate cin. + + Used for supporting UNICODE more easily. + */ + inline std::istream& console_in() + { + return std::cin; + } + +#endif + + //------------------------------------------------------------------------------ + /** \brief Bytecode values. + + \attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt! + */ + enum ECmdCode + { + // The following are codes for built in binary operators + // apart from built in operators the user has the opportunity to + // add user defined operators. + cmLE = 0, ///< Operator item: less or equal + cmGE = 1, ///< Operator item: greater or equal + cmNEQ = 2, ///< Operator item: not equal + cmEQ = 3, ///< Operator item: equals + cmLT = 4, ///< Operator item: less than + cmGT = 5, ///< Operator item: greater than + cmADD = 6, ///< Operator item: add + cmSUB = 7, ///< Operator item: subtract + cmMUL = 8, ///< Operator item: multiply + cmDIV = 9, ///< Operator item: division + cmPOW = 10, ///< Operator item: y to the power of ... + cmLAND = 11, + cmLOR = 12, + cmASSIGN = 13, ///< Operator item: Assignment operator + cmBO = 14, ///< Operator item: opening bracket + cmBC = 15, ///< Operator item: closing bracket + cmIF = 16, ///< For use in the ternary if-then-else operator + cmELSE = 17, ///< For use in the ternary if-then-else operator + cmENDIF = 18, ///< For use in the ternary if-then-else operator + cmARG_SEP = 19, ///< function argument separator + cmVAR = 20, ///< variable item + cmVAL = 21, ///< value item + + // For optimization purposes + cmVARPOW2, + cmVARPOW3, + cmVARPOW4, + cmVARMUL, + cmPOW2, + + // operators and functions + cmFUNC, ///< Code for a generic function item + cmFUNC_STR, ///< Code for a function with a string parameter + cmFUNC_BULK, ///< Special callbacks for Bulk mode with an additional parameter for the bulk index + cmSTRING, ///< Code for a string token + cmOPRT_BIN, ///< user defined binary operator + cmOPRT_POSTFIX, ///< code for postfix operators + cmOPRT_INFIX, ///< code for infix operators + cmEND, ///< end of formula + cmUNKNOWN ///< uninitialized item + }; + + //------------------------------------------------------------------------------ + /** \brief Types internally used by the parser. + */ + enum ETypeCode + { + tpSTR = 0, ///< String type (Function arguments and constants only, no string variables) + tpDBL = 1, ///< Floating point variables + tpVOID = 2 ///< Undefined type. + }; + + //------------------------------------------------------------------------------ + enum EParserVersionInfo + { + pviBRIEF, + pviFULL + }; + + //------------------------------------------------------------------------------ + /** \brief Parser operator precedence values. */ + enum EOprtAssociativity + { + oaLEFT = 0, + oaRIGHT = 1, + oaNONE = 2 + }; + + //------------------------------------------------------------------------------ + /** \brief Parser operator precedence values. */ + enum EOprtPrecedence + { + // binary operators + prLOR = 1, + prLAND = 2, + prLOGIC = 3, ///< logic operators + prCMP = 4, ///< comparsion operators + prADD_SUB = 5, ///< addition + prMUL_DIV = 6, ///< multiplication/division + prPOW = 7, ///< power operator priority (highest) + + // infix operators + prINFIX = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator + prPOSTFIX = 6 ///< Postfix operator priority (currently unused) + }; + + //------------------------------------------------------------------------------ + // basic types + + /** \brief The numeric datatype used by the parser. + + Normally this is a floating point type either single or double precision. + */ + typedef QMUP_BASETYPE value_type; + + /** \brief The stringtype used by the parser. + + Depends on wether UNICODE is used or not. + */ + typedef MUP_STRING_TYPE string_type; + + /** \brief The character type used by the parser. + + Depends on wether UNICODE is used or not. + */ + typedef string_type::value_type char_type; + + /** \brief Typedef for easily using stringstream that respect the parser stringtype. */ + typedef std::basic_stringstream, + std::allocator > stringstream_type; + + // Data container types + + /** \brief Type used for storing variables. */ + typedef std::map varmap_type; + + /** \brief Type used for storing constants. */ + typedef std::map valmap_type; + + /** \brief Type for assigning a string name to an index in the internal string table. */ + typedef std::map strmap_type; + + // Parser callbacks + + /** \brief Callback type used for functions without arguments. */ + typedef value_type (*generic_fun_type)(); + + /** \brief Callback type used for functions without arguments. */ + typedef value_type (*fun_type0)(); + + /** \brief Callback type used for functions with a single arguments. */ + typedef value_type (*fun_type1)(value_type); + + /** \brief Callback type used for functions with two arguments. */ + typedef value_type (*fun_type2)(value_type, value_type); + + /** \brief Callback type used for functions with three arguments. */ + typedef value_type (*fun_type3)(value_type, value_type, value_type); + + /** \brief Callback type used for functions with four arguments. */ + typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions without arguments. */ + typedef value_type (*bulkfun_type0)(int, int); + + /** \brief Callback type used for functions with a single arguments. */ + typedef value_type (*bulkfun_type1)(int, int, value_type); + + /** \brief Callback type used for functions with two arguments. */ + typedef value_type (*bulkfun_type2)(int, int, value_type, value_type); + + /** \brief Callback type used for functions with three arguments. */ + typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type); + + /** \brief Callback type used for functions with four arguments. */ + typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with five arguments. */ + typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + + /** \brief Callback type used for functions with a variable argument list. */ + typedef value_type (*multfun_type)(const value_type*, int); + + /** \brief Callback type used for functions taking a string as an argument. */ + typedef value_type (*strfun_type1)(const char_type*); + + /** \brief Callback type used for functions taking a string and a value as arguments. */ + typedef value_type (*strfun_type2)(const char_type*, value_type); + + /** \brief Callback type used for functions taking a string and two values as arguments. */ + typedef value_type (*strfun_type3)(const char_type*, value_type, value_type); + + /** \brief Callback used for functions that identify values in a string. */ + typedef int (*identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal); + + /** \brief Callback used for variable creation factory functions. */ + typedef value_type* (*facfun_type)(const char_type*, void*); +} // end of namespace + +#endif + diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp new file mode 100644 index 000000000..86b7bce20 --- /dev/null +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -0,0 +1,334 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsererror.h" + + +namespace qmu +{ + const QmuParserErrorMsg QmuParserErrorMsg::m_Instance; + + //------------------------------------------------------------------------------ + const QmuParserErrorMsg& QmuParserErrorMsg::Instance() + { + return m_Instance; + } + + //------------------------------------------------------------------------------ + string_type QmuParserErrorMsg::operator[](unsigned a_iIdx) const + { + return (a_iIdx + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERERROR_H +#define QMUPARSERERROR_H + +#include +#include +#include +#include +#include +#include + +#include "qmuparserdef.h" + +/** \file + \brief This file defines the error class used by the parser. +*/ + +namespace qmu +{ + +/** \brief Error codes. */ +enum EErrorCodes +{ + // Formula syntax errors + ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found + ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified. + ecUNEXPECTED_EOF = 2, ///< Unexpected end of formula. (Example: "2+sin(") + ecUNEXPECTED_ARG_SEP = 3, ///< An unexpected comma has been found. (Example: "1,23") + ecUNEXPECTED_ARG = 4, ///< An unexpected argument has been found + ecUNEXPECTED_VAL = 5, ///< An unexpected value token has been found + ecUNEXPECTED_VAR = 6, ///< An unexpected variable token has been found + ecUNEXPECTED_PARENS = 7, ///< Unexpected Parenthesis, opening or closing + ecUNEXPECTED_STR = 8, ///< A string has been found at an inapropriate position + ecSTRING_EXPECTED = 9, ///< A string function has been called with a different type of argument + ecVAL_EXPECTED = 10, ///< A numerical function has been called with a non value type of argument + ecMISSING_PARENS = 11, ///< Missing parens. (Example: "3*sin(3") + ecUNEXPECTED_FUN = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)") + ecUNTERMINATED_STRING = 13, ///< unterminated string constant. (Example: "3*valueof("hello)") + ecTOO_MANY_PARAMS = 14, ///< Too many function parameters + ecTOO_FEW_PARAMS = 15, ///< Too few function parameters. (Example: "ite(1<2,2)") + ecOPRT_TYPE_CONFLICT = 16, ///< binary operators may only be applied to value items of the same type + ecSTR_RESULT = 17, ///< result is a string + + // Invalid Parser input Parameters + ecINVALID_NAME = 18, ///< Invalid function, variable or constant name. + ecINVALID_BINOP_IDENT = 19, ///< Invalid binary operator identifier + ecINVALID_INFIX_IDENT = 20, ///< Invalid function, variable or constant name. + ecINVALID_POSTFIX_IDENT = 21, ///< Invalid function, variable or constant name. + + ecBUILTIN_OVERLOAD = 22, ///< Trying to overload builtin operator + ecINVALID_FUN_PTR = 23, ///< Invalid callback function pointer + ecINVALID_VAR_PTR = 24, ///< Invalid variable pointer + ecEMPTY_EXPRESSION = 25, ///< The Expression is empty + ecNAME_CONFLICT = 26, ///< Name conflict + ecOPT_PRI = 27, ///< Invalid operator priority + // + ecDOMAIN_ERROR = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused) + ecDIV_BY_ZERO = 29, ///< Division by zero (currently unused) + ecGENERIC = 30, ///< Generic error + ecLOCALE = 31, ///< Conflict with current locale + + ecUNEXPECTED_CONDITIONAL = 32, + ecMISSING_ELSE_CLAUSE = 33, + ecMISPLACED_COLON = 34, + + // internal errors + ecINTERNAL_ERROR = 35, ///< Internal error of any kind. + + // The last two are special entries + ecCOUNT, ///< This is no error code, It just stores just the total number of error codes + ecUNDEFINED = -1 ///< Undefined message, placeholder to detect unassigned error messages +}; + +//--------------------------------------------------------------------------- +/** \brief A class that handles the error messages. +*/ +class QmuParserErrorMsg +{ +public: + typedef QmuParserErrorMsg self_type; + + QmuParserErrorMsg& operator=(const QmuParserErrorMsg &); + QmuParserErrorMsg(const QmuParserErrorMsg&); + QmuParserErrorMsg(); + + ~QmuParserErrorMsg(); + + static const QmuParserErrorMsg& Instance(); + string_type operator[](unsigned a_iIdx) const; + +private: + std::vector m_vErrMsg; ///< A vector with the predefined error messages + static const self_type m_Instance; ///< The instance pointer +}; + +//--------------------------------------------------------------------------- +/** \brief Error class of the parser. + \author Ingo Berg + + Part of the math parser package. +*/ +class QmuParserError +{ +private: + + /** \brief Replace all ocuurences of a substring with another string. */ + void ReplaceSubString( string_type &strSource, + const string_type &strFind, + const string_type &strReplaceWith); + void Reset(); + +public: + + QmuParserError(); + explicit QmuParserError(EErrorCodes a_iErrc); + explicit QmuParserError(const string_type &sMsg); + QmuParserError( EErrorCodes a_iErrc, + const string_type &sTok, + const string_type &sFormula = string_type(), + int a_iPos = -1); + QmuParserError( EErrorCodes a_iErrc, + int a_iPos, + const string_type &sTok); + QmuParserError( const char_type *a_szMsg, + int a_iPos = -1, + const string_type &sTok = string_type()); + QmuParserError(const QmuParserError &a_Obj); + QmuParserError& operator=(const QmuParserError &a_Obj); + ~QmuParserError(); + + void SetFormula(const string_type &a_strFormula); + const string_type& GetExpr() const; + const string_type& GetMsg() const; + std::size_t GetPos() const; + const string_type& GetToken() const; + EErrorCodes GetCode() const; + +private: + string_type m_strMsg; ///< The message string + string_type m_strFormula; ///< Formula string + string_type m_strTok; ///< Token related with the error + int m_iPos; ///< Formula position related to the error + EErrorCodes m_iErrc; ///< Error code + const QmuParserErrorMsg &m_ErrMsg; +}; + +} // namespace qmu + +#endif + diff --git a/src/libs/qmuparser/qmuparserfixes.h b/src/libs/qmuparser/qmuparserfixes.h new file mode 100644 index 000000000..f0d529a63 --- /dev/null +++ b/src/libs/qmuparser/qmuparserfixes.h @@ -0,0 +1,59 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERFIXES_H +#define QMUPARSERFIXES_H + +/** \file + \brief This file contains compatibility fixes for some platforms. +*/ + +// +// Compatibility fixes +// + +//--------------------------------------------------------------------------- +// +// Intel Compiler +// +//--------------------------------------------------------------------------- + +#ifdef __INTEL_COMPILER + +// remark #981: operands are evaluated in unspecified order +// disabled -> completely pointless if the functions do not have side effects +// +#pragma warning(disable:981) + +// remark #383: value copied to temporary, reference to temporary used +#pragma warning(disable:383) + +// remark #1572: floating-point equality and inequality comparisons are unreliable +// disabled -> everyone knows it, the parser passes this problem +// deliberately to the user +#pragma warning(disable:1572) + +#endif + +#endif // include guard + + diff --git a/src/libs/qmuparser/qmuparserint.cpp b/src/libs/qmuparser/qmuparserint.cpp new file mode 100644 index 000000000..f1627adaa --- /dev/null +++ b/src/libs/qmuparser/qmuparserint.cpp @@ -0,0 +1,277 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparserint.h" + +#include +#include +#include + +using namespace std; + +/** \file + \brief Implementation of a parser using integer value. +*/ + +/** \brief Namespace for mathematical applications. */ +namespace qmu +{ +value_type QmuParserInt::Abs(value_type v) { return (value_type)Round(fabs((double)v)); } +value_type QmuParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; } +value_type QmuParserInt::Ite(value_type v1, + value_type v2, + value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); } +value_type QmuParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); } +value_type QmuParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); } +value_type QmuParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); } +value_type QmuParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); } +value_type QmuParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); } +value_type QmuParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); } +value_type QmuParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); } +value_type QmuParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); } +value_type QmuParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); } +value_type QmuParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); } +value_type QmuParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); } +value_type QmuParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); } +value_type QmuParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); } +value_type QmuParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); } +value_type QmuParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); } +value_type QmuParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); } +value_type QmuParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); } +value_type QmuParserInt::Not(value_type v) { return !Round(v); } + +value_type QmuParserInt::Pow(value_type v1, value_type v2) +{ + return std::pow((double)Round(v1), (double)Round(v2)); +} + +//--------------------------------------------------------------------------- +// Unary operator Callbacks: Infix operators +value_type QmuParserInt::UnaryMinus(value_type v) +{ + return -Round(v); +} + +//--------------------------------------------------------------------------- +value_type QmuParserInt::Sum(const value_type* a_afArg, int a_iArgc) +{ + if (!a_iArgc) + throw QmuParserError(_T("too few arguments for function sum.")); + + value_type fRes=0; + for (int i=0; i> iVal; + if (stream.fail()) + return 0; + + stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading + if (stream.fail()) + iEnd = stream.str().length(); + + if (iEnd==(stringstream_type::pos_type)-1) + return 0; + + *a_iPos += (int)iEnd; + *a_fVal = (value_type)iVal; + return 1; +} + +//--------------------------------------------------------------------------- +/** \brief Check a given position in the expression for the presence of + a hex value. + \param a_szExpr Pointer to the expression string + \param [in/out] a_iPos Pointer to an interger value holding the current parsing + position in the expression. + \param [out] a_fVal Pointer to the position where the detected value shall be stored. + + Hey values must be prefixed with "0x" in order to be detected properly. +*/ +int QmuParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) +{ + if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) + return 0; + + unsigned iVal(0); + + // New code based on streams for UNICODE compliance: + stringstream_type::pos_type nPos(0); + stringstream_type ss(a_szExpr + 2); + ss >> std::hex >> iVal; + nPos = ss.tellg(); + + if (nPos==(stringstream_type::pos_type)0) + return 1; + + *a_iPos += (int)(2 + nPos); + *a_fVal = (value_type)iVal; + return 1; +} + +//--------------------------------------------------------------------------- +int QmuParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) +{ + if (a_szExpr[0]!='#') + return 0; + + unsigned iVal(0), + iBits(sizeof(iVal)*8), + i(0); + + for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i> (iBits-i) ); + *a_iPos += i+1; + + return 1; +} + +//--------------------------------------------------------------------------- +/** \brief Constructor. + + Call ParserBase class constructor and trigger Function, Operator and Constant initialization. +*/ +QmuParserInt::QmuParserInt() + :QmuParserBase() +{ + AddValIdent(IsVal); // lowest priority + AddValIdent(IsBinVal); + AddValIdent(IsHexVal); // highest priority + + InitCharSets(); + InitFun(); + InitOprt(); +} + +//--------------------------------------------------------------------------- +void QmuParserInt::InitConst() +{ +} + +//--------------------------------------------------------------------------- +void QmuParserInt::InitCharSets() +{ + DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") ); + DefineOprtChars( _T("+-*^/?<>=!%&|~'_") ); + DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") ); +} + +//--------------------------------------------------------------------------- +/** \brief Initialize the default functions. */ +void QmuParserInt::InitFun() +{ + DefineFun( _T("sign"), Sign); + DefineFun( _T("abs"), Abs); + DefineFun( _T("if"), Ite); + DefineFun( _T("sum"), Sum); + DefineFun( _T("min"), Min); + DefineFun( _T("max"), Max); +} + +//--------------------------------------------------------------------------- +/** \brief Initialize operators. */ +void QmuParserInt::InitOprt() +{ + // disable all built in operators, not all of them usefull for integer numbers + // (they don't do rounding of values) + EnableBuiltInOprt(false); + + // Disable all built in operators, they wont work with integer numbers + // since they are designed for floating point numbers + DefineInfixOprt( _T("-"), UnaryMinus); + DefineInfixOprt( _T("!"), Not); + + DefineOprt( _T("&"), LogAnd, prLOGIC); + DefineOprt( _T("|"), LogOr, prLOGIC); + DefineOprt( _T("&&"), And, prLOGIC); + DefineOprt( _T("||"), Or, prLOGIC); + + DefineOprt( _T("<"), Less, prCMP); + DefineOprt( _T(">"), Greater, prCMP); + DefineOprt( _T("<="), LessEq, prCMP); + DefineOprt( _T(">="), GreaterEq, prCMP); + DefineOprt( _T("=="), Equal, prCMP); + DefineOprt( _T("!="), NotEqual, prCMP); + + DefineOprt( _T("+"), Add, prADD_SUB); + DefineOprt( _T("-"), Sub, prADD_SUB); + + DefineOprt( _T("*"), Mul, prMUL_DIV); + DefineOprt( _T("/"), Div, prMUL_DIV); + DefineOprt( _T("%"), Mod, prMUL_DIV); + + DefineOprt( _T("^"), Pow, prPOW, oaRIGHT); + DefineOprt( _T(">>"), Shr, prMUL_DIV+1); + DefineOprt( _T("<<"), Shl, prMUL_DIV+1); +} + +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparserint.h b/src/libs/qmuparser/qmuparserint.h new file mode 100644 index 000000000..1333142d5 --- /dev/null +++ b/src/libs/qmuparser/qmuparserint.h @@ -0,0 +1,132 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERINT_H +#define QMUPARSERINT_H + +#include "qmuparserbase.h" +#include + + +/** \file + \brief Definition of a parser using integer value. +*/ + + +namespace qmu +{ + +/** \brief Mathematical expressions parser. + + This version of the parser handles only integer numbers. It disables the built in operators thus it is + slower than muParser. Integer values are stored in the double value_type and converted if needed. +*/ +class QmuParserInt : public QmuParserBase +{ +private: + static int Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); }; + + static value_type Abs(value_type); + static value_type Sign(value_type); + static value_type Ite(value_type, value_type, value_type); + // !! The unary Minus is a MUST, otherwise you cant use negative signs !! + static value_type UnaryMinus(value_type); + // Functions with variable number of arguments + static value_type Sum(const value_type* a_afArg, int a_iArgc); // sum + static value_type Min(const value_type* a_afArg, int a_iArgc); // minimum + static value_type Max(const value_type* a_afArg, int a_iArgc); // maximum + // binary operator callbacks + static value_type Add(value_type v1, value_type v2); + static value_type Sub(value_type v1, value_type v2); + static value_type Mul(value_type v1, value_type v2); + static value_type Div(value_type v1, value_type v2); + static value_type Mod(value_type v1, value_type v2); + static value_type Pow(value_type v1, value_type v2); + static value_type Shr(value_type v1, value_type v2); + static value_type Shl(value_type v1, value_type v2); + static value_type LogAnd(value_type v1, value_type v2); + static value_type LogOr(value_type v1, value_type v2); + static value_type And(value_type v1, value_type v2); + static value_type Or(value_type v1, value_type v2); + static value_type Xor(value_type v1, value_type v2); + static value_type Less(value_type v1, value_type v2); + static value_type Greater(value_type v1, value_type v2); + static value_type LessEq(value_type v1, value_type v2); + static value_type GreaterEq(value_type v1, value_type v2); + static value_type Equal(value_type v1, value_type v2); + static value_type NotEqual(value_type v1, value_type v2); + static value_type Not(value_type v1); + + static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); + static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); + static int IsVal (const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); + + /** \brief A facet class used to change decimal and thousands separator. */ + template + class change_dec_sep : public std::numpunct + { + public: + + explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) + :std::numpunct() + ,m_cDecPoint(cDecSep) + ,m_cThousandsSep(cThousandsSep) + ,m_nGroup(nGroup) + {} + + protected: + + virtual char_type do_decimal_point() const + { + return m_cDecPoint; + } + + virtual char_type do_thousands_sep() const + { + return m_cThousandsSep; + } + + virtual std::string do_grouping() const + { + return std::string(1, m_nGroup); + } + + private: + + int m_nGroup; + char_type m_cDecPoint; + char_type m_cThousandsSep; + }; + +public: + QmuParserInt(); + + virtual void InitFun(); + virtual void InitOprt(); + virtual void InitConst(); + virtual void InitCharSets(); +}; + +} // namespace qmu + +#endif + diff --git a/src/libs/qmuparser/qmuparserstack.h b/src/libs/qmuparser/qmuparserstack.h new file mode 100644 index 000000000..6c4cae6ea --- /dev/null +++ b/src/libs/qmuparser/qmuparserstack.h @@ -0,0 +1,122 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERSTACK_H +#define QMUPARSERSTACK_H + +#include +#include +#include +#include + +#include "qmuparsererror.h" +#include "qmuparsertoken.h" + +/** \file + \brief This file defines the stack used by muparser. +*/ + +namespace qmu +{ + + /** \brief Parser stack implementation. + + Stack implementation based on a std::stack. The behaviour of pop() had been + slightly changed in order to get an error code if the stack is empty. + The stack is used within the Parser both as a value stack and as an operator stack. + + \author (C) 2004-2011 Ingo Berg + */ + template + class QmuParserStack + { + private: + + /** \brief Type of the underlying stack implementation. */ + typedef std::stack > impl_type; + + impl_type m_Stack; ///< This is the actual stack. + + public: + + //--------------------------------------------------------------------------- + QmuParserStack() + :m_Stack() + {} + + //--------------------------------------------------------------------------- + virtual ~QmuParserStack() + {} + + //--------------------------------------------------------------------------- + /** \brief Pop a value from the stack. + + Unlike the standard implementation this function will return the value that + is going to be taken from the stack. + + \throw ParserException in case the stack is empty. + \sa pop(int &a_iErrc) + */ + TValueType pop() + { + if (empty()) + throw QmuParserError( _T("stack is empty.") ); + + TValueType el = top(); + m_Stack.pop(); + return el; + } + + /** \brief Push an object into the stack. + + \param a_Val object to push into the stack. + \throw nothrow + */ + void push(const TValueType& a_Val) + { + m_Stack.push(a_Val); + } + + /** \brief Return the number of stored elements. */ + unsigned size() const + { + return (unsigned)m_Stack.size(); + } + + /** \brief Returns true if stack is empty false otherwise. */ + bool empty() const + { + return m_Stack.size()==0; + } + + /** \brief Return reference to the top object in the stack. + + The top object is the one pushed most recently. + */ + TValueType& top() + { + return m_Stack.top(); + } + }; +} // namespace MathUtils + +#endif diff --git a/src/libs/qmuparser/qmuparsertemplatemagic.h b/src/libs/qmuparser/qmuparsertemplatemagic.h new file mode 100644 index 000000000..324d659a9 --- /dev/null +++ b/src/libs/qmuparser/qmuparsertemplatemagic.h @@ -0,0 +1,150 @@ +#ifndef QMUPARSERTEMPLATEMAGIC_H +#define QMUPARSERTEMPLATEMAGIC_H + +#include +#include "muParserError.h" + + +namespace qmu +{ + //----------------------------------------------------------------------------------------------- + // + // Compile time type detection + // + //----------------------------------------------------------------------------------------------- + + /** \brief A class singling out integer types at compile time using + template meta programming. + */ + template + struct TypeInfo + { + static bool IsInteger() { return false; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + template<> + struct TypeInfo + { + static bool IsInteger() { return true; } + }; + + + //----------------------------------------------------------------------------------------------- + // + // Standard math functions with dummy overload for integer types + // + //----------------------------------------------------------------------------------------------- + + /** \brief A template class for providing wrappers for essential math functions. + + This template is spezialized for several types in order to provide a unified interface + for parser internal math function calls regardless of the data type. + */ + template + struct MathImpl + { + static T Sin(T v) { return sin(v); } + static T Cos(T v) { return cos(v); } + static T Tan(T v) { return tan(v); } + static T ASin(T v) { return asin(v); } + static T ACos(T v) { return acos(v); } + static T ATan(T v) { return atan(v); } + static T ATan2(T v1, T v2) { return atan2(v1, v2); } + static T Sinh(T v) { return sinh(v); } + static T Cosh(T v) { return cosh(v); } + static T Tanh(T v) { return tanh(v); } + static T ASinh(T v) { return log(v + sqrt(v * v + 1)); } + static T ACosh(T v) { return log(v + sqrt(v * v - 1)); } + static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); } + static T Log(T v) { return log(v); } + static T Log2(T v) { return log(v)/log((T)2); } // Logarithm base 2 + static T Log10(T v) { return log10(v); } // Logarithm base 10 + static T Exp(T v) { return exp(v); } + static T Abs(T v) { return (v>=0) ? v : -v; } + static T Sqrt(T v) { return sqrt(v); } + static T Rint(T v) { return floor(v + (T)0.5); } + static T Sign(T v) { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); } + static T Pow(T v1, T v2) { return std::pow(v1, v2); } + }; + + // Create (mostly) dummy math function definitions for integer types. They are mostly + // empty since they are not applicable for integer values. +#define MAKE_MATH_DUMMY(TYPE) \ + template<> \ + struct MathImpl \ + { \ + static TYPE Sin(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Cos(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Tan(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ASin(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ACos(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ATan(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ATan2(TYPE, TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Sinh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Cosh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Tanh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ASinh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ACosh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE ATanh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Log(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Log2(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Log10(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Exp(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Abs(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Sqrt(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Rint(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \ + static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \ + }; + + MAKE_MATH_DUMMY(char) + MAKE_MATH_DUMMY(short) + MAKE_MATH_DUMMY(int) + MAKE_MATH_DUMMY(long) + +#undef MAKE_MATH_DUMMY +} + +#endif diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp new file mode 100644 index 000000000..ce6e508ea --- /dev/null +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -0,0 +1,1447 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsertest.h" + +#include +#include +#include +#include + +#define PARSER_CONST_PI 3.141592653589793238462643 +#define PARSER_CONST_E 2.718281828459045235360287 + +using namespace std; + +/** \file + \brief This file contains the implementation of parser test cases. +*/ + +namespace qmu +{ + namespace Test + { + int QmuParserTester::c_iCount = 0; + + //--------------------------------------------------------------------------------------------- + QmuParserTester::QmuParserTester() + :m_vTestFun() + { + AddTest(&QmuParserTester::TestNames); + AddTest(&QmuParserTester::TestSyntax); + AddTest(&QmuParserTester::TestPostFix); + AddTest(&QmuParserTester::TestInfixOprt); + AddTest(&QmuParserTester::TestVarConst); + AddTest(&QmuParserTester::TestMultiArg); + AddTest(&QmuParserTester::TestExpression); + AddTest(&QmuParserTester::TestIfThenElse); + AddTest(&QmuParserTester::TestInterface); + AddTest(&QmuParserTester::TestBinOprt); + AddTest(&QmuParserTester::TestException); + AddTest(&QmuParserTester::TestStrArg); + + QmuParserTester::c_iCount = 0; + } + + //--------------------------------------------------------------------------------------------- + int QmuParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) + { + if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) + return 0; + + unsigned iVal(0); + + // New code based on streams for UNICODE compliance: + stringstream_type::pos_type nPos(0); + stringstream_type ss(a_szExpr + 2); + ss >> std::hex >> iVal; + nPos = ss.tellg(); + + if (nPos==(stringstream_type::pos_type)0) + return 1; + + *a_iPos += (int)(2 + nPos); + *a_fVal = (value_type)iVal; + return 1; + } + + //--------------------------------------------------------------------------------------------- + int QmuParserTester::TestInterface() + { + int iStat = 0; + mu::console() << _T("testing member functions..."); + + // Test RemoveVar + value_type afVal[3] = {1,2,3}; + QmuParser p; + + try + { + p.DefineVar( _T("a"), &afVal[0]); + p.DefineVar( _T("b"), &afVal[1]); + p.DefineVar( _T("c"), &afVal[2]); + p.SetExpr( _T("a+b+c") ); + p.Eval(); + } + catch(...) + { + iStat += 1; // this is not supposed to happen + } + + try + { + p.RemoveVar( _T("c") ); + p.Eval(); + iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... + } + catch(...) + { + // failure is expected... + } + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + //--------------------------------------------------------------------------------------------- + int QmuParserTester::TestStrArg() + { + int iStat = 0; + mu::console() << _T("testing string arguments..."); + + iStat += EqnTest(_T("valueof(\"\")"), 123, true); // empty string arguments caused a crash + iStat += EqnTest(_T("valueof(\"aaa\")+valueof(\"bbb\") "), 246, true); + iStat += EqnTest(_T("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323, true); + // use in expressions with variables + iStat += EqnTest(_T("a*(atof(\"10\")-b)"), 8, true); + iStat += EqnTest(_T("a-(atof(\"10\")*b)"), -19, true); + // string + numeric arguments + iStat += EqnTest(_T("strfun1(\"100\")"), 100, true); + iStat += EqnTest(_T("strfun2(\"100\",1)"), 101, true); + iStat += EqnTest(_T("strfun3(\"99\",1,2)"), 102, true); + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + //--------------------------------------------------------------------------------------------- + int QmuParserTester::TestBinOprt() + { + int iStat = 0; + mu::console() << _T("testing binary operators..."); + + // built in operators + // xor operator + //iStat += EqnTest(_T("1 xor 2"), 3, true); + //iStat += EqnTest(_T("a xor b"), 3, true); // with a=1 and b=2 + //iStat += EqnTest(_T("1 xor 2 xor 3"), 0, true); + //iStat += EqnTest(_T("a xor b xor 3"), 0, true); // with a=1 and b=2 + //iStat += EqnTest(_T("a xor b xor c"), 0, true); // with a=1 and b=2 + //iStat += EqnTest(_T("(1 xor 2) xor 3"), 0, true); + //iStat += EqnTest(_T("(a xor b) xor c"), 0, true); // with a=1 and b=2 + //iStat += EqnTest(_T("(a) xor (b) xor c"), 0, true); // with a=1 and b=2 + //iStat += EqnTest(_T("1 or 2"), 3, true); + //iStat += EqnTest(_T("a or b"), 3, true); // with a=1 and b=2 + iStat += EqnTest(_T("a++b"), 3, true); + iStat += EqnTest(_T("a ++ b"), 3, true); + iStat += EqnTest(_T("1++2"), 3, true); + iStat += EqnTest(_T("1 ++ 2"), 3, true); + iStat += EqnTest(_T("a add b"), 3, true); + iStat += EqnTest(_T("1 add 2"), 3, true); + iStat += EqnTest(_T("aa"), 1, true); + iStat += EqnTest(_T("a>a"), 0, true); + iStat += EqnTest(_T("aa"), 0, true); + iStat += EqnTest(_T("a<=a"), 1, true); + iStat += EqnTest(_T("a<=b"), 1, true); + iStat += EqnTest(_T("b<=a"), 0, true); + iStat += EqnTest(_T("a>=a"), 1, true); + iStat += EqnTest(_T("b>=a"), 1, true); + iStat += EqnTest(_T("a>=b"), 0, true); + + // Test logical operators, expecially if user defined "&" and the internal "&&" collide + iStat += EqnTest(_T("1 && 1"), 1, true); + iStat += EqnTest(_T("1 && 0"), 0, true); + iStat += EqnTest(_T("(aa)"), 1, true); + iStat += EqnTest(_T("(ab)"), 0, true); + //iStat += EqnTest(_T("12 and 255"), 12, true); + //iStat += EqnTest(_T("12 and 0"), 0, true); + iStat += EqnTest(_T("12 & 255"), 12, true); + iStat += EqnTest(_T("12 & 0"), 0, true); + iStat += EqnTest(_T("12&255"), 12, true); + iStat += EqnTest(_T("12&0"), 0, true); + + // Assignement operator + iStat += EqnTest(_T("a = b"), 2, true); + iStat += EqnTest(_T("a = sin(b)"), 0.909297, true); + iStat += EqnTest(_T("a = 1+sin(b)"), 1.909297, true); + iStat += EqnTest(_T("(a=b)*2"), 4, true); + iStat += EqnTest(_T("2*(a=b)"), 4, true); + iStat += EqnTest(_T("2*(a=b+1)"), 6, true); + iStat += EqnTest(_T("(a=b+1)*2"), 6, true); + + iStat += EqnTest(_T("2^2^3"), 256, true); + iStat += EqnTest(_T("1/2/3"), 1.0/6.0, true); + + // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 + iStat += EqnTest(_T("3+4*2/(1-5)^2^3"), 3.0001220703125, true); + + // Test user defined binary operators + iStat += EqnTestInt(_T("1 | 2"), 3, true); + iStat += EqnTestInt(_T("1 || 2"), 1, true); + iStat += EqnTestInt(_T("123 & 456"), 72, true); + iStat += EqnTestInt(_T("(123 & 456) % 10"), 2, true); + iStat += EqnTestInt(_T("1 && 0"), 0, true); + iStat += EqnTestInt(_T("123 && 456"), 1, true); + iStat += EqnTestInt(_T("1 << 3"), 8, true); + iStat += EqnTestInt(_T("8 >> 3"), 1, true); + iStat += EqnTestInt(_T("9 / 4"), 2, true); + iStat += EqnTestInt(_T("9 % 4"), 1, true); + iStat += EqnTestInt(_T("if(5%2,1,0)"), 1, true); + iStat += EqnTestInt(_T("if(4%2,1,0)"), 0, true); + iStat += EqnTestInt(_T("-10+1"), -9, true); + iStat += EqnTestInt(_T("1+2*3"), 7, true); + iStat += EqnTestInt(_T("const1 != const2"), 1, true); + iStat += EqnTestInt(_T("const1 != const2"), 0, false); + iStat += EqnTestInt(_T("const1 == const2"), 0, true); + iStat += EqnTestInt(_T("const1 == 1"), 1, true); + iStat += EqnTestInt(_T("10*(const1 == 1)"), 10, true); + iStat += EqnTestInt(_T("2*(const1 | const2)"), 6, true); + iStat += EqnTestInt(_T("2*(const1 | const2)"), 7, false); + iStat += EqnTestInt(_T("const1 < const2"), 1, true); + iStat += EqnTestInt(_T("const2 > const1"), 1, true); + iStat += EqnTestInt(_T("const1 <= 1"), 1, true); + iStat += EqnTestInt(_T("const2 >= 2"), 1, true); + iStat += EqnTestInt(_T("2*(const1 + const2)"), 6, true); + iStat += EqnTestInt(_T("2*(const1 - const2)"), -2, true); + iStat += EqnTestInt(_T("a != b"), 1, true); + iStat += EqnTestInt(_T("a != b"), 0, false); + iStat += EqnTestInt(_T("a == b"), 0, true); + iStat += EqnTestInt(_T("a == 1"), 1, true); + iStat += EqnTestInt(_T("10*(a == 1)"), 10, true); + iStat += EqnTestInt(_T("2*(a | b)"), 6, true); + iStat += EqnTestInt(_T("2*(a | b)"), 7, false); + iStat += EqnTestInt(_T("a < b"), 1, true); + iStat += EqnTestInt(_T("b > a"), 1, true); + iStat += EqnTestInt(_T("a <= 1"), 1, true); + iStat += EqnTestInt(_T("b >= 2"), 1, true); + iStat += EqnTestInt(_T("2*(a + b)"), 6, true); + iStat += EqnTestInt(_T("2*(a - b)"), -2, true); + iStat += EqnTestInt(_T("a + (a << b)"), 5, true); + iStat += EqnTestInt(_T("-2^2"), -4, true); + iStat += EqnTestInt(_T("3--a"), 4, true); + iStat += EqnTestInt(_T("3+-3^2"), -6, true); + + // Test reading of hex values: + iStat += EqnTestInt(_T("0xff"), 255, true); + iStat += EqnTestInt(_T("10+0xff"), 265, true); + iStat += EqnTestInt(_T("0xff+10"), 265, true); + iStat += EqnTestInt(_T("10*0xff"), 2550, true); + iStat += EqnTestInt(_T("0xff*10"), 2550, true); + iStat += EqnTestInt(_T("10+0xff+1"), 266, true); + iStat += EqnTestInt(_T("1+0xff+10"), 266, true); + +// incorrect: '^' is yor here, not power +// iStat += EqnTestInt("-(1+2)^2", -9, true); +// iStat += EqnTestInt("-1^3", -1, true); + + // Test precedence + // a=1, b=2, c=3 + iStat += EqnTestInt(_T("a + b * c"), 7, true); + iStat += EqnTestInt(_T("a * b + c"), 5, true); + iStat += EqnTestInt(_T("a10"), 0, true); + iStat += EqnTestInt(_T("a"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("?<"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("**"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("xor"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("and"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("or"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("not"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, _T("!"), f1of1) + // Binary operator + // The following must fail with builtin operators activated + // p.EnableBuiltInOp(true); -> this is the default + p.ClearPostfixOprt(); + PARSER_THROWCHECK(Oprt, false, _T("+"), f1of2) + PARSER_THROWCHECK(Oprt, false, _T("-"), f1of2) + PARSER_THROWCHECK(Oprt, false, _T("*"), f1of2) + PARSER_THROWCHECK(Oprt, false, _T("/"), f1of2) + PARSER_THROWCHECK(Oprt, false, _T("^"), f1of2) + PARSER_THROWCHECK(Oprt, false, _T("&&"), f1of2) + PARSER_THROWCHECK(Oprt, false, _T("||"), f1of2) + // without activated built in operators it should work + p.EnableBuiltInOprt(false); + PARSER_THROWCHECK(Oprt, true, _T("+"), f1of2) + PARSER_THROWCHECK(Oprt, true, _T("-"), f1of2) + PARSER_THROWCHECK(Oprt, true, _T("*"), f1of2) + PARSER_THROWCHECK(Oprt, true, _T("/"), f1of2) + PARSER_THROWCHECK(Oprt, true, _T("^"), f1of2) + PARSER_THROWCHECK(Oprt, true, _T("&&"), f1of2) + PARSER_THROWCHECK(Oprt, true, _T("||"), f1of2) + #undef PARSER_THROWCHECK + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + //--------------------------------------------------------------------------- + int QmuParserTester::TestSyntax() + { + int iStat = 0; + mu::console() << _T("testing syntax engine..."); + + iStat += ThrowTest(_T("1,"), ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest(_T("a,"), ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest(_T("sin(8),"), ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest(_T("(sin(8)),"), ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest(_T("a{m},"), ecUNEXPECTED_EOF); // incomplete hex definition + + iStat += EqnTest(_T("(1+ 2*a)"), 3, true); // Spaces within formula + iStat += EqnTest(_T("sqrt((4))"), 2, true); // Multiple brackets + iStat += EqnTest(_T("sqrt((2)+2)"), 2, true);// Multiple brackets + iStat += EqnTest(_T("sqrt(2+(2))"), 2, true);// Multiple brackets + iStat += EqnTest(_T("sqrt(a+(3))"), 2, true);// Multiple brackets + iStat += EqnTest(_T("sqrt((3)+a)"), 2, true);// Multiple brackets + iStat += EqnTest(_T("order(1,2)"), 1, true); // May not cause name collision with operator "or" + iStat += EqnTest(_T("(2+"), 0, false); // missing closing bracket + iStat += EqnTest(_T("2++4"), 0, false); // unexpected operator + iStat += EqnTest(_T("2+-4"), 0, false); // unexpected operator + iStat += EqnTest(_T("(2+)"), 0, false); // unexpected closing bracket + iStat += EqnTest(_T("--2"), 0, false); // double sign + iStat += EqnTest(_T("ksdfj"), 0, false); // unknown token + iStat += EqnTest(_T("()"), 0, false); // empty bracket without a function + iStat += EqnTest(_T("5+()"), 0, false); // empty bracket without a function + iStat += EqnTest(_T("sin(cos)"), 0, false); // unexpected function + iStat += EqnTest(_T("5t6"), 0, false); // unknown token + iStat += EqnTest(_T("5 t 6"), 0, false); // unknown token + iStat += EqnTest(_T("8*"), 0, false); // unexpected end of formula + iStat += EqnTest(_T(",3"), 0, false); // unexpected comma + iStat += EqnTest(_T("3,5"), 0, false); // unexpected comma + iStat += EqnTest(_T("sin(8,8)"), 0, false); // too many function args + iStat += EqnTest(_T("(7,8)"), 0, false); // too many function args + iStat += EqnTest(_T("sin)"), 0, false); // unexpected closing bracket + iStat += EqnTest(_T("a)"), 0, false); // unexpected closing bracket + iStat += EqnTest(_T("pi)"), 0, false); // unexpected closing bracket + iStat += EqnTest(_T("sin(())"), 0, false); // unexpected closing bracket + iStat += EqnTest(_T("sin()"), 0, false); // unexpected closing bracket + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + //--------------------------------------------------------------------------- + int QmuParserTester::TestVarConst() + { + int iStat = 0; + mu::console() << _T("testing variable/constant detection..."); + + // Test if the result changes when a variable changes + iStat += EqnTestWithVarChange( _T("a"), 1, 1, 2, 2 ); + iStat += EqnTestWithVarChange( _T("2*a"), 2, 4, 3, 6 ); + + // distinguish constants with same basename + iStat += EqnTest( _T("const"), 1, true); + iStat += EqnTest( _T("const1"), 2, true); + iStat += EqnTest( _T("const2"), 3, true); + iStat += EqnTest( _T("2*const"), 2, true); + iStat += EqnTest( _T("2*const1"), 4, true); + iStat += EqnTest( _T("2*const2"), 6, true); + iStat += EqnTest( _T("2*const+1"), 3, true); + iStat += EqnTest( _T("2*const1+1"), 5, true); + iStat += EqnTest( _T("2*const2+1"), 7, true); + iStat += EqnTest( _T("const"), 0, false); + iStat += EqnTest( _T("const1"), 0, false); + iStat += EqnTest( _T("const2"), 0, false); + + // distinguish variables with same basename + iStat += EqnTest( _T("a"), 1, true); + iStat += EqnTest( _T("aa"), 2, true); + iStat += EqnTest( _T("2*a"), 2, true); + iStat += EqnTest( _T("2*aa"), 4, true); + iStat += EqnTest( _T("2*a-1"), 1, true); + iStat += EqnTest( _T("2*aa-1"), 3, true); + + // custom value recognition + iStat += EqnTest( _T("0xff"), 255, true); + iStat += EqnTest( _T("0x97 + 0xff"), 406, true); + + // Finally test querying of used variables + try + { + int idx; + qmu::QmuParser p; + qmu::value_type vVarVal[] = { 1, 2, 3, 4, 5}; + p.DefineVar( _T("a"), &vVarVal[0]); + p.DefineVar( _T("b"), &vVarVal[1]); + p.DefineVar( _T("c"), &vVarVal[2]); + p.DefineVar( _T("d"), &vVarVal[3]); + p.DefineVar( _T("e"), &vVarVal[4]); + + // Test lookup of defined variables + // 4 used variables + p.SetExpr( _T("a+b+c+d") ); + mu::varmap_type UsedVar = p.GetUsedVar(); + int iCount = (int)UsedVar.size(); + if (iCount!=4) + throw false; + + // the next check will fail if the parser + // erroneousely creates new variables internally + if (p.GetVar().size()!=5) + throw false; + + mu::varmap_type::const_iterator item = UsedVar.begin(); + for (idx=0; item!=UsedVar.end(); ++item) + { + if (&vVarVal[idx++]!=item->second) + throw false; + } + + // Test lookup of undefined variables + p.SetExpr( _T("undef1+undef2+undef3") ); + UsedVar = p.GetUsedVar(); + iCount = (int)UsedVar.size(); + if (iCount!=3) + throw false; + + // the next check will fail if the parser + // erroneousely creates new variables internally + if (p.GetVar().size()!=5) + throw false; + + for (item = UsedVar.begin(); item!=UsedVar.end(); ++item) + { + if (item->second!=0) + throw false; // all pointers to undefined variables must be null + } + + // 1 used variables + p.SetExpr( _T("a+b") ); + UsedVar = p.GetUsedVar(); + iCount = (int)UsedVar.size(); + if (iCount!=2) throw false; + item = UsedVar.begin(); + for (idx=0; item!=UsedVar.end(); ++item) + if (&vVarVal[idx++]!=item->second) throw false; + + } + catch(...) + { + iStat += 1; + } + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + //--------------------------------------------------------------------------- + int QmuParserTester::TestMultiArg() + { + int iStat = 0; + mu::console() << _T("testing multiarg functions..."); + + // Compound expressions + iStat += EqnTest( _T("1,2,3"), 3, true); + iStat += EqnTest( _T("a,b,c"), 3, true); + iStat += EqnTest( _T("a=10,b=20,c=a*b"), 200, true); + iStat += EqnTest( _T("1,\n2,\n3"), 3, true); + iStat += EqnTest( _T("a,\nb,\nc"), 3, true); + iStat += EqnTest( _T("a=10,\nb=20,\nc=a*b"), 200, true); + iStat += EqnTest( _T("1,\r\n2,\r\n3"), 3, true); + iStat += EqnTest( _T("a,\r\nb,\r\nc"), 3, true); + iStat += EqnTest( _T("a=10,\r\nb=20,\r\nc=a*b"), 200, true); + + // picking the right argument + iStat += EqnTest( _T("f1of1(1)"), 1, true); + iStat += EqnTest( _T("f1of2(1, 2)"), 1, true); + iStat += EqnTest( _T("f2of2(1, 2)"), 2, true); + iStat += EqnTest( _T("f1of3(1, 2, 3)"), 1, true); + iStat += EqnTest( _T("f2of3(1, 2, 3)"), 2, true); + iStat += EqnTest( _T("f3of3(1, 2, 3)"), 3, true); + iStat += EqnTest( _T("f1of4(1, 2, 3, 4)"), 1, true); + iStat += EqnTest( _T("f2of4(1, 2, 3, 4)"), 2, true); + iStat += EqnTest( _T("f3of4(1, 2, 3, 4)"), 3, true); + iStat += EqnTest( _T("f4of4(1, 2, 3, 4)"), 4, true); + iStat += EqnTest( _T("f1of5(1, 2, 3, 4, 5)"), 1, true); + iStat += EqnTest( _T("f2of5(1, 2, 3, 4, 5)"), 2, true); + iStat += EqnTest( _T("f3of5(1, 2, 3, 4, 5)"), 3, true); + iStat += EqnTest( _T("f4of5(1, 2, 3, 4, 5)"), 4, true); + iStat += EqnTest( _T("f5of5(1, 2, 3, 4, 5)"), 5, true); + // Too few arguments / Too many arguments + iStat += EqnTest( _T("1+ping()"), 11, true); + iStat += EqnTest( _T("ping()+1"), 11, true); + iStat += EqnTest( _T("2*ping()"), 20, true); + iStat += EqnTest( _T("ping()*2"), 20, true); + iStat += EqnTest( _T("ping(1,2)"), 0, false); + iStat += EqnTest( _T("1+ping(1,2)"), 0, false); + iStat += EqnTest( _T("f1of1(1,2)"), 0, false); + iStat += EqnTest( _T("f1of1()"), 0, false); + iStat += EqnTest( _T("f1of2(1, 2, 3)"), 0, false); + iStat += EqnTest( _T("f1of2(1)"), 0, false); + iStat += EqnTest( _T("f1of3(1, 2, 3, 4)"), 0, false); + iStat += EqnTest( _T("f1of3(1)"), 0, false); + iStat += EqnTest( _T("f1of4(1, 2, 3, 4, 5)"), 0, false); + iStat += EqnTest( _T("f1of4(1)"), 0, false); + iStat += EqnTest( _T("(1,2,3)"), 0, false); + iStat += EqnTest( _T("1,2,3"), 0, false); + iStat += EqnTest( _T("(1*a,2,3)"), 0, false); + iStat += EqnTest( _T("1,2*a,3"), 0, false); + + // correct calculation of arguments + iStat += EqnTest( _T("min(a, 1)"), 1, true); + iStat += EqnTest( _T("min(3*2, 1)"), 1, true); + iStat += EqnTest( _T("min(3*2, 1)"), 6, false); + iStat += EqnTest( _T("firstArg(2,3,4)"), 2, true); + iStat += EqnTest( _T("lastArg(2,3,4)"), 4, true); + iStat += EqnTest( _T("min(3*a+1, 1)"), 1, true); + iStat += EqnTest( _T("max(3*a+1, 1)"), 4, true); + iStat += EqnTest( _T("max(3*a+1, 1)*2"), 8, true); + iStat += EqnTest( _T("2*max(3*a+1, 1)+2"), 10, true); + + // functions with Variable argument count + iStat += EqnTest( _T("sum(a)"), 1, true); + iStat += EqnTest( _T("sum(1,2,3)"), 6, true); + iStat += EqnTest( _T("sum(a,b,c)"), 6, true); + iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"), 4, true); + iStat += EqnTest( _T("2*sum(1,2,3)"), 12, true); + iStat += EqnTest( _T("2*sum(1,2,3)+2"), 14, true); + iStat += EqnTest( _T("2*sum(-1,2,3)+2"), 10, true); + iStat += EqnTest( _T("2*sum(-1,2,-(-a))+2"), 6, true); + iStat += EqnTest( _T("2*sum(-1,10,-a)+2"), 18, true); + iStat += EqnTest( _T("2*sum(1,2,3)*2"), 24, true); + iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"), 4, true); + iStat += EqnTest( _T("sum(1*3, 4, a+2)"), 10, true); + iStat += EqnTest( _T("sum(1*3, 2*sum(1,2,2), a+2)"), 16, true); + iStat += EqnTest( _T("sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)"), 24, true); + + // some failures + iStat += EqnTest( _T("sum()"), 0, false); + iStat += EqnTest( _T("sum(,)"), 0, false); + iStat += EqnTest( _T("sum(1,2,)"), 0, false); + iStat += EqnTest( _T("sum(,1,2)"), 0, false); + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + + //--------------------------------------------------------------------------- + int QmuParserTester::TestInfixOprt() + { + int iStat(0); + mu::console() << "testing infix operators..."; + + iStat += EqnTest( _T("-1"), -1, true); + iStat += EqnTest( _T("-(-1)"), 1, true); + iStat += EqnTest( _T("-(-1)*2"), 2, true); + iStat += EqnTest( _T("-(-2)*sqrt(4)"), 4, true); + iStat += EqnTest( _T("-_pi"), -PARSER_CONST_PI, true); + iStat += EqnTest( _T("-a"), -1, true); + iStat += EqnTest( _T("-(a)"), -1, true); + iStat += EqnTest( _T("-(-a)"), 1, true); + iStat += EqnTest( _T("-(-a)*2"), 2, true); + iStat += EqnTest( _T("-(8)"), -8, true); + iStat += EqnTest( _T("-8"), -8, true); + iStat += EqnTest( _T("-(2+1)"), -3, true); + iStat += EqnTest( _T("-(f1of1(1+2*3)+1*2)"), -9, true); + iStat += EqnTest( _T("-(-f1of1(1+2*3)+1*2)"), 5, true); + iStat += EqnTest( _T("-sin(8)"), -0.989358, true); + iStat += EqnTest( _T("3-(-a)"), 4, true); + iStat += EqnTest( _T("3--a"), 4, true); + iStat += EqnTest( _T("-1*3"), -3, true); + + // Postfix / infix priorities + iStat += EqnTest( _T("~2#"), 8, true); + iStat += EqnTest( _T("~f1of1(2)#"), 8, true); + iStat += EqnTest( _T("~(b)#"), 8, true); + iStat += EqnTest( _T("(~b)#"), 12, true); + iStat += EqnTest( _T("~(2#)"), 8, true); + iStat += EqnTest( _T("~(f1of1(2)#)"), 8, true); + // + iStat += EqnTest( _T("-2^2"),-4, true); + iStat += EqnTest( _T("-(a+b)^2"),-9, true); + iStat += EqnTest( _T("(-3)^2"),9, true); + iStat += EqnTest( _T("-(-2^2)"),4, true); + iStat += EqnTest( _T("3+-3^2"),-6, true); + // The following assumes use of sqr as postfix operator ("") together + // with a sign operator of low priority: + iStat += EqnTest( _T("-2'"), -4, true); + iStat += EqnTest( _T("-(1+1)'"),-4, true); + iStat += EqnTest( _T("2+-(1+1)'"),-2, true); + iStat += EqnTest( _T("2+-2'"), -2, true); + // This is the classic behaviour of the infix sign operator (here: "$") which is + // now deprecated: + iStat += EqnTest( _T("$2^2"),4, true); + iStat += EqnTest( _T("$(a+b)^2"),9, true); + iStat += EqnTest( _T("($3)^2"),9, true); + iStat += EqnTest( _T("$($2^2)"),-4, true); + iStat += EqnTest( _T("3+$3^2"),12, true); + + // infix operators sharing the first few characters + iStat += EqnTest( _T("~ 123"), 123+2, true); + iStat += EqnTest( _T("~~ 123"), 123+2, true); + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + + //--------------------------------------------------------------------------- + int QmuParserTester::TestPostFix() + { + int iStat = 0; + mu::console() << _T("testing postfix operators..."); + + // application + iStat += EqnTest( _T("3{m}+5"), 5.003, true); + iStat += EqnTest( _T("1000{m}"), 1, true); + iStat += EqnTest( _T("1000 {m}"), 1, true); + iStat += EqnTest( _T("(a){m}"), 1e-3, true); + iStat += EqnTest( _T("a{m}"), 1e-3, true); + iStat += EqnTest( _T("a {m}"), 1e-3, true); + iStat += EqnTest( _T("-(a){m}"), -1e-3, true); + iStat += EqnTest( _T("-2{m}"), -2e-3, true); + iStat += EqnTest( _T("-2 {m}"), -2e-3, true); + iStat += EqnTest( _T("f1of1(1000){m}"), 1, true); + iStat += EqnTest( _T("-f1of1(1000){m}"), -1, true); + iStat += EqnTest( _T("-f1of1(-1000){m}"), 1, true); + iStat += EqnTest( _T("f4of4(0,0,0,1000){m}"), 1, true); + iStat += EqnTest( _T("2+(a*1000){m}"), 3, true); + + // can postfix operators "m" und "meg" be told apart properly? + iStat += EqnTest( _T("2*3000meg+2"), 2*3e9+2, true); + + // some incorrect results + iStat += EqnTest( _T("1000{m}"), 0.1, false); + iStat += EqnTest( _T("(a){m}"), 2, false); + // failure due to syntax checking + iStat += ThrowTest(_T("0x"), ecUNASSIGNABLE_TOKEN); // incomplete hex definition + iStat += ThrowTest(_T("3+"), ecUNEXPECTED_EOF); + iStat += ThrowTest( _T("4 + {m}"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("{m}4"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("sin({m})"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("{m} {m}"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("{m}(8)"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("4,{m}"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("-{m}"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( _T("2(-{m})"), ecUNEXPECTED_PARENS); + iStat += ThrowTest( _T("2({m})"), ecUNEXPECTED_PARENS); + + iStat += ThrowTest( _T("multi*1.0"), ecUNASSIGNABLE_TOKEN); + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + //--------------------------------------------------------------------------- + int QmuParserTester::TestExpression() + { + int iStat = 0; + mu::console() << _T("testing expression samples..."); + + value_type b = 2; + + // Optimization + iStat += EqnTest( _T("2*b*5"), 20, true); + iStat += EqnTest( _T("2*b*5 + 4*b"), 28, true); + iStat += EqnTest( _T("2*a/3"), 2.0/3.0, true); + + // Addition auf cmVARMUL + iStat += EqnTest( _T("3+b"), b+3, true); + iStat += EqnTest( _T("b+3"), b+3, true); + iStat += EqnTest( _T("b*3+2"), b*3+2, true); + iStat += EqnTest( _T("3*b+2"), b*3+2, true); + iStat += EqnTest( _T("2+b*3"), b*3+2, true); + iStat += EqnTest( _T("2+3*b"), b*3+2, true); + iStat += EqnTest( _T("b+3*b"), b+3*b, true); + iStat += EqnTest( _T("3*b+b"), b+3*b, true); + + iStat += EqnTest( _T("2+b*3+b"), 2+b*3+b, true); + iStat += EqnTest( _T("b+2+b*3"), b+2+b*3, true); + + iStat += EqnTest( _T("(2*b+1)*4"), (2*b+1)*4, true); + iStat += EqnTest( _T("4*(2*b+1)"), (2*b+1)*4, true); + + // operator precedencs + iStat += EqnTest( _T("1+2-3*4/5^6"), 2.99923, true); + iStat += EqnTest( _T("1^2/3*4-5+6"), 2.33333333, true); + iStat += EqnTest( _T("1+2*3"), 7, true); + iStat += EqnTest( _T("1+2*3"), 7, true); + iStat += EqnTest( _T("(1+2)*3"), 9, true); + iStat += EqnTest( _T("(1+2)*(-3)"), -9, true); + iStat += EqnTest( _T("2/4"), 0.5, true); + + iStat += EqnTest( _T("exp(ln(7))"), 7, true); + iStat += EqnTest( _T("e^ln(7)"), 7, true); + iStat += EqnTest( _T("e^(ln(7))"), 7, true); + iStat += EqnTest( _T("(e^(ln(7)))"), 7, true); + iStat += EqnTest( _T("1-(e^(ln(7)))"), -6, true); + iStat += EqnTest( _T("2*(e^(ln(7)))"), 14, true); + iStat += EqnTest( _T("10^log(5)"), 5, true); + iStat += EqnTest( _T("10^log10(5)"), 5, true); + iStat += EqnTest( _T("2^log2(4)"), 4, true); + iStat += EqnTest( _T("-(sin(0)+1)"), -1, true); + iStat += EqnTest( _T("-(2^1.1)"), -2.14354692, true); + + iStat += EqnTest( _T("(cos(2.41)/b)"), -0.372056, true); + iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(a+b)))))))"), 2160, true); + iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"), 15120, true); + iStat += EqnTest( _T("(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))"), 0.00377999, true); + + // long formula (Reference: Matlab) + iStat += EqnTest( + _T("(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))") + _T("/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/") + _T("((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-") + _T("e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6") + _T("+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e") + _T("*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), -12.23016549, true); + + // long formula (Reference: Matlab) + iStat += EqnTest( + _T("(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e") + _T(")+a)))*2.77)"), -2.16995656, true); + + // long formula (Reference: Matlab) + iStat += EqnTest( _T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926, true); + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + + + //--------------------------------------------------------------------------- + int QmuParserTester::TestIfThenElse() + { + int iStat = 0; + mu::console() << _T("testing if-then-else operator..."); + + // Test error detection + iStat += ThrowTest(_T(":3"), ecUNEXPECTED_CONDITIONAL); + iStat += ThrowTest(_T("? 1 : 2"), ecUNEXPECTED_CONDITIONAL); + iStat += ThrowTest(_T("(ab) ? 10 : 11"), 11, true); + iStat += EqnTest(_T("(ab) ? c : d"), -2, true); + + iStat += EqnTest(_T("(a>b) ? 1 : 0"), 0, true); + iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : 2"), 2, true); + iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)"), 2, true); + iStat += EqnTest(_T("((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)"), 1, true); + + iStat += EqnTest(_T("sum((a>b) ? 1 : 2)"), 2, true); + iStat += EqnTest(_T("sum((1) ? 1 : 2)"), 1, true); + iStat += EqnTest(_T("sum((a>b) ? 1 : 2, 100)"), 102, true); + iStat += EqnTest(_T("sum((1) ? 1 : 2, 100)"), 101, true); + iStat += EqnTest(_T("sum(3, (a>b) ? 3 : 10)"), 13, true); + iStat += EqnTest(_T("sum(3, (ab) ? 3 : 10)"), 130, true); + iStat += EqnTest(_T("10*sum(3, (ab) ? 3 : 10)*10"), 130, true); + iStat += EqnTest(_T("sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab)&&(a2)&&(1<2) ? 128 : 255"), 255, true); + iStat += EqnTest(_T("((1<2)&&(1<2)) ? 128 : 255"), 128, true); + iStat += EqnTest(_T("((1>2)&&(1<2)) ? 128 : 255"), 255, true); + iStat += EqnTest(_T("((ab)&&(a0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255, true); + iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255, true); + iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128, true); + iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128, true); + iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32, true); + iStat += EqnTest(_T("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64, true); + iStat += EqnTest(_T("1>0 ? 50 : 1>0 ? 128 : 255"), 50, true); + iStat += EqnTest(_T("1>0 ? 50 : (1>0 ? 128 : 255)"), 50, true); + iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 50"), 128, true); + iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32, true); + iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32, true); + iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16"), 255, true); + iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255, true); + iStat += EqnTest(_T("1 ? 0 ? 128 : 255 : 1 ? 32 : 64"), 255, true); + + // assignment operators + iStat += EqnTest(_T("a= 0 ? 128 : 255, a"), 255, true); + iStat += EqnTest(_T("a=((a>b)&&(a + // this is now legal, for reference see: + // https://sourceforge.net/forum/message.php?msg_id=7411373 + // iStat += ThrowTest( _T("sin=9"), ecUNEXPECTED_OPERATOR); + //
+ + iStat += ThrowTest( _T("(8)=5"), ecUNEXPECTED_OPERATOR); + iStat += ThrowTest( _T("(a)=5"), ecUNEXPECTED_OPERATOR); + iStat += ThrowTest( _T("a=\"tttt\""), ecOPRT_TYPE_CONFLICT); + + if (iStat==0) + mu::console() << _T("passed") << endl; + else + mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + + return iStat; + } + + + //--------------------------------------------------------------------------- + void QmuParserTester::AddTest(testfun_type a_pFun) + { + m_vTestFun.push_back(a_pFun); + } + + //--------------------------------------------------------------------------- + void QmuParserTester::Run() + { + int iStat = 0; + try + { + for (int i=0; i<(int)m_vTestFun.size(); ++i) + iStat += (this->*m_vTestFun[i])(); + } + catch(QmuParser::exception_type &e) + { + mu::console() << "\n" << e.GetMsg() << endl; + mu::console() << e.GetToken() << endl; + Abort(); + } + catch(std::exception &e) + { + mu::console() << e.what() << endl; + Abort(); + } + catch(...) + { + mu::console() << "Internal error"; + Abort(); + } + + if (iStat==0) + { + mu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl; + } + else + { + mu::console() << "Test failed with " << iStat + << " errors (" << QmuParserTester::c_iCount + << " expressions)" << endl; + } + QmuParserTester::c_iCount = 0; + } + + + //--------------------------------------------------------------------------- + int QmuParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail) + { + QmuParserTester::c_iCount++; + + try + { + value_type fVal[] = {1,1,1}; + QmuParser p; + + p.DefineVar( _T("a"), &fVal[0]); + p.DefineVar( _T("b"), &fVal[1]); + p.DefineVar( _T("c"), &fVal[2]); + p.DefinePostfixOprt( _T("{m}"), Milli); + p.DefinePostfixOprt( _T("m"), Milli); + p.DefineFun( _T("ping"), Ping); + p.DefineFun( _T("valueof"), ValueOf); + p.DefineFun( _T("strfun1"), StrFun1); + p.DefineFun( _T("strfun2"), StrFun2); + p.DefineFun( _T("strfun3"), StrFun3); + p.SetExpr(a_str); + p.Eval(); + } + catch(QmuParserError &e) + { + // output the formula in case of an failed test + if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) + { + mu::console() << _T("\n ") + << _T("Expression: ") << a_str + << _T(" Code:") << e.GetCode() << _T("(") << e.GetMsg() << _T(")") + << _T(" Expected:") << a_iErrc; + } + + return (a_iErrc==e.GetCode()) ? 0 : 1; + } + + // if a_bFail==false no exception is expected + bool bRet((a_bFail==false) ? 0 : 1); + if (bRet==1) + { + mu::console() << _T("\n ") + << _T("Expression: ") << a_str + << _T(" did evaluate; Expected error:") << a_iErrc; + } + + return bRet; + } + + //--------------------------------------------------------------------------- + /** \brief Evaluate a tet expression. + + \return 1 in case of a failure, 0 otherwise. + */ + int QmuParserTester::EqnTestWithVarChange(const string_type &a_str, + double a_fVar1, + double a_fRes1, + double a_fVar2, + double a_fRes2) + { + QmuParserTester::c_iCount++; + value_type fVal[2] = {-999, -999 }; // should be equalinitially + + try + { + QmuParser p; + + // variable + value_type var = 0; + p.DefineVar( _T("a"), &var); + p.SetExpr(a_str); + + var = a_fVar1; + fVal[0] = p.Eval(); + + var = a_fVar2; + fVal[1] = p.Eval(); + + if ( fabs(a_fRes1-fVal[0]) > 0.0000000001) + throw std::runtime_error("incorrect result (first pass)"); + + if ( fabs(a_fRes2-fVal[1]) > 0.0000000001) + throw std::runtime_error("incorrect result (second pass)"); + } + catch(QmuParser::exception_type &e) + { + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")"); + return 1; + } + catch(std::exception &e) + { + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")"); + return 1; // always return a failure since this exception is not expected + } + catch(...) + { + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)"); + return 1; // exceptions other than ParserException are not allowed + } + + return 0; + } + + //--------------------------------------------------------------------------- + /** \brief Evaluate a tet expression. + + \return 1 in case of a failure, 0 otherwise. + */ + int QmuParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) + { + QmuParserTester::c_iCount++; + int iRet(0); + value_type fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different + + try + { + std::auto_ptr p1; + QmuParser p2, p3; // three parser objects + // they will be used for testing copy and assihnment operators + // p1 is a pointer since i'm going to delete it in order to test if + // parsers after copy construction still refer to members of it. + // !! If this is the case this function will crash !! + + p1.reset(new qmu::QmuParser()); + // Add constants + p1->DefineConst( _T("pi"), (value_type)PARSER_CONST_PI); + p1->DefineConst( _T("e"), (value_type)PARSER_CONST_E); + p1->DefineConst( _T("const"), 1); + p1->DefineConst( _T("const1"), 2); + p1->DefineConst( _T("const2"), 3); + // variables + value_type vVarVal[] = { 1, 2, 3, -2}; + p1->DefineVar( _T("a"), &vVarVal[0]); + p1->DefineVar( _T("aa"), &vVarVal[1]); + p1->DefineVar( _T("b"), &vVarVal[1]); + p1->DefineVar( _T("c"), &vVarVal[2]); + p1->DefineVar( _T("d"), &vVarVal[3]); + + // custom value ident functions + p1->AddValIdent(&QmuParserTester::IsHexVal); + + // functions + p1->DefineFun( _T("ping"), Ping); + p1->DefineFun( _T("f1of1"), f1of1); // one parameter + p1->DefineFun( _T("f1of2"), f1of2); // two parameter + p1->DefineFun( _T("f2of2"), f2of2); + p1->DefineFun( _T("f1of3"), f1of3); // three parameter + p1->DefineFun( _T("f2of3"), f2of3); + p1->DefineFun( _T("f3of3"), f3of3); + p1->DefineFun( _T("f1of4"), f1of4); // four parameter + p1->DefineFun( _T("f2of4"), f2of4); + p1->DefineFun( _T("f3of4"), f3of4); + p1->DefineFun( _T("f4of4"), f4of4); + p1->DefineFun( _T("f1of5"), f1of5); // five parameter + p1->DefineFun( _T("f2of5"), f2of5); + p1->DefineFun( _T("f3of5"), f3of5); + p1->DefineFun( _T("f4of5"), f4of5); + p1->DefineFun( _T("f5of5"), f5of5); + + // binary operators + p1->DefineOprt( _T("add"), add, 0); + p1->DefineOprt( _T("++"), add, 0); + p1->DefineOprt( _T("&"), land, prLAND); + + // sample functions + p1->DefineFun( _T("min"), Min); + p1->DefineFun( _T("max"), Max); + p1->DefineFun( _T("sum"), Sum); + p1->DefineFun( _T("valueof"), ValueOf); + p1->DefineFun( _T("atof"), StrToFloat); + p1->DefineFun( _T("strfun1"), StrFun1); + p1->DefineFun( _T("strfun2"), StrFun2); + p1->DefineFun( _T("strfun3"), StrFun3); + p1->DefineFun( _T("lastArg"), LastArg); + p1->DefineFun( _T("firstArg"), FirstArg); + p1->DefineFun( _T("order"), FirstArg); + + // infix / postfix operator + // Note: Identifiers used here do not have any meaning + // they are mere placeholders to test certain features. + p1->DefineInfixOprt( _T("$"), sign, prPOW+1); // sign with high priority + p1->DefineInfixOprt( _T("~"), plus2); // high priority + p1->DefineInfixOprt( _T("~~"), plus2); + p1->DefinePostfixOprt( _T("{m}"), Milli); + p1->DefinePostfixOprt( _T("{M}"), Mega); + p1->DefinePostfixOprt( _T("m"), Milli); + p1->DefinePostfixOprt( _T("meg"), Mega); + p1->DefinePostfixOprt( _T("#"), times3); + p1->DefinePostfixOprt( _T("'"), sqr); + p1->SetExpr(a_str); + + // Test bytecode integrity + // String parsing and bytecode parsing must yield the same result + fVal[0] = p1->Eval(); // result from stringparsing + fVal[1] = p1->Eval(); // result from bytecode + if (fVal[0]!=fVal[1]) + throw QmuParser::exception_type( _T("Bytecode / string parsing mismatch.") ); + + // Test copy and assignement operators + try + { + // Test copy constructor + std::vector vParser; + vParser.push_back(*(p1.get())); + qmu::QmuParser p2 = vParser[0]; // take parser from vector + + // destroy the originals from p2 + vParser.clear(); // delete the vector + p1.reset(0); + + fVal[2] = p2.Eval(); + + // Test assignement operator + // additionally disable Optimizer this time + qmu::QmuParser p3; + p3 = p2; + p3.EnableOptimizer(false); + fVal[3] = p3.Eval(); + + // Test Eval function for multiple return values + // use p2 since it has the optimizer enabled! + int nNum; + value_type *v = p2.Eval(nNum); + fVal[4] = v[nNum-1]; + } + catch(std::exception &e) + { + mu::console() << _T("\n ") << e.what() << _T("\n"); + } + + // limited floating point accuracy requires the following test + bool bCloseEnough(true); + for (unsigned i=0; i::has_infinity) + bCloseEnough &= (fabs(fVal[i]) != numeric_limits::infinity()); + } + + iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1; + + + if (iRet==1) + { + mu::console() << _T("\n fail: ") << a_str.c_str() + << _T(" (incorrect result; expected: ") << a_fRes + << _T(" ;calculated: ") << fVal[0] << _T(",") + << fVal[1] << _T(",") + << fVal[2] << _T(",") + << fVal[3] << _T(",") + << fVal[4] << _T(")."); + } + } + catch(QmuParser::exception_type &e) + { + if (a_fPass) + { + if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (copy construction)"); + else + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")"); + return 1; + } + } + catch(std::exception &e) + { + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")"); + return 1; // always return a failure since this exception is not expected + } + catch(...) + { + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)"); + return 1; // exceptions other than ParserException are not allowed + } + + return iRet; + } + + //--------------------------------------------------------------------------- + int QmuParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPass) + { + QmuParserTester::c_iCount++; + + value_type vVarVal[] = {1, 2, 3}; // variable values + value_type fVal[2] = {-99, -999}; // results: initially should be different + int iRet(0); + + try + { + QmuParserInt p; + p.DefineConst( _T("const1"), 1); + p.DefineConst( _T("const2"), 2); + p.DefineVar( _T("a"), &vVarVal[0]); + p.DefineVar( _T("b"), &vVarVal[1]); + p.DefineVar( _T("c"), &vVarVal[2]); + + p.SetExpr(a_str); + fVal[0] = p.Eval(); // result from stringparsing + fVal[1] = p.Eval(); // result from bytecode + + if (fVal[0]!=fVal[1]) + throw QmuParser::exception_type( _T("Bytecode corrupt.") ); + + iRet = ( (a_fRes==fVal[0] && a_fPass) || + (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1; + if (iRet==1) + { + mu::console() << _T("\n fail: ") << a_str.c_str() + << _T(" (incorrect result; expected: ") << a_fRes + << _T(" ;calculated: ") << fVal[0]<< _T(")."); + } + } + catch(QmuParser::exception_type &e) + { + if (a_fPass) + { + mu::console() << _T("\n fail: ") << e.GetExpr() << _T(" : ") << e.GetMsg(); + iRet = 1; + } + } + catch(...) + { + mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)"); + iRet = 1; // exceptions other than ParserException are not allowed + } + + return iRet; + } + + //--------------------------------------------------------------------------- + /** \brief Internal error in test class Test is going to be aborted. */ + void QmuParserTester::Abort() const + { + mu::console() << _T("Test failed (internal error in test class)") << endl; + while (!getchar()); + exit(-1); + } + } // namespace test +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h new file mode 100644 index 000000000..d6407060c --- /dev/null +++ b/src/libs/qmuparser/qmuparsertest.h @@ -0,0 +1,207 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTEST_H +#define QMUPARSERTEST_H + +#include +#include +#include // for accumulate +#include "qmuparser.h" +#include "qmuparserint.h" + +/** \file + \brief This file contains the parser test class. +*/ + +namespace qmu +{ + /** \brief Namespace for test cases. */ + namespace Test + { + //------------------------------------------------------------------------------ + /** \brief Test cases for unit testing. + + (C) 2004-2011 Ingo Berg + */ + class QmuParserTester // final + { + private: + static int c_iCount; + + // Multiarg callbacks + static value_type f1of1(value_type v) { return v;}; + + static value_type f1of2(value_type v, value_type ) {return v;}; + static value_type f2of2(value_type , value_type v) {return v;}; + + static value_type f1of3(value_type v, value_type , value_type ) {return v;}; + static value_type f2of3(value_type , value_type v, value_type ) {return v;}; + static value_type f3of3(value_type , value_type , value_type v) {return v;}; + + static value_type f1of4(value_type v, value_type, value_type , value_type ) {return v;} + static value_type f2of4(value_type , value_type v, value_type , value_type ) {return v;} + static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;} + static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;} + + static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; } + static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; } + static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; } + static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; } + static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; } + + static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1a_fVal2) ? a_fVal1 : a_fVal2; } + + static value_type plus2(value_type v1) { return v1+2; } + static value_type times3(value_type v1) { return v1*3; } + static value_type sqr(value_type v1) { return v1*v1; } + static value_type sign(value_type v) { return -v; } + static value_type add(value_type v1, value_type v2) { return v1+v2; } + static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; } + + + static value_type FirstArg(const value_type* a_afArg, int a_iArgc) + { + if (!a_iArgc) + throw qmu::QmuParser::exception_type( _T("too few arguments for function FirstArg.") ); + + return a_afArg[0]; + } + + static value_type LastArg(const value_type* a_afArg, int a_iArgc) + { + if (!a_iArgc) + throw qmu::QmuParser::exception_type( _T("too few arguments for function LastArg.") ); + + return a_afArg[a_iArgc-1]; + } + + static value_type Sum(const value_type* a_afArg, int a_iArgc) + { + if (!a_iArgc) + throw qmu::QmuParser::exception_type( _T("too few arguments for function sum.") ); + + value_type fRes=0; + for (int i=0; i> val; + return (value_type)val; + } + + static value_type StrFun2(const char_type* v1, value_type v2) + { + int val(0); + stringstream_type(v1) >> val; + return (value_type)(val + v2); + } + + static value_type StrFun3(const char_type* v1, value_type v2, value_type v3) + { + int val(0); + stringstream_type(v1) >> val; + return val + v2 + v3; + } + + static value_type StrToFloat(const char_type* a_szMsg) + { + value_type val(0); + stringstream_type(a_szMsg) >> val; + return val; + } + + // postfix operator callback + static value_type Mega(value_type a_fVal) { return a_fVal * (value_type)1e6; } + static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; } + static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; } + + // Custom value recognition + static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal); + + int TestNames(); + int TestSyntax(); + int TestMultiArg(); + int TestPostFix(); + int TestExpression(); + int TestInfixOprt(); + int TestBinOprt(); + int TestVarConst(); + int TestInterface(); + int TestException(); + int TestStrArg(); + int TestIfThenElse(); + + void Abort() const; + + public: + typedef int (QmuParserTester::*testfun_type)(); + + QmuParserTester(); + void Run(); + + private: + std::vector m_vTestFun; + void AddTest(testfun_type a_pFun); + + // Test Double Parser + int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass); + int EqnTestWithVarChange(const string_type& a_str, + double a_fRes1, + double a_fVar1, + double a_fRes2, + double a_fVar2); + int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true); + + // Test Int Parser + int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass); + }; + } // namespace Test +} // namespace qmu + +#endif + + diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h new file mode 100644 index 000000000..81a23ed7f --- /dev/null +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -0,0 +1,396 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTOKEN_H +#define QMUPARSERTOKEN_H + +#include +#include +#include +#include +#include + +#include "qmuparsererror.h" +#include "qmuparsercallback.h" + +/** \file + \brief This file contains the parser token definition. +*/ + +namespace qmu +{ + /** \brief Encapsulation of the data for a single formula token. + + Formula token implementation. Part of the Math Parser Package. + Formula tokens can be either one of the following: +
    +
  • value
  • +
  • variable
  • +
  • function with numerical arguments
  • +
  • functions with a string as argument
  • +
  • prefix operators
  • +
  • infix operators
  • +
  • binary operator
  • +
+ + \author (C) 2004-2013 Ingo Berg + */ + template + class QmuParserToken + { + private: + + ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. + ETypeCode m_iType; + void *m_pTok; ///< Stores Token pointer; not applicable for all tokens + int m_iIdx; ///< An otional index to an external buffer storing the token data + TString m_strTok; ///< Token string + TString m_strVal; ///< Value for string variables + value_type m_fVal; ///< the value + std::auto_ptr m_pCallback; + + public: + + //--------------------------------------------------------------------------- + /** \brief Constructor (default). + + Sets token to an neutral state of type cmUNKNOWN. + \throw nothrow + \sa ECmdCode + */ + QmuParserToken() + :m_iCode(cmUNKNOWN) + ,m_iType(tpVOID) + ,m_pTok(0) + ,m_iIdx(-1) + ,m_strTok() + ,m_pCallback() + {} + + //------------------------------------------------------------------------------ + /** \brief Create token from another one. + + Implemented by calling Assign(...) + \throw nothrow + \post m_iType==cmUNKNOWN + \sa #Assign + */ + QmuParserToken(const QmuParserToken &a_Tok) + { + Assign(a_Tok); + } + + //------------------------------------------------------------------------------ + /** \brief Assignement operator. + + Copy token state from another token and return this. + Implemented by calling Assign(...). + \throw nothrow + */ + QmuParserToken& operator=(const QmuParserToken &a_Tok) + { + Assign(a_Tok); + return *this; + } + + //------------------------------------------------------------------------------ + /** \brief Copy token information from argument. + + \throw nothrow + */ + void Assign(const QmuParserToken &a_Tok) + { + m_iCode = a_Tok.m_iCode; + m_pTok = a_Tok.m_pTok; + m_strTok = a_Tok.m_strTok; + m_iIdx = a_Tok.m_iIdx; + m_strVal = a_Tok.m_strVal; + m_iType = a_Tok.m_iType; + m_fVal = a_Tok.m_fVal; + // create new callback object if a_Tok has one + m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0); + } + + //------------------------------------------------------------------------------ + /** \brief Assign a token type. + + Token may not be of type value, variable or function. Those have seperate set functions. + + \pre [assert] a_iType!=cmVAR + \pre [assert] a_iType!=cmVAL + \pre [assert] a_iType!=cmFUNC + \post m_fVal = 0 + \post m_pTok = 0 + */ + QmuParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString()) + { + // The following types cant be set this way, they have special Set functions + assert(a_iType!=cmVAR); + assert(a_iType!=cmVAL); + assert(a_iType!=cmFUNC); + + m_iCode = a_iType; + m_iType = tpVOID; + m_pTok = 0; + m_strTok = a_strTok; + m_iIdx = -1; + + return *this; + } + + //------------------------------------------------------------------------------ + /** \brief Set Callback type. */ + QmuParserToken& Set(const QmuParserCallback &a_pCallback, const TString &a_sTok) + { + assert(a_pCallback.GetAddr()); + + m_iCode = a_pCallback.GetCode(); + m_iType = tpVOID; + m_strTok = a_sTok; + m_pCallback.reset(new QmuParserCallback(a_pCallback)); + + m_pTok = 0; + m_iIdx = -1; + + return *this; + } + + //------------------------------------------------------------------------------ + /** \brief Make this token a value token. + + Member variables not necessary for value tokens will be invalidated. + \throw nothrow + */ + QmuParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString()) + { + m_iCode = cmVAL; + m_iType = tpDBL; + m_fVal = a_fVal; + m_strTok = a_strTok; + m_iIdx = -1; + + m_pTok = 0; + m_pCallback.reset(0); + + return *this; + } + + //------------------------------------------------------------------------------ + /** \brief make this token a variable token. + + Member variables not necessary for variable tokens will be invalidated. + \throw nothrow + */ + QmuParserToken& SetVar(TBase *a_pVar, const TString &a_strTok) + { + m_iCode = cmVAR; + m_iType = tpDBL; + m_strTok = a_strTok; + m_iIdx = -1; + m_pTok = (void*)a_pVar; + m_pCallback.reset(0); + return *this; + } + + //------------------------------------------------------------------------------ + /** \brief Make this token a variable token. + + Member variables not necessary for variable tokens will be invalidated. + \throw nothrow + */ + QmuParserToken& SetString(const TString &a_strTok, std::size_t a_iSize) + { + m_iCode = cmSTRING; + m_iType = tpSTR; + m_strTok = a_strTok; + m_iIdx = static_cast(a_iSize); + + m_pTok = 0; + m_pCallback.reset(0); + return *this; + } + + //------------------------------------------------------------------------------ + /** \brief Set an index associated with the token related data. + + In cmSTRFUNC - This is the index to a string table in the main parser. + \param a_iIdx The index the string function result will take in the bytecode parser. + \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING + */ + void SetIdx(int a_iIdx) + { + if (m_iCode!=cmSTRING || a_iIdx<0) + throw QmuParserError(ecINTERNAL_ERROR); + + m_iIdx = a_iIdx; + } + + //------------------------------------------------------------------------------ + /** \brief Return Index associated with the token related data. + + In cmSTRFUNC - This is the index to a string table in the main parser. + + \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING + \return The index the result will take in the Bytecode calculatin array (#m_iIdx). + */ + int GetIdx() const + { + if (m_iIdx<0 || m_iCode!=cmSTRING ) + throw QmuParserError(ecINTERNAL_ERROR); + + return m_iIdx; + } + + //------------------------------------------------------------------------------ + /** \brief Return the token type. + + \return #m_iType + \throw nothrow + */ + ECmdCode GetCode() const + { + if (m_pCallback.get()) + { + return m_pCallback->GetCode(); + } + else + { + return m_iCode; + } + } + + //------------------------------------------------------------------------------ + ETypeCode GetType() const + { + if (m_pCallback.get()) + { + return m_pCallback->GetType(); + } + else + { + return m_iType; + } + } + + //------------------------------------------------------------------------------ + int GetPri() const + { + if ( !m_pCallback.get()) + throw QmuParserError(ecINTERNAL_ERROR); + + if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX) + throw QmuParserError(ecINTERNAL_ERROR); + + return m_pCallback->GetPri(); + } + + //------------------------------------------------------------------------------ + EOprtAssociativity GetAssociativity() const + { + if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN) + throw QmuParserError(ecINTERNAL_ERROR); + + return m_pCallback->GetAssociativity(); + } + + //------------------------------------------------------------------------------ + /** \brief Return the address of the callback function assoziated with + function and operator tokens. + + \return The pointer stored in #m_pTok. + \throw exception_type if token type is non of: +
    +
  • cmFUNC
  • +
  • cmSTRFUNC
  • +
  • cmPOSTOP
  • +
  • cmINFIXOP
  • +
  • cmOPRT_BIN
  • +
+ \sa ECmdCode + */ + generic_fun_type GetFuncAddr() const + { + return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0; + } + + //------------------------------------------------------------------------------ + /** \biref Get value of the token. + + Only applicable to variable and value tokens. + \throw exception_type if token is no value/variable token. + */ + TBase GetVal() const + { + switch (m_iCode) + { + case cmVAL: return m_fVal; + case cmVAR: return *((TBase*)m_pTok); + default: throw QmuParserError(ecVAL_EXPECTED); + } + } + + //------------------------------------------------------------------------------ + /** \brief Get address of a variable token. + + Valid only if m_iType==CmdVar. + \throw exception_type if token is no variable token. + */ + TBase* GetVar() const + { + if (m_iCode!=cmVAR) + throw QmuParserError(ecINTERNAL_ERROR); + + return (TBase*)m_pTok; + } + + //------------------------------------------------------------------------------ + /** \brief Return the number of function arguments. + + Valid only if m_iType==CmdFUNC. + */ + int GetArgCount() const + { + assert(m_pCallback.get()); + + if (!m_pCallback->GetAddr()) + throw QmuParserError(ecINTERNAL_ERROR); + + return m_pCallback->GetArgc(); + } + + //------------------------------------------------------------------------------ + /** \brief Return the token identifier. + + If #m_iType is cmSTRING the token identifier is the value of the string argument + for a string function. + \return #m_strTok + \throw nothrow + \sa m_strTok + */ + const TString& GetAsString() const + { + return m_strTok; + } + }; +} // namespace qmu + +#endif diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp new file mode 100644 index 000000000..81d7f4f20 --- /dev/null +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -0,0 +1,953 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "qmuparsertokenreader.h" +#include "qmuparserbase.h" + +/** \file + \brief This file contains the parser token reader implementation. +*/ + + +namespace qmu +{ + + // Forward declaration + class QmuParserBase; + + //--------------------------------------------------------------------------- + /** \brief Copy constructor. + + \sa Assign + \throw nothrow + */ + QmuParserTokenReader::QmuParserTokenReader(const QmuParserTokenReader &a_Reader) + { + Assign(a_Reader); + } + + //--------------------------------------------------------------------------- + /** \brief Assignement operator. + + Self assignement will be suppressed otherwise #Assign is called. + + \param a_Reader Object to copy to this token reader. + \throw nothrow + */ + QmuParserTokenReader& QmuParserTokenReader::operator=(const QmuParserTokenReader &a_Reader) + { + if (&a_Reader!=this) + Assign(a_Reader); + + return *this; + } + + //--------------------------------------------------------------------------- + /** \brief Assign state of a token reader to this token reader. + + \param a_Reader Object from which the state should be copied. + \throw nothrow + */ + void QmuParserTokenReader::Assign(const QmuParserTokenReader &a_Reader) + { + m_pParser = a_Reader.m_pParser; + m_strFormula = a_Reader.m_strFormula; + m_iPos = a_Reader.m_iPos; + m_iSynFlags = a_Reader.m_iSynFlags; + + m_UsedVar = a_Reader.m_UsedVar; + m_pFunDef = a_Reader.m_pFunDef; + m_pConstDef = a_Reader.m_pConstDef; + m_pVarDef = a_Reader.m_pVarDef; + m_pStrVarDef = a_Reader.m_pStrVarDef; + m_pPostOprtDef = a_Reader.m_pPostOprtDef; + m_pInfixOprtDef = a_Reader.m_pInfixOprtDef; + m_pOprtDef = a_Reader.m_pOprtDef; + m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar; + m_vIdentFun = a_Reader.m_vIdentFun; + m_pFactory = a_Reader.m_pFactory; + m_pFactoryData = a_Reader.m_pFactoryData; + m_iBrackets = a_Reader.m_iBrackets; + m_cArgSep = a_Reader.m_cArgSep; + } + + //--------------------------------------------------------------------------- + /** \brief Constructor. + + Create a Token reader and bind it to a parser object. + + \pre [assert] a_pParser may not be NULL + \post #m_pParser==a_pParser + \param a_pParent Parent parser object of the token reader. + */ + QmuParserTokenReader::QmuParserTokenReader(QmuParserBase *a_pParent) + :m_pParser(a_pParent) + ,m_strFormula() + ,m_iPos(0) + ,m_iSynFlags(0) + ,m_bIgnoreUndefVar(false) + ,m_pFunDef(NULL) + ,m_pPostOprtDef(NULL) + ,m_pInfixOprtDef(NULL) + ,m_pOprtDef(NULL) + ,m_pConstDef(NULL) + ,m_pStrVarDef(NULL) + ,m_pVarDef(NULL) + ,m_pFactory(NULL) + ,m_pFactoryData(NULL) + ,m_vIdentFun() + ,m_UsedVar() + ,m_fZero(0) + ,m_iBrackets(0) + ,m_lastTok() + ,m_cArgSep(',') + { + assert(m_pParser); + SetParent(m_pParser); + } + + //--------------------------------------------------------------------------- + /** \brief Create instance of a QParserTokenReader identical with this + and return its pointer. + + This is a factory method the calling function must take care of the object destruction. + + \return A new QParserTokenReader object. + \throw nothrow + */ + QmuParserTokenReader* QmuParserTokenReader::Clone(QmuParserBase *a_pParent) const + { + std::auto_ptr ptr(new QmuParserTokenReader(*this)); + ptr->SetParent(a_pParent); + return ptr.release(); + } + + //--------------------------------------------------------------------------- + QmuParserTokenReader::token_type& QmuParserTokenReader::SaveBeforeReturn(const token_type &tok) + { + m_lastTok = tok; + return m_lastTok; + } + + //--------------------------------------------------------------------------- + void QmuParserTokenReader::AddValIdent(identfun_type a_pCallback) + { + // Use push_front is used to give user defined callbacks a higher priority than + // the built in ones. Otherwise reading hex numbers would not work + // since the "0" in "0xff" would always be read first making parsing of + // the rest impossible. + // reference: + // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956 + m_vIdentFun.push_front(a_pCallback); + } + + //--------------------------------------------------------------------------- + void QmuParserTokenReader::SetVarCreator(facfun_type a_pFactory, void *pUserData) + { + m_pFactory = a_pFactory; + m_pFactoryData = pUserData; + } + + //--------------------------------------------------------------------------- + /** \brief Return the current position of the token reader in the formula string. + + \return #m_iPos + \throw nothrow + */ + int QmuParserTokenReader::GetPos() const + { + return m_iPos; + } + + //--------------------------------------------------------------------------- + /** \brief Return a reference to the formula. + + \return #m_strFormula + \throw nothrow + */ + const string_type& QmuParserTokenReader::GetExpr() const + { + return m_strFormula; + } + + //--------------------------------------------------------------------------- + /** \brief Return a map containing the used variables only. */ + varmap_type& QmuParserTokenReader::GetUsedVar() + { + return m_UsedVar; + } + + //--------------------------------------------------------------------------- + /** \brief Initialize the token Reader. + + Sets the formula position index to zero and set Syntax flags to default for initial formula parsing. + \pre [assert] triggered if a_szFormula==0 + */ + void QmuParserTokenReader::SetFormula(const string_type &a_strFormula) + { + m_strFormula = a_strFormula; + ReInit(); + } + + //--------------------------------------------------------------------------- + /** \brief Set Flag that contronls behaviour in case of undefined variables beeing found. + + If true, the parser does not throw an exception if an undefined variable is found. + otherwise it does. This variable is used internally only! + It supresses a "undefined variable" exception in GetUsedVar(). + Those function should return a complete list of variables including + those the are not defined by the time of it's call. + */ + void QmuParserTokenReader::IgnoreUndefVar(bool bIgnore) + { + m_bIgnoreUndefVar = bIgnore; + } + + //--------------------------------------------------------------------------- + /** \brief Reset the token reader to the start of the formula. + + The syntax flags will be reset to a value appropriate for the + start of a formula. + \post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR + \throw nothrow + \sa ESynCodes + */ + void QmuParserTokenReader::ReInit() + { + m_iPos = 0; + m_iSynFlags = sfSTART_OF_LINE; + m_iBrackets = 0; + m_UsedVar.clear(); + m_lastTok = token_type(); + } + + //--------------------------------------------------------------------------- + /** \brief Read the next token from the string. */ + QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken() + { + assert(m_pParser); + + std::stack FunArgs; + const char_type *szFormula = m_strFormula.c_str(); + token_type tok; + + // Ignore all non printable characters when reading the expression + while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20) + ++m_iPos; + + if ( IsEOF(tok) ) return SaveBeforeReturn(tok); // Check for end of formula + if ( IsOprt(tok) ) return SaveBeforeReturn(tok); // Check for user defined binary operator + if ( IsFunTok(tok) ) return SaveBeforeReturn(tok); // Check for function token + if ( IsBuiltIn(tok) ) return SaveBeforeReturn(tok); // Check built in operators / tokens + if ( IsArgSep(tok) ) return SaveBeforeReturn(tok); // Check for function argument separators + if ( IsValTok(tok) ) return SaveBeforeReturn(tok); // Check for values / constant tokens + if ( IsVarTok(tok) ) return SaveBeforeReturn(tok); // Check for variable tokens + if ( IsStrVarTok(tok) ) return SaveBeforeReturn(tok); // Check for string variables + if ( IsString(tok) ) return SaveBeforeReturn(tok); // Check for String tokens + if ( IsInfixOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators + if ( IsPostOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators + + // Check String for undefined variable token. Done only if a + // flag is set indicating to ignore undefined variables. + // This is a way to conditionally avoid an error if + // undefined variables occur. + // (The GetUsedVar function must suppress the error for + // undefined variables in order to collect all variable + // names including the undefined ones.) + if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) + return SaveBeforeReturn(tok); + + // Check for unknown token + // + // !!! From this point on there is no exit without an exception possible... + // + string_type strTok; + int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); + if (iEnd!=m_iPos) + Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok); + + Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos)); + return token_type(); // never reached + } + + //--------------------------------------------------------------------------- + void QmuParserTokenReader::SetParent(QmuParserBase *a_pParent) + { + m_pParser = a_pParent; + m_pFunDef = &a_pParent->m_FunDef; + m_pOprtDef = &a_pParent->m_OprtDef; + m_pInfixOprtDef = &a_pParent->m_InfixOprtDef; + m_pPostOprtDef = &a_pParent->m_PostOprtDef; + m_pVarDef = &a_pParent->m_VarDef; + m_pStrVarDef = &a_pParent->m_StrVarDef; + m_pConstDef = &a_pParent->m_ConstDef; + } + + //--------------------------------------------------------------------------- + /** \brief Extract all characters that belong to a certain charset. + + \param a_szCharSet [in] Const char array of the characters allowed in the token. + \param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. + \param a_iPos [in] Position in the string from where to start reading. + \return The Position of the first character not listed in a_szCharSet. + \throw nothrow + */ + int QmuParserTokenReader::ExtractToken(const char_type *a_szCharSet, + string_type &a_sTok, + int a_iPos) const + { + int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos); + + if (iEnd==(int)string_type::npos) + iEnd = (int)m_strFormula.length(); + + // Assign token string if there was something found + if (a_iPos!=iEnd) + a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd); + + return iEnd; + } + + //--------------------------------------------------------------------------- + /** \brief Check Expression for the presence of a binary operator token. + + Userdefined binary operator "++" gives inconsistent parsing result for + the equations "a++b" and "a ++ b" if alphabetic characters are allowed + in operator tokens. To avoid this this function checks specifically + for operator tokens. + */ + int QmuParserTokenReader::ExtractOperatorToken(string_type &a_sTok, + int a_iPos) const + { + int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos); + if (iEnd==(int)string_type::npos) + iEnd = (int)m_strFormula.length(); + + // Assign token string if there was something found + if (a_iPos!=iEnd) + { + a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd); + return iEnd; + } + else + { + // There is still the chance of having to deal with an operator consisting exclusively + // of alphabetic characters. + return ExtractToken(QMUP_CHARS, a_sTok, a_iPos); + } + } + + //--------------------------------------------------------------------------- + /** \brief Check if a built in operator or other token can be found + \param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. + \return true if an operator token has been found. + */ + bool QmuParserTokenReader::IsBuiltIn(token_type &a_Tok) + { + const char_type **const pOprtDef = m_pParser->GetOprtDef(), + *const szFormula = m_strFormula.c_str(); + + // Compare token with function and operator strings + // check string for operator/function + for (int i=0; pOprtDef[i]; i++) + { + std::size_t len( std::char_traits::length(pOprtDef[i]) ); + if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) ) + { + switch(i) + { + //case cmAND: + //case cmOR: + //case cmXOR: + case cmLAND: + case cmLOR: + case cmLT: + case cmGT: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmASSIGN: + //if (len!=sTok.length()) + // continue; + + // The assignement operator need special treatment + if (i==cmASSIGN && m_iSynFlags & noASSIGN) + Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]); + + if (!m_pParser->HasBuiltInOprt()) continue; + if (m_iSynFlags & noOPT) + { + // Maybe its an infix operator not an operator + // Both operator types can share characters in + // their identifiers + if ( IsInfixOpTok(a_Tok) ) + return true; + + Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]); + } + + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + m_iSynFlags |= ( (i != cmEND) && ( i != cmBC) ) ? noEND : 0; + break; + + case cmBO: + if (m_iSynFlags & noBO) + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + + if (m_lastTok.GetCode()==cmFUNC) + m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + else + m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN| noIF | noELSE; + + ++m_iBrackets; + break; + + case cmBC: + if (m_iSynFlags & noBC) + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + + m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; + + if (--m_iBrackets<0) + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + break; + + case cmELSE: + if (m_iSynFlags & noELSE) + Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]); + + m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; + break; + + case cmIF: + if (m_iSynFlags & noIF) + Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]); + + m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; + break; + + default: // The operator is listed in c_DefaultOprt, but not here. This is a bad thing... + Error(ecINTERNAL_ERROR); + } // switch operator id + + m_iPos += (int)len; + a_Tok.Set( (ECmdCode)i, pOprtDef[i] ); + return true; + } // if operator string found + } // end of for all operator strings + + return false; + } + + //--------------------------------------------------------------------------- + bool QmuParserTokenReader::IsArgSep(token_type &a_Tok) + { + const char_type* szFormula = m_strFormula.c_str(); + + if (szFormula[m_iPos]==m_cArgSep) + { + // copy the separator into null terminated string + char_type szSep[2]; + szSep[0] = m_cArgSep; + szSep[1] = 0; + + if (m_iSynFlags & noARG_SEP) + Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep); + + m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; + m_iPos++; + a_Tok.Set(cmARG_SEP, szSep); + return true; + } + + return false; + } + + //--------------------------------------------------------------------------- + /** \brief Check for End of Formula. + + \return true if an end of formula is found false otherwise. + \param a_Tok [out] If an eof is found the corresponding token will be stored there. + \throw nothrow + \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok + */ + bool QmuParserTokenReader::IsEOF(token_type &a_Tok) + { + const char_type* szFormula = m_strFormula.c_str(); + + // check for EOF + if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/) + { + if ( m_iSynFlags & noEND ) + Error(ecUNEXPECTED_EOF, m_iPos); + + if (m_iBrackets>0) + Error(ecMISSING_PARENS, m_iPos, _T(")")); + + m_iSynFlags = 0; + a_Tok.Set(cmEND); + return true; + } + + return false; + } + + //--------------------------------------------------------------------------- + /** \brief Check if a string position contains a unary infix operator. + \return true if a function token has been found false otherwise. + */ + bool QmuParserTokenReader::IsInfixOpTok(token_type &a_Tok) + { + string_type sTok; + int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos); + if (iEnd==m_iPos) + return false; + + // iteraterate over all postfix operator strings + funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); + for ( ; it!=m_pInfixOprtDef->rend(); ++it) + { + if (sTok.find(it->first)!=0) + continue; + + a_Tok.Set(it->second, it->first); + m_iPos += (int)it->first.length(); + + if (m_iSynFlags & noINFIXOP) + Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + + m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; + return true; + } + + return false; + +/* + a_Tok.Set(item->second, sTok); + m_iPos = (int)iEnd; + + if (m_iSynFlags & noINFIXOP) + Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + + m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; + return true; +*/ + } + + //--------------------------------------------------------------------------- + /** \brief Check whether the token at a given position is a function token. + \param a_Tok [out] If a value token is found it will be placed here. + \throw ParserException if Syntaxflags do not allow a function at a_iPos + \return true if a function token has been found false otherwise. + \pre [assert] m_pParser!=0 + */ + bool QmuParserTokenReader::IsFunTok(token_type &a_Tok) + { + string_type strTok; + int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); + if (iEnd==m_iPos) + return false; + + funmap_type::const_iterator item = m_pFunDef->find(strTok); + if (item==m_pFunDef->end()) + return false; + + // Check if the next sign is an opening bracket + const char_type *szFormula = m_strFormula.c_str(); + if (szFormula[iEnd]!='(') + return false; + + a_Tok.Set(item->second, strTok); + + m_iPos = (int)iEnd; + if (m_iSynFlags & noFUN) + Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString()); + + m_iSynFlags = noANY ^ noBO; + return true; + } + + //--------------------------------------------------------------------------- + /** \brief Check if a string position contains a binary operator. + \param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. + \return true if an operator token has been found. + */ + bool QmuParserTokenReader::IsOprt(token_type &a_Tok) + { + const char_type *const szExpr = m_strFormula.c_str(); + string_type strTok; + + int iEnd = ExtractOperatorToken(strTok, m_iPos); + if (iEnd==m_iPos) + return false; + + // Check if the operator is a built in operator, if so ignore it here + const char_type **const pOprtDef = m_pParser->GetOprtDef(); + for (int i=0; m_pParser->HasBuiltInOprt() && pOprtDef[i]; ++i) + { + if (string_type(pOprtDef[i])==strTok) + return false; + } + + // Note: + // All tokens in oprt_bin_maptype are have been sorted by their length + // Long operators must come first! Otherwise short names (like: "add") that + // are part of long token names (like: "add123") will be found instead + // of the long ones. + // Length sorting is done with ascending length so we use a reverse iterator here. + funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); + for ( ; it!=m_pOprtDef->rend(); ++it) + { + const string_type &sID = it->first; + if ( sID == string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) ) + { + a_Tok.Set(it->second, strTok); + + // operator was found + if (m_iSynFlags & noOPT) + { + // An operator was found but is not expected to occur at + // this position of the formula, maybe it is an infix + // operator, not a binary operator. Both operator types + // can share characters in their identifiers. + if ( IsInfixOpTok(a_Tok) ) + return true; + else + { + // nope, no infix operator + return false; + //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + } + + } + + m_iPos += (int)sID.length(); + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; + return true; + } + } + + return false; + } + + //--------------------------------------------------------------------------- + /** \brief Check if a string position contains a unary post value operator. */ + bool QmuParserTokenReader::IsPostOpTok(token_type &a_Tok) + { + // Do not check for postfix operators if they are not allowed at + // the current expression index. + // + // This will fix the bug reported here: + // + // http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979 + // + if (m_iSynFlags & noPOSTOP) + return false; + // + + // Tricky problem with equations like "3m+5": + // m is a postfix operator, + is a valid sign for postfix operators and + // for binary operators parser detects "m+" as operator string and + // finds no matching postfix operator. + // + // This is a special case so this routine slightly differs from the other + // token readers. + + // Test if there could be a postfix operator + string_type sTok; + int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos); + if (iEnd==m_iPos) + return false; + + // iteraterate over all postfix operator strings + funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); + for ( ; it!=m_pPostOprtDef->rend(); ++it) + { + if (sTok.find(it->first)!=0) + continue; + + a_Tok.Set(it->second, sTok); + m_iPos += (int)it->first.length(); + + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; + return true; + } + + return false; + } + + //--------------------------------------------------------------------------- + /** \brief Check whether the token at a given position is a value token. + + Value tokens are either values or constants. + + \param a_Tok [out] If a value token is found it will be placed here. + \return true if a value token has been found. + */ + bool QmuParserTokenReader::IsValTok(token_type &a_Tok) + { + assert(m_pConstDef); + assert(m_pParser); + + string_type strTok; + value_type fVal(0); + int iEnd(0); + + // 2.) Check for user defined constant + // Read everything that could be a constant name + iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); + if (iEnd!=m_iPos) + { + valmap_type::const_iterator item = m_pConstDef->find(strTok); + if (item!=m_pConstDef->end()) + { + m_iPos = iEnd; + a_Tok.SetVal(item->second, strTok); + + if (m_iSynFlags & noVAL) + Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok); + + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + } + + // 3.call the value recognition functions provided by the user + // Call user defined value recognition functions + std::list::const_iterator item = m_vIdentFun.begin(); + for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item) + { + int iStart = m_iPos; + if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 ) + { + strTok.assign(m_strFormula.c_str(), iStart, m_iPos); + if (m_iSynFlags & noVAL) + Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok); + + a_Tok.SetVal(fVal, strTok); + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + } + + return false; + } + + //--------------------------------------------------------------------------- + /** \brief Check wheter a token at a given position is a variable token. + \param a_Tok [out] If a variable token has been found it will be placed here. + \return true if a variable token has been found. + */ + bool QmuParserTokenReader::IsVarTok(token_type &a_Tok) + { + if (!m_pVarDef->size()) + return false; + + string_type strTok; + int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); + if (iEnd==m_iPos) + return false; + + varmap_type::const_iterator item = m_pVarDef->find(strTok); + if (item==m_pVarDef->end()) + return false; + + if (m_iSynFlags & noVAR) + Error(ecUNEXPECTED_VAR, m_iPos, strTok); + + m_pParser->OnDetectVar(&m_strFormula, m_iPos, iEnd); + + m_iPos = iEnd; + a_Tok.SetVar(item->second, strTok); + m_UsedVar[item->first] = item->second; // Add variable to used-var-list + + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR; + +// Zur Info hier die SynFlags von IsVal(): +// m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + + //--------------------------------------------------------------------------- + bool QmuParserTokenReader::IsStrVarTok(token_type &a_Tok) + { + if (!m_pStrVarDef || !m_pStrVarDef->size()) + return false; + + string_type strTok; + int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); + if (iEnd==m_iPos) + return false; + + strmap_type::const_iterator item = m_pStrVarDef->find(strTok); + if (item==m_pStrVarDef->end()) + return false; + + if (m_iSynFlags & noSTR) + Error(ecUNEXPECTED_VAR, m_iPos, strTok); + + m_iPos = iEnd; + if (!m_pParser->m_vStringVarBuf.size()) + Error(ecINTERNAL_ERROR); + + a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() ); + + m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP); + return true; + } + + + //--------------------------------------------------------------------------- + /** \brief Check wheter a token at a given position is an undefined variable. + + \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here. + \return true if a variable token has been found. + \throw nothrow + */ + bool QmuParserTokenReader::IsUndefVarTok(token_type &a_Tok) + { + string_type strTok; + int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) ); + if ( iEnd==m_iPos ) + return false; + + if (m_iSynFlags & noVAR) + { + // 20061021 added token string strTok instead of a_Tok.GetAsString() as the + // token identifier. + // related bug report: + // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 + Error(ecUNEXPECTED_VAR, m_iPos - (int)a_Tok.GetAsString().length(), strTok); + } + + // If a factory is available implicitely create new variables + if (m_pFactory) + { + value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData); + a_Tok.SetVar(fVar, strTok ); + + // Do not use m_pParser->DefineVar( strTok, fVar ); + // in order to define the new variable, it will clear the + // m_UsedVar array which will kill previousely defined variables + // from the list + // This is safe because the new variable can never override an existing one + // because they are checked first! + (*m_pVarDef)[strTok] = fVar; + m_UsedVar[strTok] = fVar; // Add variable to used-var-list + } + else + { + a_Tok.SetVar((value_type*)&m_fZero, strTok); + m_UsedVar[strTok] = 0; // Add variable to used-var-list + } + + m_iPos = iEnd; + + // Call the variable factory in order to let it define a new parser variable + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR; + return true; + } + + + //--------------------------------------------------------------------------- + /** \brief Check wheter a token at a given position is a string. + \param a_Tok [out] If a variable token has been found it will be placed here. + \return true if a string token has been found. + \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok + \throw nothrow + */ + bool QmuParserTokenReader::IsString(token_type &a_Tok) + { + if (m_strFormula[m_iPos]!='"') + return false; + + string_type strBuf(&m_strFormula[m_iPos+1]); + std::size_t iEnd(0), iSkip(0); + + // parser over escaped '\"' end replace them with '"' + for(iEnd=(int)strBuf.find( _T("\"") ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( _T("\""), iEnd)) + { + if (strBuf[iEnd-1]!='\\') break; + strBuf.replace(iEnd-1, 2, _T("\"") ); + iSkip++; + } + + if (iEnd==string_type::npos) + Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") ); + + string_type strTok(strBuf.begin(), strBuf.begin()+iEnd); + + if (m_iSynFlags & noSTR) + Error(ecUNEXPECTED_STR, m_iPos, strTok); + + m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer + a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size()); + + m_iPos += (int)strTok.length() + 2 + (int)iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); + + return true; + } + + //--------------------------------------------------------------------------- + /** \brief Create an error containing the parse error position. + + This function will create an Parser Exception object containing the error text and its position. + + \param a_iErrc [in] The error code of type #EErrorCodes. + \param a_iPos [in] The position where the error was detected. + \param a_strTok [in] The token string representation associated with the error. + \throw ParserException always throws thats the only purpose of this function. + */ + void QmuParserTokenReader::Error( EErrorCodes a_iErrc, + int a_iPos, + const string_type &a_sTok) const + { + m_pParser->Error(a_iErrc, a_iPos, a_sTok); + } + + //--------------------------------------------------------------------------- + void QmuParserTokenReader::SetArgSep(char_type cArgSep) + { + m_cArgSep = cArgSep; + } + + //--------------------------------------------------------------------------- + char_type QmuParserTokenReader::GetArgSep() const + { + return m_cArgSep; + } +} // namespace qmu + diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h new file mode 100644 index 000000000..2475b79f4 --- /dev/null +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -0,0 +1,158 @@ +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTOKENREADER_H +#define QMUPARSERTOKENREADER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qmuparserdef.h" +#include "qmuparsertoken.h" + +/** \file + \brief This file contains the parser token reader definition. +*/ + + +namespace qmu +{ + // Forward declaration + class QmuParserBase; + + /** \brief Token reader for the ParserBase class. + + */ + class QmuParserTokenReader + { + private: + + typedef QmuParserToken token_type; + + public: + + QmuParserTokenReader(QmuParserBase *a_pParent); + QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const; + + void AddValIdent(identfun_type a_pCallback); + void SetVarCreator(facfun_type a_pFactory, void *pUserData); + void SetFormula(const string_type &a_strFormula); + void SetArgSep(char_type cArgSep); + + int GetPos() const; + const string_type& GetExpr() const; + varmap_type& GetUsedVar(); + char_type GetArgSep() const; + + void IgnoreUndefVar(bool bIgnore); + void ReInit(); + token_type ReadNextToken(); + + private: + + /** \brief Syntax codes. + + The syntax codes control the syntax check done during the first time parsing of + the expression string. They are flags that indicate which tokens are allowed next + if certain tokens are identified. + */ + enum ESynCodes + { + noBO = 1 << 0, ///< to avoid i.e. "cos(7)(" + noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()" + noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14" + noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a" + noARG_SEP = 1 << 4, ///< to avoid i.e. ",," or "+," ... + noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin" + noOPT = 1 << 6, ///< to avoid i.e. "(+)" + noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!" + noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4" + noEND = 1 << 9, ///< to avoid unexpected end of formula + noSTR = 1 << 10, ///< to block numeric arguments on string functions + noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7" + noIF = 1 << 12, + noELSE = 1 << 13, + sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP, + noANY = ~0 ///< All of he above flags set + }; + + QmuParserTokenReader(const QmuParserTokenReader &a_Reader); + QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader); + void Assign(const QmuParserTokenReader &a_Reader); + + void SetParent(QmuParserBase *a_pParent); + int ExtractToken(const char_type *a_szCharSet, + string_type &a_strTok, + int a_iPos) const; + int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const; + + bool IsBuiltIn(token_type &a_Tok); + bool IsArgSep(token_type &a_Tok); + bool IsEOF(token_type &a_Tok); + bool IsInfixOpTok(token_type &a_Tok); + bool IsFunTok(token_type &a_Tok); + bool IsPostOpTok(token_type &a_Tok); + bool IsOprt(token_type &a_Tok); + bool IsValTok(token_type &a_Tok); + bool IsVarTok(token_type &a_Tok); + bool IsStrVarTok(token_type &a_Tok); + bool IsUndefVarTok(token_type &a_Tok); + bool IsString(token_type &a_Tok); + void Error(EErrorCodes a_iErrc, + int a_iPos = -1, + const string_type &a_sTok = string_type() ) const; + + token_type& SaveBeforeReturn(const token_type &tok); + + QmuParserBase *m_pParser; + string_type m_strFormula; + int m_iPos; + int m_iSynFlags; + bool m_bIgnoreUndefVar; + + const funmap_type *m_pFunDef; + const funmap_type *m_pPostOprtDef; + const funmap_type *m_pInfixOprtDef; + const funmap_type *m_pOprtDef; + const valmap_type *m_pConstDef; + const strmap_type *m_pStrVarDef; + varmap_type *m_pVarDef; ///< The only non const pointer to parser internals + facfun_type m_pFactory; + void *m_pFactoryData; + std::list m_vIdentFun; ///< Value token identification function + varmap_type m_UsedVar; + value_type m_fZero; ///< Dummy value of zero, referenced by undefined variables + int m_iBrackets; + token_type m_lastTok; + char_type m_cArgSep; ///< The character used for separating function arguments + }; +} // namespace qmu + +#endif + + diff --git a/src/libs/qmuparser/stable.cpp b/src/libs/qmuparser/stable.cpp new file mode 100644 index 000000000..57b3c2027 --- /dev/null +++ b/src/libs/qmuparser/stable.cpp @@ -0,0 +1,30 @@ +/************************************************************************ + ** + ** @file stable.cpp + ** @author Roman Telezhinsky + ** @date November 15, 2013 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +// Build the precompiled headers. +#include "stable.h" diff --git a/src/libs/qmuparser/stable.h b/src/libs/qmuparser/stable.h new file mode 100644 index 000000000..d02111e92 --- /dev/null +++ b/src/libs/qmuparser/stable.h @@ -0,0 +1,46 @@ +/************************************************************************ + ** + ** @file stable.h + ** @author Roman Telezhinsky + ** @date November 15, 2013 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef STABLE_H +#define STABLE_H + +/* I like to include this pragma too, so the build log indicates if pre-compiled headers were in use. */ +#pragma message("Compiling precompiled headers for QmuParser library.\n") + +/* Add C includes here */ + +#if defined __cplusplus +/* Add C++ includes here */ +#ifdef Q_CC_MSVC +#define _USE_MATH_DEFINES +#endif +#include +#include +#endif + +#endif // STABLE_H diff --git a/src/src.pro b/src/src.pro index 7a8600add..5ffab2912 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,13 +1,16 @@ TEMPLATE = subdirs #SUBDIRS = sub_lib sub_tests sub_app -SUBDIRS = sub_app +SUBDIRS = \ + sub_app \ + sub_lib_qmuparser -#sub_lib.subdir = lib +sub_lib_qmuparser.subdir = libs/qmuparser +sub_lib_qmuparser.file = libs/qmuparser/qmuparser.pro #sub_tests.file = tests/proj.pro #sub_tests.depends = sub_lib sub_app.subdir = app sub_app.file = app/app.pro -#sub_app.depends = sub_lib +sub_app.depends = sub_lib_qmuparser #This makes it possible to use make -j 4 on your fancy quad-core system with a project that consists of several #components that depend on each other. To simplify the process a bit, the following test function can be defined: From 11f527143b613933c2b8fd5a5d857e396e04800f Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 25 Apr 2014 18:01:23 +0300 Subject: [PATCH 03/26] Used qreal for datatype. Deleted _T() macros. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 166 +-- src/libs/qmuparser/qmuparser.h | 58 +- src/libs/qmuparser/qmuparserbase.cpp | 114 +- src/libs/qmuparser/qmuparserbase.h | 22 +- src/libs/qmuparser/qmuparserbytecode.cpp | 112 +- src/libs/qmuparser/qmuparserbytecode.h | 16 +- src/libs/qmuparser/qmuparserdef.h | 95 +- src/libs/qmuparser/qmuparsererror.cpp | 94 +- src/libs/qmuparser/qmuparserint.cpp | 140 +- src/libs/qmuparser/qmuparserint.h | 62 +- src/libs/qmuparser/qmuparserstack.h | 2 +- src/libs/qmuparser/qmuparsertemplatemagic.h | 40 +- src/libs/qmuparser/qmuparsertest.cpp | 1432 +++++++++---------- src/libs/qmuparser/qmuparsertest.h | 94 +- src/libs/qmuparser/qmuparsertoken.h | 2 +- src/libs/qmuparser/qmuparsertokenreader.cpp | 14 +- src/libs/qmuparser/qmuparsertokenreader.h | 4 +- 17 files changed, 1224 insertions(+), 1243 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 8d24a909e..fb8a250ce 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -49,78 +49,78 @@ namespace qmu //--------------------------------------------------------------------------- // Trigonometric function - value_type QmuParser::Sin(value_type v) { return MathImpl::Sin(v); } - value_type QmuParser::Cos(value_type v) { return MathImpl::Cos(v); } - value_type QmuParser::Tan(value_type v) { return MathImpl::Tan(v); } - value_type QmuParser::ASin(value_type v) { return MathImpl::ASin(v); } - value_type QmuParser::ACos(value_type v) { return MathImpl::ACos(v); } - value_type QmuParser::ATan(value_type v) { return MathImpl::ATan(v); } - value_type QmuParser::ATan2(value_type v1, value_type v2) { return MathImpl::ATan2(v1, v2); } - value_type QmuParser::Sinh(value_type v) { return MathImpl::Sinh(v); } - value_type QmuParser::Cosh(value_type v) { return MathImpl::Cosh(v); } - value_type QmuParser::Tanh(value_type v) { return MathImpl::Tanh(v); } - value_type QmuParser::ASinh(value_type v) { return MathImpl::ASinh(v); } - value_type QmuParser::ACosh(value_type v) { return MathImpl::ACosh(v); } - value_type QmuParser::ATanh(value_type v) { return MathImpl::ATanh(v); } + qreal QmuParser::Sin(qreal v) { return MathImpl::Sin(v); } + qreal QmuParser::Cos(qreal v) { return MathImpl::Cos(v); } + qreal QmuParser::Tan(qreal v) { return MathImpl::Tan(v); } + qreal QmuParser::ASin(qreal v) { return MathImpl::ASin(v); } + qreal QmuParser::ACos(qreal v) { return MathImpl::ACos(v); } + qreal QmuParser::ATan(qreal v) { return MathImpl::ATan(v); } + qreal QmuParser::ATan2(qreal v1, qreal v2) { return MathImpl::ATan2(v1, v2); } + qreal QmuParser::Sinh(qreal v) { return MathImpl::Sinh(v); } + qreal QmuParser::Cosh(qreal v) { return MathImpl::Cosh(v); } + qreal QmuParser::Tanh(qreal v) { return MathImpl::Tanh(v); } + qreal QmuParser::ASinh(qreal v) { return MathImpl::ASinh(v); } + qreal QmuParser::ACosh(qreal v) { return MathImpl::ACosh(v); } + qreal QmuParser::ATanh(qreal v) { return MathImpl::ATanh(v); } //--------------------------------------------------------------------------- // Logarithm functions // Logarithm base 2 - value_type QmuParser::Log2(value_type v) + qreal QmuParser::Log2(qreal v) { #ifdef MUP_MATH_EXCEPTIONS if (v<=0) - throw QmuParserError(ecDOMAIN_ERROR, _T("Log2")); + throw QmuParserError(ecDOMAIN_ERROR, "Log2"); #endif - return MathImpl::Log2(v); + return MathImpl::Log2(v); } // Logarithm base 10 - value_type QmuParser::Log10(value_type v) + qreal QmuParser::Log10(qreal v) { #ifdef MUP_MATH_EXCEPTIONS if (v<=0) - throw QmuParserError(ecDOMAIN_ERROR, _T("Log10")); + throw QmuParserError(ecDOMAIN_ERROR, "Log10"); #endif - return MathImpl::Log10(v); + return MathImpl::Log10(v); } // Logarithm base e (natural logarithm) - value_type QmuParser::Ln(value_type v) + qreal QmuParser::Ln(qreal v) { #ifdef MUP_MATH_EXCEPTIONS if (v<=0) - throw QmuParserError(ecDOMAIN_ERROR, _T("Ln")); + throw QmuParserError(ecDOMAIN_ERROR, "Ln"); #endif - return MathImpl::Log(v); + return MathImpl::Log(v); } //--------------------------------------------------------------------------- // misc - value_type QmuParser::Exp(value_type v) { return MathImpl::Exp(v); } - value_type QmuParser::Abs(value_type v) { return MathImpl::Abs(v); } - value_type QmuParser::Sqrt(value_type v) + qreal QmuParser::Exp(qreal v) { return MathImpl::Exp(v); } + qreal QmuParser::Abs(qreal v) { return MathImpl::Abs(v); } + qreal QmuParser::Sqrt(qreal v) { #ifdef MUP_MATH_EXCEPTIONS if (v<0) - throw QmuParserError(ecDOMAIN_ERROR, _T("sqrt")); + throw QmuParserError(ecDOMAIN_ERROR, "sqrt"); #endif - return MathImpl::Sqrt(v); + return MathImpl::Sqrt(v); } - value_type QmuParser::Rint(value_type v) { return MathImpl::Rint(v); } - value_type QmuParser::Sign(value_type v) { return MathImpl::Sign(v); } + qreal QmuParser::Rint(qreal v) { return MathImpl::Rint(v); } + qreal QmuParser::Sign(qreal v) { return MathImpl::Sign(v); } //--------------------------------------------------------------------------- /** \brief Callback for the unary minus operator. \param v The value to negate \return -v */ - value_type QmuParser::UnaryMinus(value_type v) + qreal QmuParser::UnaryMinus(qreal v) { return -v; } @@ -130,12 +130,12 @@ namespace qmu \param [in] a_afArg Vector with the function arguments \param [in] a_iArgc The size of a_afArg */ - value_type QmuParser::Sum(const value_type *a_afArg, int a_iArgc) + qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc) { if (!a_iArgc) - throw exception_type(_T("too few arguments for function sum.")); + throw exception_type("too few arguments for function sum."); - value_type fRes=0; + qreal fRes=0; for (int i=0; i=#!$%&|~'_{}") ); - DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") ); + DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); + DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" ); + DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" ); } //--------------------------------------------------------------------------- /** \brief Initialize the default functions. */ void QmuParser::InitFun() { - if (qmu::TypeInfo::IsInteger()) + if (qmu::TypeInfo::IsInteger()) { // When setting MUP_BASETYPE to an integer type // Place functions for dealing with integer values here @@ -262,38 +262,38 @@ namespace qmu else { // trigonometric functions - DefineFun(_T("sin"), Sin); - DefineFun(_T("cos"), Cos); - DefineFun(_T("tan"), Tan); + DefineFun("sin", Sin); + DefineFun("cos", Cos); + DefineFun("tan", Tan); // arcus functions - DefineFun(_T("asin"), ASin); - DefineFun(_T("acos"), ACos); - DefineFun(_T("atan"), ATan); - DefineFun(_T("atan2"), ATan2); + DefineFun("asin", ASin); + DefineFun("acos", ACos); + DefineFun("atan", ATan); + DefineFun("atan2", ATan2); // hyperbolic functions - DefineFun(_T("sinh"), Sinh); - DefineFun(_T("cosh"), Cosh); - DefineFun(_T("tanh"), Tanh); + DefineFun("sinh", Sinh); + DefineFun("cosh", Cosh); + DefineFun("tanh", Tanh); // arcus hyperbolic functions - DefineFun(_T("asinh"), ASinh); - DefineFun(_T("acosh"), ACosh); - DefineFun(_T("atanh"), ATanh); + DefineFun("asinh", ASinh); + DefineFun("acosh", ACosh); + DefineFun("atanh", ATanh); // Logarithm functions - DefineFun(_T("log2"), Log2); - DefineFun(_T("log10"), Log10); - DefineFun(_T("log"), Log10); - DefineFun(_T("ln"), Ln); + DefineFun("log2", Log2); + DefineFun("log10", Log10); + DefineFun("log", Log10); + DefineFun("ln", Ln); // misc - DefineFun(_T("exp"), Exp); - DefineFun(_T("sqrt"), Sqrt); - DefineFun(_T("sign"), Sign); - DefineFun(_T("rint"), Rint); - DefineFun(_T("abs"), Abs); + DefineFun("exp", Exp); + DefineFun("sqrt", Sqrt); + DefineFun("sign", Sign); + DefineFun("rint", Rint); + DefineFun("abs", Abs); // Functions with variable number of arguments - DefineFun(_T("sum"), Sum); - DefineFun(_T("avg"), Avg); - DefineFun(_T("min"), Min); - DefineFun(_T("max"), Max); + DefineFun("sum", Sum); + DefineFun("avg", Avg); + DefineFun("min", Min); + DefineFun("max", Max); } } @@ -305,8 +305,8 @@ namespace qmu */ void QmuParser::InitConst() { - DefineConst(_T("_pi"), (value_type)QmuParser_CONST_PI); - DefineConst(_T("_e"), (value_type)QmuParser_CONST_E); + DefineConst("_pi", (qreal)QmuParser_CONST_PI); + DefineConst("_e", (qreal)QmuParser_CONST_E); } //--------------------------------------------------------------------------- @@ -316,7 +316,7 @@ namespace qmu */ void QmuParser::InitOprt() { - DefineInfixOprt(_T("-"), UnaryMinus); + DefineInfixOprt("-", UnaryMinus); } //--------------------------------------------------------------------------- @@ -357,11 +357,11 @@ namespace qmu http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 */ - value_type QmuParser::Diff(value_type *a_Var, - value_type a_fPos, - value_type a_fEpsilon) const + qreal QmuParser::Diff(qreal *a_Var, + qreal a_fPos, + qreal a_fEpsilon) const { - value_type fRes(0), + qreal fRes(0), fBuf(*a_Var), f[4] = {0,0,0,0}, fEpsilon(a_fEpsilon); @@ -369,7 +369,7 @@ namespace qmu // Backwards compatible calculation of epsilon inc case the user doesnt provide // his own epsilon if (fEpsilon==0) - fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos; + fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos; *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 07a1b8c3a..6832a1fde 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -59,50 +59,50 @@ public: virtual void InitOprt(); virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); - value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon = 0) const; + qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; protected: // Trigonometric functions - static value_type Sin(value_type); - static value_type Cos(value_type); - static value_type Tan(value_type); - static value_type Tan2(value_type, value_type); + static qreal Sin(qreal); + static qreal Cos(qreal); + static qreal Tan(qreal); + static qreal Tan2(qreal, qreal); // arcus functions - static value_type ASin(value_type); - static value_type ACos(value_type); - static value_type ATan(value_type); - static value_type ATan2(value_type, value_type); + static qreal ASin(qreal); + static qreal ACos(qreal); + static qreal ATan(qreal); + static qreal ATan2(qreal, qreal); // hyperbolic functions - static value_type Sinh(value_type); - static value_type Cosh(value_type); - static value_type Tanh(value_type); + static qreal Sinh(qreal); + static qreal Cosh(qreal); + static qreal Tanh(qreal); // arcus hyperbolic functions - static value_type ASinh(value_type); - static value_type ACosh(value_type); - static value_type ATanh(value_type); + static qreal ASinh(qreal); + static qreal ACosh(qreal); + static qreal ATanh(qreal); // Logarithm functions - static value_type Log2(value_type); // Logarithm Base 2 - static value_type Log10(value_type); // Logarithm Base 10 - static value_type Ln(value_type); // Logarithm Base e (natural logarithm) + static qreal Log2(qreal); // Logarithm Base 2 + static qreal Log10(qreal); // Logarithm Base 10 + static qreal Ln(qreal); // Logarithm Base e (natural logarithm) // misc - static value_type Exp(value_type); - static value_type Abs(value_type); - static value_type Sqrt(value_type); - static value_type Rint(value_type); - static value_type Sign(value_type); + static qreal Exp(qreal); + static qreal Abs(qreal); + static qreal Sqrt(qreal); + static qreal Rint(qreal); + static qreal Sign(qreal); // Prefix operators // !!! Unary Minus is a MUST if you want to use negative signs !!! - static value_type UnaryMinus(value_type); + static qreal UnaryMinus(qreal); // Functions with variable number of arguments - static value_type Sum(const value_type*, int); // sum - static value_type Avg(const value_type*, int); // mean value - static value_type Min(const value_type*, int); // minimum - static value_type Max(const value_type*, int); // maximum + static qreal Sum(const qreal*, int); // sum + static qreal Avg(const qreal*, int); // mean value + static qreal Min(const qreal*, int); // minimum + static qreal Max(const qreal*, int); // maximum - static int IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal); + static int IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal); }; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index fa8a7c2a1..244e79fb2 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -57,12 +57,12 @@ namespace qmu */ const char_type* QmuParserBase::c_DefaultOprt[] = { - _T("<="), _T(">="), _T("!="), - _T("=="), _T("<"), _T(">"), - _T("+"), _T("-"), _T("*"), - _T("/"), _T("^"), _T("&&"), - _T("||"), _T("="), _T("("), - _T(")"), _T("?"), _T(":"), 0 + "<=", ">=", "!=", + "==", "<", ">", + "+", "-", "*", + "/", "^", "&&", + "||", "=", "(", + ")", "?", ":", 0 }; //------------------------------------------------------------------------------ @@ -270,38 +270,38 @@ namespace qmu if (eInfo==pviFULL) { - ss << _T(" (") << MUP_VERSION_DATE; - ss << std::dec << _T("; ") << sizeof(void*)*8 << _T("BIT"); + ss << " (" << MUP_VERSION_DATE; + ss << std::dec << "; " << sizeof(void*)*8 << "BIT"; #ifdef _DEBUG - ss << _T("; DEBUG"); + ss << "; DEBUG"; #else - ss << _T("; RELEASE"); + ss << "; RELEASE"; #endif #ifdef _UNICODE - ss << _T("; UNICODE"); + ss << "; UNICODE"; #else #ifdef _MBCS - ss << _T("; MBCS"); + ss << "; MBCS"; #else - ss << _T("; ASCII"); + ss << "; ASCII"; #endif #endif -#ifdef MUP_USE_OPENMP - ss << _T("; OPENMP"); +#ifdef QMUP_USE_OPENMP + ss << "; OPENMP"; //#else -// ss << _T("; NO_OPENMP"); +// ss << "; NO_OPENMP"; #endif #if defined(MUP_MATH_EXCEPTIONS) - ss << _T("; MATHEXC"); + ss << "; MATHEXC"; //#else -// ss << _T("; NO_MATHEXC"); +// ss << "; NO_MATHEXC"; #endif - ss << _T(")"); + ss << ")"; } return ss.str(); @@ -417,7 +417,7 @@ namespace qmu // when calling tellg on a stringstream created from the expression after // reading a value at the end of an expression. (mu::Parser::IsVal function) // (tellg returns -1 otherwise causing the parser to ignore the value) - string_type sBuf(a_sExpr + _T(" ") ); + string_type sBuf(a_sExpr + " " ); m_pTokenReader->SetFormula(sBuf); ReInit(); } @@ -589,7 +589,7 @@ namespace qmu \post Will reset the Parser to string parsing mode. \throw ParserException in case the name contains invalid signs or a_pVar is NULL. */ - void QmuParserBase::DefineVar(const string_type &a_sName, value_type *a_pVar) + void QmuParserBase::DefineVar(const string_type &a_sName, qreal *a_pVar) { if (a_pVar==0) Error(ecINVALID_VAR_PTR); @@ -610,7 +610,7 @@ namespace qmu \post Will reset the Parser to string parsing mode. \throw ParserException in case the name contains invalid signs. */ - void QmuParserBase::DefineConst(const string_type &a_sName, value_type a_fVal) + void QmuParserBase::DefineConst(const string_type &a_sName, qreal a_fVal) { CheckName(a_sName, ValidNameChars()); m_ConstDef[a_sName] = a_fVal; @@ -923,7 +923,7 @@ namespace qmu if (optTok.GetCode()==cmASSIGN) { if (valTok2.GetCode()!=cmVAR) - Error(ecUNEXPECTED_OPERATOR, -1, _T("=")); + Error(ecUNEXPECTED_OPERATOR, -1, "="); m_vRPN.AddAssignOp(valTok2.GetVar()); } @@ -990,7 +990,7 @@ namespace qmu associated operators. The Stack is filled beginning from index one the value at index zero is not used at all. */ - value_type QmuParserBase::ParseCmdCode() const + qreal QmuParserBase::ParseCmdCode() const { return ParseCmdCodeBulk(0, 0); } @@ -1000,14 +1000,14 @@ namespace qmu \param nOffset The offset added to variable addresses (for bulk mode) \param nThreadID OpenMP Thread id of the calling thread */ - value_type QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const + qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const { assert(nThreadID<=s_MaxNumOpenMPThreads); // Note: The check for nOffset==0 and nThreadID here is not necessary but // brings a minor performance gain when not in bulk mode. - value_type *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; - value_type buf; + qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; + qreal buf; int sidx(0); for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) { @@ -1033,7 +1033,7 @@ namespace qmu continue; case cmPOW: - --sidx; Stack[sidx] = MathImpl::Pow(Stack[sidx], Stack[1+sidx]); + --sidx; Stack[sidx] = MathImpl::Pow(Stack[sidx], Stack[1+sidx]); continue; case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue; @@ -1208,7 +1208,7 @@ namespace qmu case cmVAR: stVal.push(opt); - m_vRPN.AddVar( static_cast(opt.GetVar()) ); + m_vRPN.AddVar( static_cast(opt.GetVar()) ); break; case cmVAL: @@ -1415,7 +1415,7 @@ namespace qmu pointer #m_pParseFormula will be changed to the second parse routine the uses bytecode instead of string parsing. */ - value_type QmuParserBase::ParseString() const + qreal QmuParserBase::ParseString() const { try { @@ -1610,14 +1610,14 @@ namespace qmu QmuParserStack stOprt(a_stOprt), stVal(a_stVal); - mu::console() << _T("\nValue stack:\n"); + mu::console() << "\nValue stack:\n"; while ( !stVal.empty() ) { token_type val = stVal.pop(); if (val.GetType()==tpSTR) - mu::console() << _T(" \"") << val.GetAsString() << _T("\" "); + mu::console() << " \"" << val.GetAsString() << "\" "; else - mu::console() << _T(" ") << val.GetVal() << _T(" "); + mu::console() << " " << val.GetVal() << " "; } mu::console() << "\nOperator stack:\n"; @@ -1625,37 +1625,37 @@ namespace qmu { if (stOprt.top().GetCode()<=cmASSIGN) { - mu::console() << _T("OPRT_INTRNL \"") + mu::console() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] - << _T("\" \n"); + << "\" \n"; } else { switch(stOprt.top().GetCode()) { - case cmVAR: mu::console() << _T("VAR\n"); break; - case cmVAL: mu::console() << _T("VAL\n"); break; - case cmFUNC: mu::console() << _T("FUNC \"") + case cmVAR: mu::console() << "VAR\n"; break; + case cmVAL: mu::console() << "VAL\n"; break; + case cmFUNC: mu::console() << "FUNC \"" << stOprt.top().GetAsString() - << _T("\"\n"); break; - case cmFUNC_BULK: mu::console() << _T("FUNC_BULK \"") + << "\"\n"; break; + case cmFUNC_BULK: mu::console() << "FUNC_BULK \"" << stOprt.top().GetAsString() - << _T("\"\n"); break; - case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"") + << "\"\n"; break; + case cmOPRT_INFIX: mu::console() << "OPRT_INFIX \"" << stOprt.top().GetAsString() - << _T("\"\n"); break; - case cmOPRT_BIN: mu::console() << _T("OPRT_BIN \"") + << "\"\n"; break; + case cmOPRT_BIN: mu::console() << "OPRT_BIN \"" << stOprt.top().GetAsString() - << _T("\"\n"); break; - case cmFUNC_STR: mu::console() << _T("FUNC_STR\n"); break; - case cmEND: mu::console() << _T("END\n"); break; - case cmUNKNOWN: mu::console() << _T("UNKNOWN\n"); break; - case cmBO: mu::console() << _T("BRACKET \"(\"\n"); break; - case cmBC: mu::console() << _T("BRACKET \")\"\n"); break; - case cmIF: mu::console() << _T("IF\n"); break; - case cmELSE: mu::console() << _T("ELSE\n"); break; - case cmENDIF: mu::console() << _T("ENDIF\n"); break; - default: mu::console() << stOprt.top().GetCode() << _T(" "); break; + << "\"\n"; break; + case cmFUNC_STR: mu::console() << "FUNC_STR\n"; break; + case cmEND: mu::console() << "END\n"; break; + case cmUNKNOWN: mu::console() << "UNKNOWN\n"; break; + case cmBO: mu::console() << "BRACKET \"(\"\n"; break; + case cmBC: mu::console() << "BRACKET \")\"\n"; break; + case cmIF: mu::console() << "IF\n"; break; + case cmELSE: mu::console() << "ELSE\n"; break; + case cmENDIF: mu::console() << "ENDIF\n"; break; + default: mu::console() << stOprt.top().GetCode() << " "; break; } } stOprt.pop(); @@ -1672,7 +1672,7 @@ namespace qmu This member function can be used to retriev all results of an expression made up of multiple comma seperated subexpressions (i.e. "x+y,sin(x),cos(y)") */ - value_type* QmuParserBase::Eval(int &nStackSize) const + qreal* QmuParserBase::Eval(int &nStackSize) const { (this->*m_pParseFormula)(); nStackSize = m_nFinalResultIdx; @@ -1709,13 +1709,13 @@ namespace qmu \return The evaluation result \throw ParseException if no Formula is set or in case of any other error related to the formula. */ - value_type QmuParserBase::Eval() const + qreal QmuParserBase::Eval() const { return (this->*m_pParseFormula)(); } //--------------------------------------------------------------------------- - void QmuParserBase::Eval(value_type *results, int nBulkSize) + void QmuParserBase::Eval(qreal *results, int nBulkSize) { CreateRPN(); diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 453274706..e5a50bb4f 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -68,10 +68,10 @@ private: the function pointer to the parser function depending on which state it is in. (i.e. bytecode parser vs. string parser) */ - typedef value_type (QmuParserBase::*ParseFunction)() const; + typedef qreal (QmuParserBase::*ParseFunction)() const; /** \brief Type used for storing an array of values. */ - typedef std::vector valbuf_type; + typedef std::vector valbuf_type; /** \brief Type for a vector of strings. */ typedef std::vector stringbuf_type; @@ -80,7 +80,7 @@ private: typedef QmuParserTokenReader token_reader_type; /** \brief Type used for parser tokens. */ - typedef QmuParserToken token_type; + typedef QmuParserToken token_type; /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */ static const int s_MaxNumOpenMPThreads = 4; @@ -101,9 +101,9 @@ private: virtual ~QmuParserBase(); - value_type Eval() const; - value_type* Eval(int &nStackSize) const; - void Eval(value_type *results, int nBulkSize); + qreal Eval() const; + qreal* Eval(int &nStackSize) const; + void Eval(qreal *results, int nBulkSize); int GetNumResults() const; @@ -137,9 +137,9 @@ private: unsigned a_iPri=0, EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); - void DefineConst(const string_type &a_sName, value_type a_fVal); + void DefineConst(const string_type &a_sName, qreal a_fVal); void DefineStrConst(const string_type &a_sName, const string_type &a_strVal); - void DefineVar(const string_type &a_sName, value_type *a_fVar); + void DefineVar(const string_type &a_sName, qreal *a_fVar); void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); @@ -259,9 +259,9 @@ private: void CreateRPN() const; - value_type ParseString() const; - value_type ParseCmdCode() const; - value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const; + qreal ParseString() const; + qreal ParseCmdCode() const; + qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; void CheckName(const string_type &a_strName, const string_type &a_CharSet) const; void CheckOprt(const string_type &a_sName, diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 222c1db0a..34609b591 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -95,7 +95,7 @@ namespace qmu \param a_pVar Pointer to be added. \throw nothrow */ - void QmuParserByteCode::AddVar(value_type *a_pVar) + void QmuParserByteCode::AddVar(qreal *a_pVar) { ++m_iStackPos; m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); @@ -122,7 +122,7 @@ namespace qmu \param a_pVal Value to be added. \throw nothrow */ - void QmuParserByteCode::AddVal(value_type a_fVal) + void QmuParserByteCode::AddVal(qreal a_fVal) { ++m_iStackPos; m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); @@ -140,7 +140,7 @@ namespace qmu void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) { std::size_t sz = m_vRPN.size(); - value_type &x = m_vRPN[sz-2].Val.data2, + qreal &x = m_vRPN[sz-2].Val.data2, &y = m_vRPN[sz-1].Val.data2; switch (a_Oprt) { @@ -159,14 +159,14 @@ namespace qmu #if defined(MUP_MATH_EXCEPTIONS) if (y==0) - throw ParserError(ecDIV_BY_ZERO, _T("0")); + throw ParserError(ecDIV_BY_ZERO, "0"); #endif x = x / y; m_vRPN.pop_back(); break; - case cmPOW: x = MathImpl::Pow(x, y); + case cmPOW: x = MathImpl::Pow(x, y); m_vRPN.pop_back(); break; @@ -243,7 +243,7 @@ namespace qmu (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable + m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior m_vRPN.pop_back(); @@ -256,7 +256,7 @@ namespace qmu (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) { m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; m_vRPN[sz-2].Val.data2 = 0; m_vRPN.pop_back(); @@ -267,7 +267,7 @@ namespace qmu { // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); if (m_vRPN[sz-1].Cmd == cmVAL) { m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; @@ -335,7 +335,7 @@ namespace qmu \sa ParserToken::ECmdCode */ - void QmuParserByteCode::AddAssignOp(value_type *a_pVar) + void QmuParserByteCode::AddAssignOp(qreal *a_pVar) { --m_iStackPos; @@ -495,89 +495,89 @@ namespace qmu { if (!m_vRPN.size()) { - mu::console() << _T("No bytecode available\n"); + mu::console() << "No bytecode available\n"; return; } - mu::console() << _T("Number of RPN tokens:") << (int)m_vRPN.size() << _T("\n"); + mu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n"; for (std::size_t i=0; i token_type; + typedef QmuParserToken token_type; /** \brief Token vector for storing the RPN. */ typedef std::vector rpn_type; @@ -112,11 +112,11 @@ public: QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); void Assign(const QmuParserByteCode &a_ByteCode); - void AddVar(value_type *a_pVar); - void AddVal(value_type a_fVal); + void AddVar(qreal *a_pVar); + void AddVal(qreal a_fVal); void AddOp(ECmdCode a_Oprt); void AddIfElse(ECmdCode a_Oprt); - void AddAssignOp(value_type *a_pVar); + void AddAssignOp(qreal *a_pVar); void AddFun(generic_fun_type a_pFun, int a_iArgc); void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 40d7de54d..b5dc3e89c 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -34,20 +34,13 @@ \brief This file contains standard definitions used by the parser. */ -#define QMUP_VERSION _T("2.2.3") -#define QMUP_VERSION_DATE _T("20121222; SF") +#define QMUP_VERSION "2.2.3" +#define QMUP_VERSION_DATE "20121222; SF" -#define QMUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") +#define QMUP_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" /** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */ -//#define MUP_MATH_EXCEPTIONS - -/** \brief Define the base datatype for values. - - This datatype must be a built in value type. You can not use custom classes. - It should be working with all types except "int"! -*/ -#define QMUP_BASETYPE double +//#define QMUP_MATH_EXCEPTIONS /** \brief Activate this option in order to compile with OpenMP support. @@ -59,13 +52,7 @@ /** \brief Definition of the basic parser string type. */ #define MUP_STRING_TYPE std::wstring - #if !defined(_T) - #define _T(x) L##x - #endif // not defined _T #else - #ifndef _T - #define _T(x) x - #endif /** \brief Definition of the basic parser string type. */ #define MUP_STRING_TYPE std::string @@ -89,9 +76,9 @@ if (!(COND)) \ { \ stringstream_type ss; \ - ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \ - << __FILE__ << _T(" line ") \ - << __LINE__ << _T("."); \ + ss << "Assertion \"" #COND "\" failed: ") \ + << __FILE__ << " line " \ + << __LINE__ << "."; \ throw ParserError( ss.str() ); \ } #else @@ -238,12 +225,6 @@ namespace qmu //------------------------------------------------------------------------------ // basic types - /** \brief The numeric datatype used by the parser. - - Normally this is a floating point type either single or double precision. - */ - typedef QMUP_BASETYPE value_type; - /** \brief The stringtype used by the parser. Depends on wether UNICODE is used or not. @@ -264,10 +245,10 @@ namespace qmu // Data container types /** \brief Type used for storing variables. */ - typedef std::map varmap_type; + typedef std::map varmap_type; /** \brief Type used for storing constants. */ - typedef std::map valmap_type; + typedef std::map valmap_type; /** \brief Type for assigning a string name to an index in the internal string table. */ typedef std::map strmap_type; @@ -275,91 +256,91 @@ namespace qmu // Parser callbacks /** \brief Callback type used for functions without arguments. */ - typedef value_type (*generic_fun_type)(); + typedef qreal (*generic_fun_type)(); /** \brief Callback type used for functions without arguments. */ - typedef value_type (*fun_type0)(); + typedef qreal (*fun_type0)(); /** \brief Callback type used for functions with a single arguments. */ - typedef value_type (*fun_type1)(value_type); + typedef qreal (*fun_type1)(qreal); /** \brief Callback type used for functions with two arguments. */ - typedef value_type (*fun_type2)(value_type, value_type); + typedef qreal (*fun_type2)(qreal, qreal); /** \brief Callback type used for functions with three arguments. */ - typedef value_type (*fun_type3)(value_type, value_type, value_type); + typedef qreal (*fun_type3)(qreal, qreal, qreal); /** \brief Callback type used for functions with four arguments. */ - typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type); + typedef qreal (*fun_type4)(qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type); + typedef qreal (*fun_type5)(qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*fun_type6)(qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*fun_type7)(qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*fun_type8)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*fun_type9)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*fun_type10)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions without arguments. */ - typedef value_type (*bulkfun_type0)(int, int); + typedef qreal (*bulkfun_type0)(int, int); /** \brief Callback type used for functions with a single arguments. */ - typedef value_type (*bulkfun_type1)(int, int, value_type); + typedef qreal (*bulkfun_type1)(int, int, qreal); /** \brief Callback type used for functions with two arguments. */ - typedef value_type (*bulkfun_type2)(int, int, value_type, value_type); + typedef qreal (*bulkfun_type2)(int, int, qreal, qreal); /** \brief Callback type used for functions with three arguments. */ - typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type); + typedef qreal (*bulkfun_type3)(int, int, qreal, qreal, qreal); /** \brief Callback type used for functions with four arguments. */ - typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type4)(int, int, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type5)(int, int, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type6)(int, int, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type7)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type8)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type9)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with five arguments. */ - typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); + typedef qreal (*bulkfun_type10)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); /** \brief Callback type used for functions with a variable argument list. */ - typedef value_type (*multfun_type)(const value_type*, int); + typedef qreal (*multfun_type)(const qreal*, int); /** \brief Callback type used for functions taking a string as an argument. */ - typedef value_type (*strfun_type1)(const char_type*); + typedef qreal (*strfun_type1)(const char_type*); /** \brief Callback type used for functions taking a string and a value as arguments. */ - typedef value_type (*strfun_type2)(const char_type*, value_type); + typedef qreal (*strfun_type2)(const char_type*, qreal); /** \brief Callback type used for functions taking a string and two values as arguments. */ - typedef value_type (*strfun_type3)(const char_type*, value_type, value_type); + typedef qreal (*strfun_type3)(const char_type*, qreal, qreal); /** \brief Callback used for functions that identify values in a string. */ - typedef int (*identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal); + typedef int (*identfun_type)(const char_type *sExpr, int *nPos, qreal *fVal); /** \brief Callback used for variable creation factory functions. */ - typedef value_type* (*facfun_type)(const char_type*, void*); + typedef qreal* (*facfun_type)(const char_type*, void*); } // end of namespace #endif diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 86b7bce20..c909f57c5 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -62,42 +62,42 @@ namespace qmu { m_vErrMsg.resize(ecCOUNT); - m_vErrMsg[ecUNASSIGNABLE_TOKEN] = _T("Unexpected token \"$TOK$\" found at position $POS$."); - m_vErrMsg[ecINTERNAL_ERROR] = _T("Internal error"); - m_vErrMsg[ecINVALID_NAME] = _T("Invalid function-, variable- or constant name: \"$TOK$\"."); - m_vErrMsg[ecINVALID_BINOP_IDENT] = _T("Invalid binary operator identifier: \"$TOK$\"."); - m_vErrMsg[ecINVALID_INFIX_IDENT] = _T("Invalid infix operator identifier: \"$TOK$\"."); - m_vErrMsg[ecINVALID_POSTFIX_IDENT] = _T("Invalid postfix operator identifier: \"$TOK$\"."); - m_vErrMsg[ecINVALID_FUN_PTR] = _T("Invalid pointer to callback function."); - m_vErrMsg[ecEMPTY_EXPRESSION] = _T("Expression is empty."); - m_vErrMsg[ecINVALID_VAR_PTR] = _T("Invalid pointer to variable."); - m_vErrMsg[ecUNEXPECTED_OPERATOR] = _T("Unexpected operator \"$TOK$\" found at position $POS$"); - m_vErrMsg[ecUNEXPECTED_EOF] = _T("Unexpected end of expression at position $POS$"); - m_vErrMsg[ecUNEXPECTED_ARG_SEP] = _T("Unexpected argument separator at position $POS$"); - m_vErrMsg[ecUNEXPECTED_PARENS] = _T("Unexpected parenthesis \"$TOK$\" at position $POS$"); - m_vErrMsg[ecUNEXPECTED_FUN] = _T("Unexpected function \"$TOK$\" at position $POS$"); - m_vErrMsg[ecUNEXPECTED_VAL] = _T("Unexpected value \"$TOK$\" found at position $POS$"); - m_vErrMsg[ecUNEXPECTED_VAR] = _T("Unexpected variable \"$TOK$\" found at position $POS$"); - m_vErrMsg[ecUNEXPECTED_ARG] = _T("Function arguments used without a function (position: $POS$)"); - m_vErrMsg[ecMISSING_PARENS] = _T("Missing parenthesis"); - m_vErrMsg[ecTOO_MANY_PARAMS] = _T("Too many parameters for function \"$TOK$\" at expression position $POS$"); - m_vErrMsg[ecTOO_FEW_PARAMS] = _T("Too few parameters for function \"$TOK$\" at expression position $POS$"); - m_vErrMsg[ecDIV_BY_ZERO] = _T("Divide by zero"); - m_vErrMsg[ecDOMAIN_ERROR] = _T("Domain error"); - m_vErrMsg[ecNAME_CONFLICT] = _T("Name conflict"); - m_vErrMsg[ecOPT_PRI] = _T("Invalid value for operator priority (must be greater or equal to zero)."); - m_vErrMsg[ecBUILTIN_OVERLOAD] = _T("user defined binary operator \"$TOK$\" conflicts with a built in operator."); - m_vErrMsg[ecUNEXPECTED_STR] = _T("Unexpected string token found at position $POS$."); - m_vErrMsg[ecUNTERMINATED_STRING] = _T("Unterminated string starting at position $POS$."); - m_vErrMsg[ecSTRING_EXPECTED] = _T("String function called with a non string type of argument."); - m_vErrMsg[ecVAL_EXPECTED] = _T("String value used where a numerical argument is expected."); - m_vErrMsg[ecOPRT_TYPE_CONFLICT] = _T("No suitable overload for operator \"$TOK$\" at position $POS$."); - m_vErrMsg[ecSTR_RESULT] = _T("Function result is a string."); - m_vErrMsg[ecGENERIC] = _T("Parser error."); - m_vErrMsg[ecLOCALE] = _T("Decimal separator is identic to function argument separator."); - m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket."); - m_vErrMsg[ecMISSING_ELSE_CLAUSE] = _T("If-then-else operator is missing an else clause"); - m_vErrMsg[ecMISPLACED_COLON] = _T("Misplaced colon at position $POS$"); + m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$."; + m_vErrMsg[ecINTERNAL_ERROR] = "Internal error"; + m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\"."; + m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function."; + m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty."; + m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable."; + m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$"; + m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$"; + m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$"; + m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$"; + m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)"; + m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis"; + m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$"; + m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$"; + m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero"; + m_vErrMsg[ecDOMAIN_ERROR] = "Domain error"; + m_vErrMsg[ecNAME_CONFLICT] = "Name conflict"; + m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero)."; + m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator."; + m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$."; + m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$."; + m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument."; + m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected."; + m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$."; + m_vErrMsg[ecSTR_RESULT] = "Function result is a string."; + m_vErrMsg[ecGENERIC] = "Parser error."; + m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator."; + m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket."; + m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause"; + m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$"; #if defined(_DEBUG) for (int i=0; i0) ? 1 : 0; } -value_type QmuParserInt::Ite(value_type v1, - value_type v2, - value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); } -value_type QmuParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); } -value_type QmuParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); } -value_type QmuParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); } -value_type QmuParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); } -value_type QmuParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); } -value_type QmuParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); } -value_type QmuParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); } -value_type QmuParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); } -value_type QmuParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); } -value_type QmuParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); } -value_type QmuParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); } -value_type QmuParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); } -value_type QmuParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); } -value_type QmuParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); } -value_type QmuParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); } -value_type QmuParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); } -value_type QmuParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); } -value_type QmuParserInt::Not(value_type v) { return !Round(v); } +qreal QmuParserInt::Abs(qreal v) { return (qreal)Round(fabs((double)v)); } +qreal QmuParserInt::Sign(qreal v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; } +qreal QmuParserInt::Ite(qreal v1, + qreal v2, + qreal v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); } +qreal QmuParserInt::Add(qreal v1, qreal v2) { return Round(v1) + Round(v2); } +qreal QmuParserInt::Sub(qreal v1, qreal v2) { return Round(v1) - Round(v2); } +qreal QmuParserInt::Mul(qreal v1, qreal v2) { return Round(v1) * Round(v2); } +qreal QmuParserInt::Div(qreal v1, qreal v2) { return Round(v1) / Round(v2); } +qreal QmuParserInt::Mod(qreal v1, qreal v2) { return Round(v1) % Round(v2); } +qreal QmuParserInt::Shr(qreal v1, qreal v2) { return Round(v1) >> Round(v2); } +qreal QmuParserInt::Shl(qreal v1, qreal v2) { return Round(v1) << Round(v2); } +qreal QmuParserInt::LogAnd(qreal v1, qreal v2) { return Round(v1) & Round(v2); } +qreal QmuParserInt::LogOr(qreal v1, qreal v2) { return Round(v1) | Round(v2); } +qreal QmuParserInt::And(qreal v1, qreal v2) { return Round(v1) && Round(v2); } +qreal QmuParserInt::Or(qreal v1, qreal v2) { return Round(v1) || Round(v2); } +qreal QmuParserInt::Less(qreal v1, qreal v2) { return Round(v1) < Round(v2); } +qreal QmuParserInt::Greater(qreal v1, qreal v2) { return Round(v1) > Round(v2); } +qreal QmuParserInt::LessEq(qreal v1, qreal v2) { return Round(v1) <= Round(v2); } +qreal QmuParserInt::GreaterEq(qreal v1, qreal v2) { return Round(v1) >= Round(v2); } +qreal QmuParserInt::Equal(qreal v1, qreal v2) { return Round(v1) == Round(v2); } +qreal QmuParserInt::NotEqual(qreal v1, qreal v2) { return Round(v1) != Round(v2); } +qreal QmuParserInt::Not(qreal v) { return !Round(v); } -value_type QmuParserInt::Pow(value_type v1, value_type v2) +qreal QmuParserInt::Pow(qreal v1, qreal v2) { return std::pow((double)Round(v1), (double)Round(v2)); } //--------------------------------------------------------------------------- // Unary operator Callbacks: Infix operators -value_type QmuParserInt::UnaryMinus(value_type v) +qreal QmuParserInt::UnaryMinus(qreal v) { return -Round(v); } //--------------------------------------------------------------------------- -value_type QmuParserInt::Sum(const value_type* a_afArg, int a_iArgc) +qreal QmuParserInt::Sum(const qreal* a_afArg, int a_iArgc) { if (!a_iArgc) - throw QmuParserError(_T("too few arguments for function sum.")); + throw QmuParserError("too few arguments for function sum."); - value_type fRes=0; + qreal fRes=0; for (int i=0; i> (iBits-i) ); *a_iPos += i+1; @@ -220,21 +220,21 @@ void QmuParserInt::InitConst() //--------------------------------------------------------------------------- void QmuParserInt::InitCharSets() { - DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") ); - DefineOprtChars( _T("+-*^/?<>=!%&|~'_") ); - DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") ); + DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); + DefineOprtChars( "+-*^/?<>=!%&|~'_" ); + DefineInfixOprtChars( "/+-*^?<>=!%&|~'_" ); } //--------------------------------------------------------------------------- /** \brief Initialize the default functions. */ void QmuParserInt::InitFun() { - DefineFun( _T("sign"), Sign); - DefineFun( _T("abs"), Abs); - DefineFun( _T("if"), Ite); - DefineFun( _T("sum"), Sum); - DefineFun( _T("min"), Min); - DefineFun( _T("max"), Max); + DefineFun( "sign", Sign); + DefineFun( "abs", Abs); + DefineFun( "if", Ite); + DefineFun( "sum", Sum); + DefineFun( "min", Min); + DefineFun( "max", Max); } //--------------------------------------------------------------------------- @@ -247,31 +247,31 @@ void QmuParserInt::InitOprt() // Disable all built in operators, they wont work with integer numbers // since they are designed for floating point numbers - DefineInfixOprt( _T("-"), UnaryMinus); - DefineInfixOprt( _T("!"), Not); + DefineInfixOprt( "-", UnaryMinus); + DefineInfixOprt( "!", Not); - DefineOprt( _T("&"), LogAnd, prLOGIC); - DefineOprt( _T("|"), LogOr, prLOGIC); - DefineOprt( _T("&&"), And, prLOGIC); - DefineOprt( _T("||"), Or, prLOGIC); + DefineOprt( "&", LogAnd, prLOGIC); + DefineOprt( "|", LogOr, prLOGIC); + DefineOprt( "&&", And, prLOGIC); + DefineOprt( "||", Or, prLOGIC); - DefineOprt( _T("<"), Less, prCMP); - DefineOprt( _T(">"), Greater, prCMP); - DefineOprt( _T("<="), LessEq, prCMP); - DefineOprt( _T(">="), GreaterEq, prCMP); - DefineOprt( _T("=="), Equal, prCMP); - DefineOprt( _T("!="), NotEqual, prCMP); + DefineOprt( "<", Less, prCMP); + DefineOprt( ">", Greater, prCMP); + DefineOprt( "<=", LessEq, prCMP); + DefineOprt( ">=", GreaterEq, prCMP); + DefineOprt( "==", Equal, prCMP); + DefineOprt( "!=", NotEqual, prCMP); - DefineOprt( _T("+"), Add, prADD_SUB); - DefineOprt( _T("-"), Sub, prADD_SUB); + DefineOprt( "+", Add, prADD_SUB); + DefineOprt( "-", Sub, prADD_SUB); - DefineOprt( _T("*"), Mul, prMUL_DIV); - DefineOprt( _T("/"), Div, prMUL_DIV); - DefineOprt( _T("%"), Mod, prMUL_DIV); + DefineOprt( "*", Mul, prMUL_DIV); + DefineOprt( "/", Div, prMUL_DIV); + DefineOprt( "%", Mod, prMUL_DIV); - DefineOprt( _T("^"), Pow, prPOW, oaRIGHT); - DefineOprt( _T(">>"), Shr, prMUL_DIV+1); - DefineOprt( _T("<<"), Shl, prMUL_DIV+1); + DefineOprt( "^", Pow, prPOW, oaRIGHT); + DefineOprt( ">>", Shr, prMUL_DIV+1); + DefineOprt( "<<", Shl, prMUL_DIV+1); } } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserint.h b/src/libs/qmuparser/qmuparserint.h index 1333142d5..98ef3b1a8 100644 --- a/src/libs/qmuparser/qmuparserint.h +++ b/src/libs/qmuparser/qmuparserint.h @@ -43,42 +43,42 @@ namespace qmu class QmuParserInt : public QmuParserBase { private: - static int Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); }; + static int Round(qreal v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); }; - static value_type Abs(value_type); - static value_type Sign(value_type); - static value_type Ite(value_type, value_type, value_type); + static qreal Abs(qreal); + static qreal Sign(qreal); + static qreal Ite(qreal, qreal, qreal); // !! The unary Minus is a MUST, otherwise you cant use negative signs !! - static value_type UnaryMinus(value_type); + static qreal UnaryMinus(qreal); // Functions with variable number of arguments - static value_type Sum(const value_type* a_afArg, int a_iArgc); // sum - static value_type Min(const value_type* a_afArg, int a_iArgc); // minimum - static value_type Max(const value_type* a_afArg, int a_iArgc); // maximum + static qreal Sum(const qreal* a_afArg, int a_iArgc); // sum + static qreal Min(const qreal* a_afArg, int a_iArgc); // minimum + static qreal Max(const qreal* a_afArg, int a_iArgc); // maximum // binary operator callbacks - static value_type Add(value_type v1, value_type v2); - static value_type Sub(value_type v1, value_type v2); - static value_type Mul(value_type v1, value_type v2); - static value_type Div(value_type v1, value_type v2); - static value_type Mod(value_type v1, value_type v2); - static value_type Pow(value_type v1, value_type v2); - static value_type Shr(value_type v1, value_type v2); - static value_type Shl(value_type v1, value_type v2); - static value_type LogAnd(value_type v1, value_type v2); - static value_type LogOr(value_type v1, value_type v2); - static value_type And(value_type v1, value_type v2); - static value_type Or(value_type v1, value_type v2); - static value_type Xor(value_type v1, value_type v2); - static value_type Less(value_type v1, value_type v2); - static value_type Greater(value_type v1, value_type v2); - static value_type LessEq(value_type v1, value_type v2); - static value_type GreaterEq(value_type v1, value_type v2); - static value_type Equal(value_type v1, value_type v2); - static value_type NotEqual(value_type v1, value_type v2); - static value_type Not(value_type v1); + static qreal Add(qreal v1, qreal v2); + static qreal Sub(qreal v1, qreal v2); + static qreal Mul(qreal v1, qreal v2); + static qreal Div(qreal v1, qreal v2); + static qreal Mod(qreal v1, qreal v2); + static qreal Pow(qreal v1, qreal v2); + static qreal Shr(qreal v1, qreal v2); + static qreal Shl(qreal v1, qreal v2); + static qreal LogAnd(qreal v1, qreal v2); + static qreal LogOr(qreal v1, qreal v2); + static qreal And(qreal v1, qreal v2); + static qreal Or(qreal v1, qreal v2); + static qreal Xor(qreal v1, qreal v2); + static qreal Less(qreal v1, qreal v2); + static qreal Greater(qreal v1, qreal v2); + static qreal LessEq(qreal v1, qreal v2); + static qreal GreaterEq(qreal v1, qreal v2); + static qreal Equal(qreal v1, qreal v2); + static qreal NotEqual(qreal v1, qreal v2); + static qreal Not(qreal v1); - static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); - static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); - static int IsVal (const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); + static int IsHexVal(const char_type* a_szExpr, int *a_iPos, qreal *a_iVal); + static int IsBinVal(const char_type* a_szExpr, int *a_iPos, qreal *a_iVal); + static int IsVal (const char_type* a_szExpr, int *a_iPos, qreal *a_iVal); /** \brief A facet class used to change decimal and thousands separator. */ template diff --git a/src/libs/qmuparser/qmuparserstack.h b/src/libs/qmuparser/qmuparserstack.h index 6c4cae6ea..c5ba528d0 100644 --- a/src/libs/qmuparser/qmuparserstack.h +++ b/src/libs/qmuparser/qmuparserstack.h @@ -79,7 +79,7 @@ namespace qmu TValueType pop() { if (empty()) - throw QmuParserError( _T("stack is empty.") ); + throw QmuParserError( "stack is empty." ); TValueType el = top(); m_Stack.pop(); diff --git a/src/libs/qmuparser/qmuparsertemplatemagic.h b/src/libs/qmuparser/qmuparsertemplatemagic.h index 324d659a9..9103091ca 100644 --- a/src/libs/qmuparser/qmuparsertemplatemagic.h +++ b/src/libs/qmuparser/qmuparsertemplatemagic.h @@ -115,26 +115,26 @@ namespace qmu template<> \ struct MathImpl \ { \ - static TYPE Sin(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Cos(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Tan(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ASin(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ACos(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ATan(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ATan2(TYPE, TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Sinh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Cosh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Tanh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ASinh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ACosh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE ATanh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Log(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Log2(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Log10(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Exp(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Abs(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Sqrt(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ - static TYPE Rint(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ + static TYPE Sin(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Cos(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Tan(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ASin(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ACos(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ATan(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ATan2(TYPE, TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Sinh(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Cosh(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Tanh(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ASinh(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ACosh(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE ATanh(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Log(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Log2(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Log10(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Exp(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Abs(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Sqrt(TYPE) { throw QmuParserError("unimplemented function."); } \ + static TYPE Rint(TYPE) { throw QmuParserError("unimplemented function."); } \ static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \ static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \ }; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index ce6e508ea..eeacdc29d 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -63,7 +63,7 @@ namespace qmu } //--------------------------------------------------------------------------------------------- - int QmuParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) + int QmuParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal) { if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) return 0; @@ -80,7 +80,7 @@ namespace qmu return 1; *a_iPos += (int)(2 + nPos); - *a_fVal = (value_type)iVal; + *a_fVal = (qreal)iVal; return 1; } @@ -88,18 +88,18 @@ namespace qmu int QmuParserTester::TestInterface() { int iStat = 0; - mu::console() << _T("testing member functions..."); + mu::console() << "testing member functions..."; // Test RemoveVar - value_type afVal[3] = {1,2,3}; + qreal afVal[3] = {1,2,3}; QmuParser p; try { - p.DefineVar( _T("a"), &afVal[0]); - p.DefineVar( _T("b"), &afVal[1]); - p.DefineVar( _T("c"), &afVal[2]); - p.SetExpr( _T("a+b+c") ); + p.DefineVar( "a", &afVal[0]); + p.DefineVar( "b", &afVal[1]); + p.DefineVar( "c", &afVal[2]); + p.SetExpr( "a+b+c" ); p.Eval(); } catch(...) @@ -109,7 +109,7 @@ namespace qmu try { - p.RemoveVar( _T("c") ); + p.RemoveVar( "c" ); p.Eval(); iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... } @@ -119,9 +119,9 @@ namespace qmu } if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -130,23 +130,23 @@ namespace qmu int QmuParserTester::TestStrArg() { int iStat = 0; - mu::console() << _T("testing string arguments..."); + mu::console() << "testing string arguments..."; - iStat += EqnTest(_T("valueof(\"\")"), 123, true); // empty string arguments caused a crash - iStat += EqnTest(_T("valueof(\"aaa\")+valueof(\"bbb\") "), 246, true); - iStat += EqnTest(_T("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323, true); + iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash + iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true); + iStat += EqnTest("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")", 323, true); // use in expressions with variables - iStat += EqnTest(_T("a*(atof(\"10\")-b)"), 8, true); - iStat += EqnTest(_T("a-(atof(\"10\")*b)"), -19, true); + iStat += EqnTest("a*(atof(\"10\")-b)", 8, true); + iStat += EqnTest("a-(atof(\"10\")*b)", -19, true); // string + numeric arguments - iStat += EqnTest(_T("strfun1(\"100\")"), 100, true); - iStat += EqnTest(_T("strfun2(\"100\",1)"), 101, true); - iStat += EqnTest(_T("strfun3(\"99\",1,2)"), 102, true); + iStat += EqnTest("strfun1(\"100\")", 100, true); + iStat += EqnTest("strfun2(\"100\",1)", 101, true); + iStat += EqnTest("strfun3(\"99\",1,2)", 102, true); if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -155,142 +155,142 @@ namespace qmu int QmuParserTester::TestBinOprt() { int iStat = 0; - mu::console() << _T("testing binary operators..."); + mu::console() << "testing binary operators..."; // built in operators // xor operator - //iStat += EqnTest(_T("1 xor 2"), 3, true); - //iStat += EqnTest(_T("a xor b"), 3, true); // with a=1 and b=2 - //iStat += EqnTest(_T("1 xor 2 xor 3"), 0, true); - //iStat += EqnTest(_T("a xor b xor 3"), 0, true); // with a=1 and b=2 - //iStat += EqnTest(_T("a xor b xor c"), 0, true); // with a=1 and b=2 - //iStat += EqnTest(_T("(1 xor 2) xor 3"), 0, true); - //iStat += EqnTest(_T("(a xor b) xor c"), 0, true); // with a=1 and b=2 - //iStat += EqnTest(_T("(a) xor (b) xor c"), 0, true); // with a=1 and b=2 - //iStat += EqnTest(_T("1 or 2"), 3, true); - //iStat += EqnTest(_T("a or b"), 3, true); // with a=1 and b=2 - iStat += EqnTest(_T("a++b"), 3, true); - iStat += EqnTest(_T("a ++ b"), 3, true); - iStat += EqnTest(_T("1++2"), 3, true); - iStat += EqnTest(_T("1 ++ 2"), 3, true); - iStat += EqnTest(_T("a add b"), 3, true); - iStat += EqnTest(_T("1 add 2"), 3, true); - iStat += EqnTest(_T("aa"), 1, true); - iStat += EqnTest(_T("a>a"), 0, true); - iStat += EqnTest(_T("aa"), 0, true); - iStat += EqnTest(_T("a<=a"), 1, true); - iStat += EqnTest(_T("a<=b"), 1, true); - iStat += EqnTest(_T("b<=a"), 0, true); - iStat += EqnTest(_T("a>=a"), 1, true); - iStat += EqnTest(_T("b>=a"), 1, true); - iStat += EqnTest(_T("a>=b"), 0, true); + //iStat += EqnTest("1 xor 2", 3, true); + //iStat += EqnTest("a xor b", 3, true); // with a=1 and b=2 + //iStat += EqnTest("1 xor 2 xor 3", 0, true); + //iStat += EqnTest("a xor b xor 3", 0, true); // with a=1 and b=2 + //iStat += EqnTest("a xor b xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("(1 xor 2) xor 3", 0, true); + //iStat += EqnTest("(a xor b) xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("(a) xor (b) xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("1 or 2"), 3, true; + //iStat += EqnTest("a or b"), 3, true; // with a=1 and b=2 + iStat += EqnTest("a++b", 3, true); + iStat += EqnTest("a ++ b", 3, true); + iStat += EqnTest("1++2", 3, true); + iStat += EqnTest("1 ++ 2", 3, true); + iStat += EqnTest("a add b", 3, true); + iStat += EqnTest("1 add 2", 3, true); + iStat += EqnTest("aa", 1, true); + iStat += EqnTest("a>a", 0, true); + iStat += EqnTest("aa", 0, true); + iStat += EqnTest("a<=a", 1, true); + iStat += EqnTest("a<=b", 1, true); + iStat += EqnTest("b<=a", 0, true); + iStat += EqnTest("a>=a", 1, true); + iStat += EqnTest("b>=a", 1, true); + iStat += EqnTest("a>=b", 0, true); // Test logical operators, expecially if user defined "&" and the internal "&&" collide - iStat += EqnTest(_T("1 && 1"), 1, true); - iStat += EqnTest(_T("1 && 0"), 0, true); - iStat += EqnTest(_T("(aa)"), 1, true); - iStat += EqnTest(_T("(ab)"), 0, true); - //iStat += EqnTest(_T("12 and 255"), 12, true); - //iStat += EqnTest(_T("12 and 0"), 0, true); - iStat += EqnTest(_T("12 & 255"), 12, true); - iStat += EqnTest(_T("12 & 0"), 0, true); - iStat += EqnTest(_T("12&255"), 12, true); - iStat += EqnTest(_T("12&0"), 0, true); + iStat += EqnTest("1 && 1", 1, true); + iStat += EqnTest("1 && 0", 0, true); + iStat += EqnTest("(aa)", 1, true); + iStat += EqnTest("(ab)", 0, true); + //iStat += EqnTest("12 and 255", 12, true); + //iStat += EqnTest("12 and 0", 0, true); + iStat += EqnTest("12 & 255", 12, true); + iStat += EqnTest("12 & 0", 0, true); + iStat += EqnTest("12&255", 12, true); + iStat += EqnTest("12&0", 0, true); // Assignement operator - iStat += EqnTest(_T("a = b"), 2, true); - iStat += EqnTest(_T("a = sin(b)"), 0.909297, true); - iStat += EqnTest(_T("a = 1+sin(b)"), 1.909297, true); - iStat += EqnTest(_T("(a=b)*2"), 4, true); - iStat += EqnTest(_T("2*(a=b)"), 4, true); - iStat += EqnTest(_T("2*(a=b+1)"), 6, true); - iStat += EqnTest(_T("(a=b+1)*2"), 6, true); + iStat += EqnTest("a = b", 2, true); + iStat += EqnTest("a = sin(b)", 0.909297, true); + iStat += EqnTest("a = 1+sin(b)", 1.909297, true); + iStat += EqnTest("(a=b)*2", 4, true); + iStat += EqnTest("2*(a=b)", 4, true); + iStat += EqnTest("2*(a=b+1)", 6, true); + iStat += EqnTest("(a=b+1)*2", 6, true); - iStat += EqnTest(_T("2^2^3"), 256, true); - iStat += EqnTest(_T("1/2/3"), 1.0/6.0, true); + iStat += EqnTest("2^2^3", 256, true); + iStat += EqnTest("1/2/3", 1.0/6.0, true); // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 - iStat += EqnTest(_T("3+4*2/(1-5)^2^3"), 3.0001220703125, true); + iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true); // Test user defined binary operators - iStat += EqnTestInt(_T("1 | 2"), 3, true); - iStat += EqnTestInt(_T("1 || 2"), 1, true); - iStat += EqnTestInt(_T("123 & 456"), 72, true); - iStat += EqnTestInt(_T("(123 & 456) % 10"), 2, true); - iStat += EqnTestInt(_T("1 && 0"), 0, true); - iStat += EqnTestInt(_T("123 && 456"), 1, true); - iStat += EqnTestInt(_T("1 << 3"), 8, true); - iStat += EqnTestInt(_T("8 >> 3"), 1, true); - iStat += EqnTestInt(_T("9 / 4"), 2, true); - iStat += EqnTestInt(_T("9 % 4"), 1, true); - iStat += EqnTestInt(_T("if(5%2,1,0)"), 1, true); - iStat += EqnTestInt(_T("if(4%2,1,0)"), 0, true); - iStat += EqnTestInt(_T("-10+1"), -9, true); - iStat += EqnTestInt(_T("1+2*3"), 7, true); - iStat += EqnTestInt(_T("const1 != const2"), 1, true); - iStat += EqnTestInt(_T("const1 != const2"), 0, false); - iStat += EqnTestInt(_T("const1 == const2"), 0, true); - iStat += EqnTestInt(_T("const1 == 1"), 1, true); - iStat += EqnTestInt(_T("10*(const1 == 1)"), 10, true); - iStat += EqnTestInt(_T("2*(const1 | const2)"), 6, true); - iStat += EqnTestInt(_T("2*(const1 | const2)"), 7, false); - iStat += EqnTestInt(_T("const1 < const2"), 1, true); - iStat += EqnTestInt(_T("const2 > const1"), 1, true); - iStat += EqnTestInt(_T("const1 <= 1"), 1, true); - iStat += EqnTestInt(_T("const2 >= 2"), 1, true); - iStat += EqnTestInt(_T("2*(const1 + const2)"), 6, true); - iStat += EqnTestInt(_T("2*(const1 - const2)"), -2, true); - iStat += EqnTestInt(_T("a != b"), 1, true); - iStat += EqnTestInt(_T("a != b"), 0, false); - iStat += EqnTestInt(_T("a == b"), 0, true); - iStat += EqnTestInt(_T("a == 1"), 1, true); - iStat += EqnTestInt(_T("10*(a == 1)"), 10, true); - iStat += EqnTestInt(_T("2*(a | b)"), 6, true); - iStat += EqnTestInt(_T("2*(a | b)"), 7, false); - iStat += EqnTestInt(_T("a < b"), 1, true); - iStat += EqnTestInt(_T("b > a"), 1, true); - iStat += EqnTestInt(_T("a <= 1"), 1, true); - iStat += EqnTestInt(_T("b >= 2"), 1, true); - iStat += EqnTestInt(_T("2*(a + b)"), 6, true); - iStat += EqnTestInt(_T("2*(a - b)"), -2, true); - iStat += EqnTestInt(_T("a + (a << b)"), 5, true); - iStat += EqnTestInt(_T("-2^2"), -4, true); - iStat += EqnTestInt(_T("3--a"), 4, true); - iStat += EqnTestInt(_T("3+-3^2"), -6, true); + iStat += EqnTestInt("1 | 2", 3, true); + iStat += EqnTestInt("1 || 2", 1, true); + iStat += EqnTestInt("123 & 456", 72, true); + iStat += EqnTestInt("(123 & 456) % 10", 2, true); + iStat += EqnTestInt("1 && 0", 0, true); + iStat += EqnTestInt("123 && 456", 1, true); + iStat += EqnTestInt("1 << 3", 8, true); + iStat += EqnTestInt("8 >> 3", 1, true); + iStat += EqnTestInt("9 / 4", 2, true); + iStat += EqnTestInt("9 % 4", 1, true); + iStat += EqnTestInt("if(5%2,1,0)", 1, true); + iStat += EqnTestInt("if(4%2,1,0)", 0, true); + iStat += EqnTestInt("-10+1", -9, true); + iStat += EqnTestInt("1+2*3", 7, true); + iStat += EqnTestInt("const1 != const2", 1, true); + iStat += EqnTestInt("const1 != const2", 0, false); + iStat += EqnTestInt("const1 == const2", 0, true); + iStat += EqnTestInt("const1 == 1", 1, true); + iStat += EqnTestInt("10*(const1 == 1)", 10, true); + iStat += EqnTestInt("2*(const1 | const2)", 6, true); + iStat += EqnTestInt("2*(const1 | const2)", 7, false); + iStat += EqnTestInt("const1 < const2", 1, true); + iStat += EqnTestInt("const2 > const1", 1, true); + iStat += EqnTestInt("const1 <= 1", 1, true); + iStat += EqnTestInt("const2 >= 2", 1, true); + iStat += EqnTestInt("2*(const1 + const2)", 6, true); + iStat += EqnTestInt("2*(const1 - const2)", -2, true); + iStat += EqnTestInt("a != b", 1, true); + iStat += EqnTestInt("a != b", 0, false); + iStat += EqnTestInt("a == b", 0, true); + iStat += EqnTestInt("a == 1", 1, true); + iStat += EqnTestInt("10*(a == 1)", 10, true); + iStat += EqnTestInt("2*(a | b)", 6, true); + iStat += EqnTestInt("2*(a | b)", 7, false); + iStat += EqnTestInt("a < b", 1, true); + iStat += EqnTestInt("b > a", 1, true); + iStat += EqnTestInt("a <= 1", 1, true); + iStat += EqnTestInt("b >= 2", 1, true); + iStat += EqnTestInt("2*(a + b)", 6, true); + iStat += EqnTestInt("2*(a - b)", -2, true); + iStat += EqnTestInt("a + (a << b)", 5, true); + iStat += EqnTestInt("-2^2", -4, true); + iStat += EqnTestInt("3--a", 4, true); + iStat += EqnTestInt("3+-3^2", -6, true); // Test reading of hex values: - iStat += EqnTestInt(_T("0xff"), 255, true); - iStat += EqnTestInt(_T("10+0xff"), 265, true); - iStat += EqnTestInt(_T("0xff+10"), 265, true); - iStat += EqnTestInt(_T("10*0xff"), 2550, true); - iStat += EqnTestInt(_T("0xff*10"), 2550, true); - iStat += EqnTestInt(_T("10+0xff+1"), 266, true); - iStat += EqnTestInt(_T("1+0xff+10"), 266, true); + iStat += EqnTestInt("0xff", 255, true); + iStat += EqnTestInt("10+0xff", 265, true); + iStat += EqnTestInt("0xff+10", 265, true); + iStat += EqnTestInt("10*0xff", 2550, true); + iStat += EqnTestInt("0xff*10", 2550, true); + iStat += EqnTestInt("10+0xff+1", 266, true); + iStat += EqnTestInt("1+0xff+10", 266, true); -// incorrect: '^' is yor here, not power +// incorrect: '^' is your here, not power // iStat += EqnTestInt("-(1+2)^2", -9, true); // iStat += EqnTestInt("-1^3", -1, true); // Test precedence // a=1, b=2, c=3 - iStat += EqnTestInt(_T("a + b * c"), 7, true); - iStat += EqnTestInt(_T("a * b + c"), 5, true); - iStat += EqnTestInt(_T("a10"), 0, true); - iStat += EqnTestInt(_T("a10", 0, true); + iStat += EqnTestInt("a"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("?<"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("**"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("xor"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("and"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("or"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("not"), f1of1) - PARSER_THROWCHECK(PostfixOprt, true, _T("!"), f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "-a", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "?a", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "_", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "#", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "&&", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "||", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "&", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "|", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "++", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "--", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "?>", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "?<", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "**", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "xor", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "and", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "or", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "not", f1of1) + PARSER_THROWCHECK(PostfixOprt, true, "!", f1of1) // Binary operator // The following must fail with builtin operators activated // p.EnableBuiltInOp(true); -> this is the default p.ClearPostfixOprt(); - PARSER_THROWCHECK(Oprt, false, _T("+"), f1of2) - PARSER_THROWCHECK(Oprt, false, _T("-"), f1of2) - PARSER_THROWCHECK(Oprt, false, _T("*"), f1of2) - PARSER_THROWCHECK(Oprt, false, _T("/"), f1of2) - PARSER_THROWCHECK(Oprt, false, _T("^"), f1of2) - PARSER_THROWCHECK(Oprt, false, _T("&&"), f1of2) - PARSER_THROWCHECK(Oprt, false, _T("||"), f1of2) + PARSER_THROWCHECK(Oprt, false, "+", f1of2) + PARSER_THROWCHECK(Oprt, false, "-", f1of2) + PARSER_THROWCHECK(Oprt, false, "*", f1of2) + PARSER_THROWCHECK(Oprt, false, "/", f1of2) + PARSER_THROWCHECK(Oprt, false, "^", f1of2) + PARSER_THROWCHECK(Oprt, false, "&&", f1of2) + PARSER_THROWCHECK(Oprt, false, "||", f1of2) // without activated built in operators it should work p.EnableBuiltInOprt(false); - PARSER_THROWCHECK(Oprt, true, _T("+"), f1of2) - PARSER_THROWCHECK(Oprt, true, _T("-"), f1of2) - PARSER_THROWCHECK(Oprt, true, _T("*"), f1of2) - PARSER_THROWCHECK(Oprt, true, _T("/"), f1of2) - PARSER_THROWCHECK(Oprt, true, _T("^"), f1of2) - PARSER_THROWCHECK(Oprt, true, _T("&&"), f1of2) - PARSER_THROWCHECK(Oprt, true, _T("||"), f1of2) + PARSER_THROWCHECK(Oprt, true, "+", f1of2) + PARSER_THROWCHECK(Oprt, true, "-", f1of2) + PARSER_THROWCHECK(Oprt, true, "*", f1of2) + PARSER_THROWCHECK(Oprt, true, "/", f1of2) + PARSER_THROWCHECK(Oprt, true, "^", f1of2) + PARSER_THROWCHECK(Oprt, true, "&&", f1of2) + PARSER_THROWCHECK(Oprt, true, "||", f1of2) #undef PARSER_THROWCHECK if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -408,47 +408,47 @@ namespace qmu int QmuParserTester::TestSyntax() { int iStat = 0; - mu::console() << _T("testing syntax engine..."); + mu::console() << "testing syntax engine..."; - iStat += ThrowTest(_T("1,"), ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest(_T("a,"), ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest(_T("sin(8),"), ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest(_T("(sin(8)),"), ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest(_T("a{m},"), ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest("sin(8),", ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest("(sin(8)),", ecUNEXPECTED_EOF); // incomplete hex definition + iStat += ThrowTest("a{m},", ecUNEXPECTED_EOF); // incomplete hex definition - iStat += EqnTest(_T("(1+ 2*a)"), 3, true); // Spaces within formula - iStat += EqnTest(_T("sqrt((4))"), 2, true); // Multiple brackets - iStat += EqnTest(_T("sqrt((2)+2)"), 2, true);// Multiple brackets - iStat += EqnTest(_T("sqrt(2+(2))"), 2, true);// Multiple brackets - iStat += EqnTest(_T("sqrt(a+(3))"), 2, true);// Multiple brackets - iStat += EqnTest(_T("sqrt((3)+a)"), 2, true);// Multiple brackets - iStat += EqnTest(_T("order(1,2)"), 1, true); // May not cause name collision with operator "or" - iStat += EqnTest(_T("(2+"), 0, false); // missing closing bracket - iStat += EqnTest(_T("2++4"), 0, false); // unexpected operator - iStat += EqnTest(_T("2+-4"), 0, false); // unexpected operator - iStat += EqnTest(_T("(2+)"), 0, false); // unexpected closing bracket - iStat += EqnTest(_T("--2"), 0, false); // double sign - iStat += EqnTest(_T("ksdfj"), 0, false); // unknown token - iStat += EqnTest(_T("()"), 0, false); // empty bracket without a function - iStat += EqnTest(_T("5+()"), 0, false); // empty bracket without a function - iStat += EqnTest(_T("sin(cos)"), 0, false); // unexpected function - iStat += EqnTest(_T("5t6"), 0, false); // unknown token - iStat += EqnTest(_T("5 t 6"), 0, false); // unknown token - iStat += EqnTest(_T("8*"), 0, false); // unexpected end of formula - iStat += EqnTest(_T(",3"), 0, false); // unexpected comma - iStat += EqnTest(_T("3,5"), 0, false); // unexpected comma - iStat += EqnTest(_T("sin(8,8)"), 0, false); // too many function args - iStat += EqnTest(_T("(7,8)"), 0, false); // too many function args - iStat += EqnTest(_T("sin)"), 0, false); // unexpected closing bracket - iStat += EqnTest(_T("a)"), 0, false); // unexpected closing bracket - iStat += EqnTest(_T("pi)"), 0, false); // unexpected closing bracket - iStat += EqnTest(_T("sin(())"), 0, false); // unexpected closing bracket - iStat += EqnTest(_T("sin()"), 0, false); // unexpected closing bracket + iStat += EqnTest("(1+ 2*a)", 3, true); // Spaces within formula + iStat += EqnTest("sqrt((4))", 2, true); // Multiple brackets + iStat += EqnTest("sqrt((2)+2)", 2, true);// Multiple brackets + iStat += EqnTest("sqrt(2+(2))", 2, true);// Multiple brackets + iStat += EqnTest("sqrt(a+(3))", 2, true);// Multiple brackets + iStat += EqnTest("sqrt((3)+a)", 2, true);// Multiple brackets + iStat += EqnTest("order(1,2)", 1, true); // May not cause name collision with operator "or" + iStat += EqnTest("(2+", 0, false); // missing closing bracket + iStat += EqnTest("2++4", 0, false); // unexpected operator + iStat += EqnTest("2+-4", 0, false); // unexpected operator + iStat += EqnTest("(2+)", 0, false); // unexpected closing bracket + iStat += EqnTest("--2", 0, false); // double sign + iStat += EqnTest("ksdfj", 0, false); // unknown token + iStat += EqnTest("()", 0, false); // empty bracket without a function + iStat += EqnTest("5+()", 0, false); // empty bracket without a function + iStat += EqnTest("sin(cos)", 0, false); // unexpected function + iStat += EqnTest("5t6", 0, false); // unknown token + iStat += EqnTest("5 t 6", 0, false); // unknown token + iStat += EqnTest("8*", 0, false); // unexpected end of formula + iStat += EqnTest(",3", 0, false); // unexpected comma + iStat += EqnTest("3,5", 0, false); // unexpected comma + iStat += EqnTest("sin(8,8)", 0, false); // too many function args + iStat += EqnTest("(7,8)", 0, false); // too many function args + iStat += EqnTest("sin)", 0, false); // unexpected closing bracket + iStat += EqnTest("a)", 0, false); // unexpected closing bracket + iStat += EqnTest("pi)", 0, false); // unexpected closing bracket + iStat += EqnTest("sin(())", 0, false); // unexpected closing bracket + iStat += EqnTest("sin()", 0, false); // unexpected closing bracket if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -457,53 +457,53 @@ namespace qmu int QmuParserTester::TestVarConst() { int iStat = 0; - mu::console() << _T("testing variable/constant detection..."); + mu::console() << "testing variable/constant detection..."; // Test if the result changes when a variable changes - iStat += EqnTestWithVarChange( _T("a"), 1, 1, 2, 2 ); - iStat += EqnTestWithVarChange( _T("2*a"), 2, 4, 3, 6 ); + iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 ); + iStat += EqnTestWithVarChange( "2*a", 2, 4, 3, 6 ); // distinguish constants with same basename - iStat += EqnTest( _T("const"), 1, true); - iStat += EqnTest( _T("const1"), 2, true); - iStat += EqnTest( _T("const2"), 3, true); - iStat += EqnTest( _T("2*const"), 2, true); - iStat += EqnTest( _T("2*const1"), 4, true); - iStat += EqnTest( _T("2*const2"), 6, true); - iStat += EqnTest( _T("2*const+1"), 3, true); - iStat += EqnTest( _T("2*const1+1"), 5, true); - iStat += EqnTest( _T("2*const2+1"), 7, true); - iStat += EqnTest( _T("const"), 0, false); - iStat += EqnTest( _T("const1"), 0, false); - iStat += EqnTest( _T("const2"), 0, false); + iStat += EqnTest( "const", 1, true); + iStat += EqnTest( "const1", 2, true); + iStat += EqnTest( "const2", 3, true); + iStat += EqnTest( "2*const", 2, true); + iStat += EqnTest( "2*const1", 4, true); + iStat += EqnTest( "2*const2", 6, true); + iStat += EqnTest( "2*const+1", 3, true); + iStat += EqnTest( "2*const1+1", 5, true); + iStat += EqnTest( "2*const2+1", 7, true); + iStat += EqnTest( "const", 0, false); + iStat += EqnTest( "const1", 0, false); + iStat += EqnTest( "const2", 0, false); // distinguish variables with same basename - iStat += EqnTest( _T("a"), 1, true); - iStat += EqnTest( _T("aa"), 2, true); - iStat += EqnTest( _T("2*a"), 2, true); - iStat += EqnTest( _T("2*aa"), 4, true); - iStat += EqnTest( _T("2*a-1"), 1, true); - iStat += EqnTest( _T("2*aa-1"), 3, true); + iStat += EqnTest( "a", 1, true); + iStat += EqnTest( "aa", 2, true); + iStat += EqnTest( "2*a", 2, true); + iStat += EqnTest( "2*aa", 4, true); + iStat += EqnTest( "2*a-1", 1, true); + iStat += EqnTest( "2*aa-1", 3, true); // custom value recognition - iStat += EqnTest( _T("0xff"), 255, true); - iStat += EqnTest( _T("0x97 + 0xff"), 406, true); + iStat += EqnTest( "0xff", 255, true); + iStat += EqnTest( "0x97 + 0xff", 406, true); // Finally test querying of used variables try { int idx; qmu::QmuParser p; - qmu::value_type vVarVal[] = { 1, 2, 3, 4, 5}; - p.DefineVar( _T("a"), &vVarVal[0]); - p.DefineVar( _T("b"), &vVarVal[1]); - p.DefineVar( _T("c"), &vVarVal[2]); - p.DefineVar( _T("d"), &vVarVal[3]); - p.DefineVar( _T("e"), &vVarVal[4]); + qreal vVarVal[] = { 1, 2, 3, 4, 5}; + p.DefineVar( "a", &vVarVal[0]); + p.DefineVar( "b", &vVarVal[1]); + p.DefineVar( "c", &vVarVal[2]); + p.DefineVar( "d", &vVarVal[3]); + p.DefineVar( "e", &vVarVal[4]); // Test lookup of defined variables // 4 used variables - p.SetExpr( _T("a+b+c+d") ); + p.SetExpr( "a+b+c+d" ); mu::varmap_type UsedVar = p.GetUsedVar(); int iCount = (int)UsedVar.size(); if (iCount!=4) @@ -522,7 +522,7 @@ namespace qmu } // Test lookup of undefined variables - p.SetExpr( _T("undef1+undef2+undef3") ); + p.SetExpr( "undef1+undef2+undef3" ); UsedVar = p.GetUsedVar(); iCount = (int)UsedVar.size(); if (iCount!=3) @@ -540,7 +540,7 @@ namespace qmu } // 1 used variables - p.SetExpr( _T("a+b") ); + p.SetExpr( "a+b" ); UsedVar = p.GetUsedVar(); iCount = (int)UsedVar.size(); if (iCount!=2) throw false; @@ -555,9 +555,9 @@ namespace qmu } if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -566,92 +566,92 @@ namespace qmu int QmuParserTester::TestMultiArg() { int iStat = 0; - mu::console() << _T("testing multiarg functions..."); + mu::console() << "testing multiarg functions..."; // Compound expressions - iStat += EqnTest( _T("1,2,3"), 3, true); - iStat += EqnTest( _T("a,b,c"), 3, true); - iStat += EqnTest( _T("a=10,b=20,c=a*b"), 200, true); - iStat += EqnTest( _T("1,\n2,\n3"), 3, true); - iStat += EqnTest( _T("a,\nb,\nc"), 3, true); - iStat += EqnTest( _T("a=10,\nb=20,\nc=a*b"), 200, true); - iStat += EqnTest( _T("1,\r\n2,\r\n3"), 3, true); - iStat += EqnTest( _T("a,\r\nb,\r\nc"), 3, true); - iStat += EqnTest( _T("a=10,\r\nb=20,\r\nc=a*b"), 200, true); + iStat += EqnTest( "1,2,3", 3, true); + iStat += EqnTest( "a,b,c", 3, true); + iStat += EqnTest( "a=10,b=20,c=a*b", 200, true); + iStat += EqnTest( "1,\n2,\n3", 3, true); + iStat += EqnTest( "a,\nb,\nc", 3, true); + iStat += EqnTest( "a=10,\nb=20,\nc=a*b", 200, true); + iStat += EqnTest( "1,\r\n2,\r\n3", 3, true); + iStat += EqnTest( "a,\r\nb,\r\nc", 3, true); + iStat += EqnTest( "a=10,\r\nb=20,\r\nc=a*b", 200, true); // picking the right argument - iStat += EqnTest( _T("f1of1(1)"), 1, true); - iStat += EqnTest( _T("f1of2(1, 2)"), 1, true); - iStat += EqnTest( _T("f2of2(1, 2)"), 2, true); - iStat += EqnTest( _T("f1of3(1, 2, 3)"), 1, true); - iStat += EqnTest( _T("f2of3(1, 2, 3)"), 2, true); - iStat += EqnTest( _T("f3of3(1, 2, 3)"), 3, true); - iStat += EqnTest( _T("f1of4(1, 2, 3, 4)"), 1, true); - iStat += EqnTest( _T("f2of4(1, 2, 3, 4)"), 2, true); - iStat += EqnTest( _T("f3of4(1, 2, 3, 4)"), 3, true); - iStat += EqnTest( _T("f4of4(1, 2, 3, 4)"), 4, true); - iStat += EqnTest( _T("f1of5(1, 2, 3, 4, 5)"), 1, true); - iStat += EqnTest( _T("f2of5(1, 2, 3, 4, 5)"), 2, true); - iStat += EqnTest( _T("f3of5(1, 2, 3, 4, 5)"), 3, true); - iStat += EqnTest( _T("f4of5(1, 2, 3, 4, 5)"), 4, true); - iStat += EqnTest( _T("f5of5(1, 2, 3, 4, 5)"), 5, true); + iStat += EqnTest( "f1of1(1)", 1, true); + iStat += EqnTest( "f1of2(1, 2)", 1, true); + iStat += EqnTest( "f2of2(1, 2)", 2, true); + iStat += EqnTest( "f1of3(1, 2, 3)", 1, true); + iStat += EqnTest( "f2of3(1, 2, 3)", 2, true); + iStat += EqnTest( "f3of3(1, 2, 3)", 3, true); + iStat += EqnTest( "f1of4(1, 2, 3, 4)", 1, true); + iStat += EqnTest( "f2of4(1, 2, 3, 4)", 2, true); + iStat += EqnTest( "f3of4(1, 2, 3, 4)", 3, true); + iStat += EqnTest( "f4of4(1, 2, 3, 4)", 4, true); + iStat += EqnTest( "f1of5(1, 2, 3, 4, 5)", 1, true); + iStat += EqnTest( "f2of5(1, 2, 3, 4, 5)", 2, true); + iStat += EqnTest( "f3of5(1, 2, 3, 4, 5)", 3, true); + iStat += EqnTest( "f4of5(1, 2, 3, 4, 5)", 4, true); + iStat += EqnTest( "f5of5(1, 2, 3, 4, 5)", 5, true); // Too few arguments / Too many arguments - iStat += EqnTest( _T("1+ping()"), 11, true); - iStat += EqnTest( _T("ping()+1"), 11, true); - iStat += EqnTest( _T("2*ping()"), 20, true); - iStat += EqnTest( _T("ping()*2"), 20, true); - iStat += EqnTest( _T("ping(1,2)"), 0, false); - iStat += EqnTest( _T("1+ping(1,2)"), 0, false); - iStat += EqnTest( _T("f1of1(1,2)"), 0, false); - iStat += EqnTest( _T("f1of1()"), 0, false); - iStat += EqnTest( _T("f1of2(1, 2, 3)"), 0, false); - iStat += EqnTest( _T("f1of2(1)"), 0, false); - iStat += EqnTest( _T("f1of3(1, 2, 3, 4)"), 0, false); - iStat += EqnTest( _T("f1of3(1)"), 0, false); - iStat += EqnTest( _T("f1of4(1, 2, 3, 4, 5)"), 0, false); - iStat += EqnTest( _T("f1of4(1)"), 0, false); - iStat += EqnTest( _T("(1,2,3)"), 0, false); - iStat += EqnTest( _T("1,2,3"), 0, false); - iStat += EqnTest( _T("(1*a,2,3)"), 0, false); - iStat += EqnTest( _T("1,2*a,3"), 0, false); + iStat += EqnTest( "1+ping()", 11, true); + iStat += EqnTest( "ping()+1", 11, true); + iStat += EqnTest( "2*ping()", 20, true); + iStat += EqnTest( "ping()*2", 20, true); + iStat += EqnTest( "ping(1,2)", 0, false); + iStat += EqnTest( "1+ping(1,2)", 0, false); + iStat += EqnTest( "f1of1(1,2)", 0, false); + iStat += EqnTest( "f1of1()", 0, false); + iStat += EqnTest( "f1of2(1, 2, 3)", 0, false); + iStat += EqnTest( "f1of2(1)", 0, false); + iStat += EqnTest( "f1of3(1, 2, 3, 4)", 0, false); + iStat += EqnTest( "f1of3(1)", 0, false); + iStat += EqnTest( "f1of4(1, 2, 3, 4, 5)", 0, false); + iStat += EqnTest( "f1of4(1)", 0, false); + iStat += EqnTest( "(1,2,3)", 0, false); + iStat += EqnTest( "1,2,3", 0, false); + iStat += EqnTest( "(1*a,2,3)", 0, false); + iStat += EqnTest( "1,2*a,3", 0, false); // correct calculation of arguments - iStat += EqnTest( _T("min(a, 1)"), 1, true); - iStat += EqnTest( _T("min(3*2, 1)"), 1, true); - iStat += EqnTest( _T("min(3*2, 1)"), 6, false); - iStat += EqnTest( _T("firstArg(2,3,4)"), 2, true); - iStat += EqnTest( _T("lastArg(2,3,4)"), 4, true); - iStat += EqnTest( _T("min(3*a+1, 1)"), 1, true); - iStat += EqnTest( _T("max(3*a+1, 1)"), 4, true); - iStat += EqnTest( _T("max(3*a+1, 1)*2"), 8, true); - iStat += EqnTest( _T("2*max(3*a+1, 1)+2"), 10, true); + iStat += EqnTest( "min(a, 1)", 1, true); + iStat += EqnTest( "min(3*2, 1)", 1, true); + iStat += EqnTest( "min(3*2, 1)", 6, false); + iStat += EqnTest( "firstArg(2,3,4)", 2, true); + iStat += EqnTest( "lastArg(2,3,4)", 4, true); + iStat += EqnTest( "min(3*a+1, 1)", 1, true); + iStat += EqnTest( "max(3*a+1, 1)", 4, true); + iStat += EqnTest( "max(3*a+1, 1)*2", 8, true); + iStat += EqnTest( "2*max(3*a+1, 1)+2", 10, true); // functions with Variable argument count - iStat += EqnTest( _T("sum(a)"), 1, true); - iStat += EqnTest( _T("sum(1,2,3)"), 6, true); - iStat += EqnTest( _T("sum(a,b,c)"), 6, true); - iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"), 4, true); - iStat += EqnTest( _T("2*sum(1,2,3)"), 12, true); - iStat += EqnTest( _T("2*sum(1,2,3)+2"), 14, true); - iStat += EqnTest( _T("2*sum(-1,2,3)+2"), 10, true); - iStat += EqnTest( _T("2*sum(-1,2,-(-a))+2"), 6, true); - iStat += EqnTest( _T("2*sum(-1,10,-a)+2"), 18, true); - iStat += EqnTest( _T("2*sum(1,2,3)*2"), 24, true); - iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"), 4, true); - iStat += EqnTest( _T("sum(1*3, 4, a+2)"), 10, true); - iStat += EqnTest( _T("sum(1*3, 2*sum(1,2,2), a+2)"), 16, true); - iStat += EqnTest( _T("sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)"), 24, true); + iStat += EqnTest( "sum(a)", 1, true); + iStat += EqnTest( "sum(1,2,3)", 6, true); + iStat += EqnTest( "sum(a,b,c)", 6, true); + iStat += EqnTest( "sum(1,-max(1,2),3)*2", 4, true); + iStat += EqnTest( "2*sum(1,2,3)", 12, true); + iStat += EqnTest( "2*sum(1,2,3)+2", 14, true); + iStat += EqnTest( "2*sum(-1,2,3)+2", 10, true); + iStat += EqnTest( "2*sum(-1,2,-(-a))+2", 6, true); + iStat += EqnTest( "2*sum(-1,10,-a)+2", 18, true); + iStat += EqnTest( "2*sum(1,2,3)*2", 24, true); + iStat += EqnTest( "sum(1,-max(1,2),3)*2", 4, true); + iStat += EqnTest( "sum(1*3, 4, a+2)", 10, true); + iStat += EqnTest( "sum(1*3, 2*sum(1,2,2), a+2)", 16, true); + iStat += EqnTest( "sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)", 24, true); // some failures - iStat += EqnTest( _T("sum()"), 0, false); - iStat += EqnTest( _T("sum(,)"), 0, false); - iStat += EqnTest( _T("sum(1,2,)"), 0, false); - iStat += EqnTest( _T("sum(,1,2)"), 0, false); + iStat += EqnTest( "sum()", 0, false); + iStat += EqnTest( "sum(,)", 0, false); + iStat += EqnTest( "sum(1,2,)", 0, false); + iStat += EqnTest( "sum(,1,2)", 0, false); if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -663,60 +663,60 @@ namespace qmu int iStat(0); mu::console() << "testing infix operators..."; - iStat += EqnTest( _T("-1"), -1, true); - iStat += EqnTest( _T("-(-1)"), 1, true); - iStat += EqnTest( _T("-(-1)*2"), 2, true); - iStat += EqnTest( _T("-(-2)*sqrt(4)"), 4, true); - iStat += EqnTest( _T("-_pi"), -PARSER_CONST_PI, true); - iStat += EqnTest( _T("-a"), -1, true); - iStat += EqnTest( _T("-(a)"), -1, true); - iStat += EqnTest( _T("-(-a)"), 1, true); - iStat += EqnTest( _T("-(-a)*2"), 2, true); - iStat += EqnTest( _T("-(8)"), -8, true); - iStat += EqnTest( _T("-8"), -8, true); - iStat += EqnTest( _T("-(2+1)"), -3, true); - iStat += EqnTest( _T("-(f1of1(1+2*3)+1*2)"), -9, true); - iStat += EqnTest( _T("-(-f1of1(1+2*3)+1*2)"), 5, true); - iStat += EqnTest( _T("-sin(8)"), -0.989358, true); - iStat += EqnTest( _T("3-(-a)"), 4, true); - iStat += EqnTest( _T("3--a"), 4, true); - iStat += EqnTest( _T("-1*3"), -3, true); + iStat += EqnTest( "-1", -1, true); + iStat += EqnTest( "-(-1)", 1, true); + iStat += EqnTest( "-(-1)*2", 2, true); + iStat += EqnTest( "-(-2)*sqrt(4)", 4, true); + iStat += EqnTest( "-_pi", -PARSER_CONST_PI, true); + iStat += EqnTest( "-a", -1, true); + iStat += EqnTest( "-(a)", -1, true); + iStat += EqnTest( "-(-a)", 1, true); + iStat += EqnTest( "-(-a)*2", 2, true); + iStat += EqnTest( "-(8)", -8, true); + iStat += EqnTest( "-8", -8, true); + iStat += EqnTest( "-(2+1)", -3, true); + iStat += EqnTest( "-(f1of1(1+2*3)+1*2)", -9, true); + iStat += EqnTest( "-(-f1of1(1+2*3)+1*2)", 5, true); + iStat += EqnTest( "-sin(8)", -0.989358, true); + iStat += EqnTest( "3-(-a)", 4, true); + iStat += EqnTest( "3--a", 4, true); + iStat += EqnTest( "-1*3", -3, true); // Postfix / infix priorities - iStat += EqnTest( _T("~2#"), 8, true); - iStat += EqnTest( _T("~f1of1(2)#"), 8, true); - iStat += EqnTest( _T("~(b)#"), 8, true); - iStat += EqnTest( _T("(~b)#"), 12, true); - iStat += EqnTest( _T("~(2#)"), 8, true); - iStat += EqnTest( _T("~(f1of1(2)#)"), 8, true); + iStat += EqnTest( "~2#", 8, true); + iStat += EqnTest( "~f1of1(2)#", 8, true); + iStat += EqnTest( "~(b)#", 8, true); + iStat += EqnTest( "(~b)#", 12, true); + iStat += EqnTest( "~(2#)", 8, true); + iStat += EqnTest( "~(f1of1(2)#)", 8, true); // - iStat += EqnTest( _T("-2^2"),-4, true); - iStat += EqnTest( _T("-(a+b)^2"),-9, true); - iStat += EqnTest( _T("(-3)^2"),9, true); - iStat += EqnTest( _T("-(-2^2)"),4, true); - iStat += EqnTest( _T("3+-3^2"),-6, true); + iStat += EqnTest( "-2^2",-4, true); + iStat += EqnTest( "-(a+b)^2",-9, true); + iStat += EqnTest( "(-3)^2",9, true); + iStat += EqnTest( "-(-2^2)",4, true); + iStat += EqnTest( "3+-3^2",-6, true); // The following assumes use of sqr as postfix operator ("") together // with a sign operator of low priority: - iStat += EqnTest( _T("-2'"), -4, true); - iStat += EqnTest( _T("-(1+1)'"),-4, true); - iStat += EqnTest( _T("2+-(1+1)'"),-2, true); - iStat += EqnTest( _T("2+-2'"), -2, true); + iStat += EqnTest( "-2'", -4, true); + iStat += EqnTest( "-(1+1)'",-4, true); + iStat += EqnTest( "2+-(1+1)'",-2, true); + iStat += EqnTest( "2+-2'", -2, true); // This is the classic behaviour of the infix sign operator (here: "$") which is // now deprecated: - iStat += EqnTest( _T("$2^2"),4, true); - iStat += EqnTest( _T("$(a+b)^2"),9, true); - iStat += EqnTest( _T("($3)^2"),9, true); - iStat += EqnTest( _T("$($2^2)"),-4, true); - iStat += EqnTest( _T("3+$3^2"),12, true); + iStat += EqnTest( "$2^2",4, true); + iStat += EqnTest( "$(a+b)^2",9, true); + iStat += EqnTest( "($3)^2",9, true); + iStat += EqnTest( "$($2^2)",-4, true); + iStat += EqnTest( "3+$3^2",12, true); // infix operators sharing the first few characters - iStat += EqnTest( _T("~ 123"), 123+2, true); - iStat += EqnTest( _T("~~ 123"), 123+2, true); + iStat += EqnTest( "~ 123", 123+2, true); + iStat += EqnTest( "~~ 123", 123+2, true); if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -726,49 +726,49 @@ namespace qmu int QmuParserTester::TestPostFix() { int iStat = 0; - mu::console() << _T("testing postfix operators..."); + mu::console() << "testing postfix operators..."; // application - iStat += EqnTest( _T("3{m}+5"), 5.003, true); - iStat += EqnTest( _T("1000{m}"), 1, true); - iStat += EqnTest( _T("1000 {m}"), 1, true); - iStat += EqnTest( _T("(a){m}"), 1e-3, true); - iStat += EqnTest( _T("a{m}"), 1e-3, true); - iStat += EqnTest( _T("a {m}"), 1e-3, true); - iStat += EqnTest( _T("-(a){m}"), -1e-3, true); - iStat += EqnTest( _T("-2{m}"), -2e-3, true); - iStat += EqnTest( _T("-2 {m}"), -2e-3, true); - iStat += EqnTest( _T("f1of1(1000){m}"), 1, true); - iStat += EqnTest( _T("-f1of1(1000){m}"), -1, true); - iStat += EqnTest( _T("-f1of1(-1000){m}"), 1, true); - iStat += EqnTest( _T("f4of4(0,0,0,1000){m}"), 1, true); - iStat += EqnTest( _T("2+(a*1000){m}"), 3, true); + iStat += EqnTest( "3{m}+5", 5.003, true); + iStat += EqnTest( "1000{m}", 1, true); + iStat += EqnTest( "1000 {m}", 1, true); + iStat += EqnTest( "(a){m}", 1e-3, true); + iStat += EqnTest( "a{m}", 1e-3, true); + iStat += EqnTest( "a {m}", 1e-3, true); + iStat += EqnTest( "-(a){m}", -1e-3, true); + iStat += EqnTest( "-2{m}", -2e-3, true); + iStat += EqnTest( "-2 {m}", -2e-3, true); + iStat += EqnTest( "f1of1(1000){m}", 1, true); + iStat += EqnTest( "-f1of1(1000){m}", -1, true); + iStat += EqnTest( "-f1of1(-1000){m}", 1, true); + iStat += EqnTest( "f4of4(0,0,0,1000){m}", 1, true); + iStat += EqnTest( "2+(a*1000){m}", 3, true); // can postfix operators "m" und "meg" be told apart properly? - iStat += EqnTest( _T("2*3000meg+2"), 2*3e9+2, true); + iStat += EqnTest( "2*3000meg+2", 2*3e9+2, true); // some incorrect results - iStat += EqnTest( _T("1000{m}"), 0.1, false); - iStat += EqnTest( _T("(a){m}"), 2, false); + iStat += EqnTest( "1000{m}", 0.1, false); + iStat += EqnTest( "(a){m}", 2, false); // failure due to syntax checking - iStat += ThrowTest(_T("0x"), ecUNASSIGNABLE_TOKEN); // incomplete hex definition - iStat += ThrowTest(_T("3+"), ecUNEXPECTED_EOF); - iStat += ThrowTest( _T("4 + {m}"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("{m}4"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("sin({m})"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("{m} {m}"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("{m}(8)"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("4,{m}"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("-{m}"), ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( _T("2(-{m})"), ecUNEXPECTED_PARENS); - iStat += ThrowTest( _T("2({m})"), ecUNEXPECTED_PARENS); + iStat += ThrowTest("0x", ecUNASSIGNABLE_TOKEN); // incomplete hex definition + iStat += ThrowTest("3+", ecUNEXPECTED_EOF); + iStat += ThrowTest( "4 + {m}", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "{m}4", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "sin({m})", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "{m} {m}", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "{m}(8)", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "4,{m}", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "-{m}", ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "2(-{m})", ecUNEXPECTED_PARENS); + iStat += ThrowTest( "2({m})", ecUNEXPECTED_PARENS); - iStat += ThrowTest( _T("multi*1.0"), ecUNASSIGNABLE_TOKEN); + iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN); if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -777,78 +777,78 @@ namespace qmu int QmuParserTester::TestExpression() { int iStat = 0; - mu::console() << _T("testing expression samples..."); + mu::console() << "testing expression samples..."; - value_type b = 2; + qreal b = 2; // Optimization - iStat += EqnTest( _T("2*b*5"), 20, true); - iStat += EqnTest( _T("2*b*5 + 4*b"), 28, true); - iStat += EqnTest( _T("2*a/3"), 2.0/3.0, true); + iStat += EqnTest( "2*b*5", 20, true); + iStat += EqnTest( "2*b*5 + 4*b", 28, true); + iStat += EqnTest( "2*a/3", 2.0/3.0, true); // Addition auf cmVARMUL - iStat += EqnTest( _T("3+b"), b+3, true); - iStat += EqnTest( _T("b+3"), b+3, true); - iStat += EqnTest( _T("b*3+2"), b*3+2, true); - iStat += EqnTest( _T("3*b+2"), b*3+2, true); - iStat += EqnTest( _T("2+b*3"), b*3+2, true); - iStat += EqnTest( _T("2+3*b"), b*3+2, true); - iStat += EqnTest( _T("b+3*b"), b+3*b, true); - iStat += EqnTest( _T("3*b+b"), b+3*b, true); + iStat += EqnTest( "3+b", b+3, true); + iStat += EqnTest( "b+3", b+3, true); + iStat += EqnTest( "b*3+2", b*3+2, true); + iStat += EqnTest( "3*b+2", b*3+2, true); + iStat += EqnTest( "2+b*3", b*3+2, true); + iStat += EqnTest( "2+3*b", b*3+2, true); + iStat += EqnTest( "b+3*b", b+3*b, true); + iStat += EqnTest( "3*b+b", b+3*b, true); - iStat += EqnTest( _T("2+b*3+b"), 2+b*3+b, true); - iStat += EqnTest( _T("b+2+b*3"), b+2+b*3, true); + iStat += EqnTest( "2+b*3+b", 2+b*3+b, true); + iStat += EqnTest( "b+2+b*3", b+2+b*3, true); - iStat += EqnTest( _T("(2*b+1)*4"), (2*b+1)*4, true); - iStat += EqnTest( _T("4*(2*b+1)"), (2*b+1)*4, true); + iStat += EqnTest( "(2*b+1)*4", (2*b+1)*4, true); + iStat += EqnTest( "4*(2*b+1)", (2*b+1)*4, true); // operator precedencs - iStat += EqnTest( _T("1+2-3*4/5^6"), 2.99923, true); - iStat += EqnTest( _T("1^2/3*4-5+6"), 2.33333333, true); - iStat += EqnTest( _T("1+2*3"), 7, true); - iStat += EqnTest( _T("1+2*3"), 7, true); - iStat += EqnTest( _T("(1+2)*3"), 9, true); - iStat += EqnTest( _T("(1+2)*(-3)"), -9, true); - iStat += EqnTest( _T("2/4"), 0.5, true); + iStat += EqnTest( "1+2-3*4/5^6", 2.99923, true); + iStat += EqnTest( "1^2/3*4-5+6", 2.33333333, true); + iStat += EqnTest( "1+2*3", 7, true); + iStat += EqnTest( "1+2*3", 7, true); + iStat += EqnTest( "(1+2)*3", 9, true); + iStat += EqnTest( "(1+2)*(-3)", -9, true); + iStat += EqnTest( "2/4", 0.5, true); - iStat += EqnTest( _T("exp(ln(7))"), 7, true); - iStat += EqnTest( _T("e^ln(7)"), 7, true); - iStat += EqnTest( _T("e^(ln(7))"), 7, true); - iStat += EqnTest( _T("(e^(ln(7)))"), 7, true); - iStat += EqnTest( _T("1-(e^(ln(7)))"), -6, true); - iStat += EqnTest( _T("2*(e^(ln(7)))"), 14, true); - iStat += EqnTest( _T("10^log(5)"), 5, true); - iStat += EqnTest( _T("10^log10(5)"), 5, true); - iStat += EqnTest( _T("2^log2(4)"), 4, true); - iStat += EqnTest( _T("-(sin(0)+1)"), -1, true); - iStat += EqnTest( _T("-(2^1.1)"), -2.14354692, true); + iStat += EqnTest( "exp(ln(7))", 7, true); + iStat += EqnTest( "e^ln(7)", 7, true); + iStat += EqnTest( "e^(ln(7))", 7, true); + iStat += EqnTest( "(e^(ln(7)))", 7, true); + iStat += EqnTest( "1-(e^(ln(7)))", -6, true); + iStat += EqnTest( "2*(e^(ln(7)))", 14, true); + iStat += EqnTest( "10^log(5)", 5, true); + iStat += EqnTest( "10^log10(5)", 5, true); + iStat += EqnTest( "2^log2(4)", 4, true); + iStat += EqnTest( "-(sin(0)+1)", -1, true); + iStat += EqnTest( "-(2^1.1)", -2.14354692, true); - iStat += EqnTest( _T("(cos(2.41)/b)"), -0.372056, true); - iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(a+b)))))))"), 2160, true); - iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"), 15120, true); - iStat += EqnTest( _T("(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))"), 0.00377999, true); + iStat += EqnTest( "(cos(2.41)/b)", -0.372056, true); + iStat += EqnTest( "(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160, true); + iStat += EqnTest( "(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120, true); + iStat += EqnTest( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))", 0.00377999, true); // long formula (Reference: Matlab) iStat += EqnTest( - _T("(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))") - _T("/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/") - _T("((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-") - _T("e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6") - _T("+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e") - _T("*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), -12.23016549, true); + "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))" + "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/" + "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-" + "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6" + "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e" + "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549, true); // long formula (Reference: Matlab) iStat += EqnTest( - _T("(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e") - _T(")+a)))*2.77)"), -2.16995656, true); + "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e" + ")+a)))*2.77)", -2.16995656, true); // long formula (Reference: Matlab) - iStat += EqnTest( _T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926, true); + iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true); if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -859,104 +859,104 @@ namespace qmu int QmuParserTester::TestIfThenElse() { int iStat = 0; - mu::console() << _T("testing if-then-else operator..."); + mu::console() << "testing if-then-else operator..."; // Test error detection - iStat += ThrowTest(_T(":3"), ecUNEXPECTED_CONDITIONAL); - iStat += ThrowTest(_T("? 1 : 2"), ecUNEXPECTED_CONDITIONAL); - iStat += ThrowTest(_T("(ab) ? 10 : 11"), 11, true); - iStat += EqnTest(_T("(ab) ? c : d"), -2, true); + iStat += EqnTest("1 ? 128 : 255", 128, true); + iStat += EqnTest("1<2 ? 128 : 255", 128, true); + iStat += EqnTest("ab) ? 10 : 11", 11, true); + iStat += EqnTest("(ab) ? c : d", -2, true); - iStat += EqnTest(_T("(a>b) ? 1 : 0"), 0, true); - iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : 2"), 2, true); - iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)"), 2, true); - iStat += EqnTest(_T("((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)"), 1, true); + iStat += EqnTest("(a>b) ? 1 : 0", 0, true); + iStat += EqnTest("((a>b) ? 1 : 0) ? 1 : 2", 2, true); + iStat += EqnTest("((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)", 2, true); + iStat += EqnTest("((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)", 1, true); - iStat += EqnTest(_T("sum((a>b) ? 1 : 2)"), 2, true); - iStat += EqnTest(_T("sum((1) ? 1 : 2)"), 1, true); - iStat += EqnTest(_T("sum((a>b) ? 1 : 2, 100)"), 102, true); - iStat += EqnTest(_T("sum((1) ? 1 : 2, 100)"), 101, true); - iStat += EqnTest(_T("sum(3, (a>b) ? 3 : 10)"), 13, true); - iStat += EqnTest(_T("sum(3, (ab) ? 3 : 10)"), 130, true); - iStat += EqnTest(_T("10*sum(3, (ab) ? 3 : 10)*10"), 130, true); - iStat += EqnTest(_T("sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? 1 : 2)", 2, true); + iStat += EqnTest("sum((1) ? 1 : 2)", 1, true); + iStat += EqnTest("sum((a>b) ? 1 : 2, 100)", 102, true); + iStat += EqnTest("sum((1) ? 1 : 2, 100)", 101, true); + iStat += EqnTest("sum(3, (a>b) ? 3 : 10)", 13, true); + iStat += EqnTest("sum(3, (ab) ? 3 : 10)", 130, true); + iStat += EqnTest("10*sum(3, (ab) ? 3 : 10)*10", 130, true); + iStat += EqnTest("sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab)&&(a2)&&(1<2) ? 128 : 255"), 255, true); - iStat += EqnTest(_T("((1<2)&&(1<2)) ? 128 : 255"), 128, true); - iStat += EqnTest(_T("((1>2)&&(1<2)) ? 128 : 255"), 255, true); - iStat += EqnTest(_T("((ab)&&(ab)&&(a2)&&(1<2) ? 128 : 255", 255, true); + iStat += EqnTest("((1<2)&&(1<2)) ? 128 : 255", 128, true); + iStat += EqnTest("((1>2)&&(1<2)) ? 128 : 255", 255, true); + iStat += EqnTest("((ab)&&(a0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255, true); - iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255, true); - iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128, true); - iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128, true); - iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32, true); - iStat += EqnTest(_T("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64, true); - iStat += EqnTest(_T("1>0 ? 50 : 1>0 ? 128 : 255"), 50, true); - iStat += EqnTest(_T("1>0 ? 50 : (1>0 ? 128 : 255)"), 50, true); - iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 50"), 128, true); - iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32, true); - iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32, true); - iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16"), 255, true); - iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255, true); - iStat += EqnTest(_T("1 ? 0 ? 128 : 255 : 1 ? 32 : 64"), 255, true); + iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 255, true); + iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)", 255, true); + iStat += EqnTest("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 128, true); + iStat += EqnTest("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)", 128, true); + iStat += EqnTest("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 32, true); + iStat += EqnTest("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 64, true); + iStat += EqnTest("1>0 ? 50 : 1>0 ? 128 : 255", 50, true); + iStat += EqnTest("1>0 ? 50 : (1>0 ? 128 : 255)", 50, true); + iStat += EqnTest("1>0 ? 1>0 ? 128 : 255 : 50", 128, true); + iStat += EqnTest("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16", 32, true); + iStat += EqnTest("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)", 32, true); + iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16", 255, true); + iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)", 255, true); + iStat += EqnTest("1 ? 0 ? 128 : 255 : 1 ? 32 : 64", 255, true); // assignment operators - iStat += EqnTest(_T("a= 0 ? 128 : 255, a"), 255, true); - iStat += EqnTest(_T("a=((a>b)&&(ab)&&(a // this is now legal, for reference see: // https://sourceforge.net/forum/message.php?msg_id=7411373 - // iStat += ThrowTest( _T("sin=9"), ecUNEXPECTED_OPERATOR); + // iStat += ThrowTest( "sin=9"), ecUNEXPECTED_OPERATOR); // - iStat += ThrowTest( _T("(8)=5"), ecUNEXPECTED_OPERATOR); - iStat += ThrowTest( _T("(a)=5"), ecUNEXPECTED_OPERATOR); - iStat += ThrowTest( _T("a=\"tttt\""), ecOPRT_TYPE_CONFLICT); + iStat += ThrowTest( "(8)=5", ecUNEXPECTED_OPERATOR); + iStat += ThrowTest( "(a)=5", ecUNEXPECTED_OPERATOR); + iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT); if (iStat==0) - mu::console() << _T("passed") << endl; + mu::console() << "passed" << endl; else - mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl; + mu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -1109,19 +1109,19 @@ namespace qmu try { - value_type fVal[] = {1,1,1}; + qreal fVal[] = {1,1,1}; QmuParser p; - p.DefineVar( _T("a"), &fVal[0]); - p.DefineVar( _T("b"), &fVal[1]); - p.DefineVar( _T("c"), &fVal[2]); - p.DefinePostfixOprt( _T("{m}"), Milli); - p.DefinePostfixOprt( _T("m"), Milli); - p.DefineFun( _T("ping"), Ping); - p.DefineFun( _T("valueof"), ValueOf); - p.DefineFun( _T("strfun1"), StrFun1); - p.DefineFun( _T("strfun2"), StrFun2); - p.DefineFun( _T("strfun3"), StrFun3); + p.DefineVar( "a", &fVal[0]); + p.DefineVar( "b", &fVal[1]); + p.DefineVar( "c", &fVal[2]); + p.DefinePostfixOprt( "{m}", Milli); + p.DefinePostfixOprt( "m", Milli); + p.DefineFun( "ping", Ping); + p.DefineFun( "valueof", ValueOf); + p.DefineFun( "strfun1", StrFun1); + p.DefineFun( "strfun2", StrFun2); + p.DefineFun( "strfun3", StrFun3); p.SetExpr(a_str); p.Eval(); } @@ -1130,10 +1130,10 @@ namespace qmu // output the formula in case of an failed test if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) { - mu::console() << _T("\n ") - << _T("Expression: ") << a_str - << _T(" Code:") << e.GetCode() << _T("(") << e.GetMsg() << _T(")") - << _T(" Expected:") << a_iErrc; + mu::console() << "\n " + << "Expression: " << a_str + << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" + << " Expected:" << a_iErrc; } return (a_iErrc==e.GetCode()) ? 0 : 1; @@ -1143,9 +1143,9 @@ namespace qmu bool bRet((a_bFail==false) ? 0 : 1); if (bRet==1) { - mu::console() << _T("\n ") - << _T("Expression: ") << a_str - << _T(" did evaluate; Expected error:") << a_iErrc; + mu::console() << "\n " + << "Expression: " << a_str + << " did evaluate; Expected error:" << a_iErrc; } return bRet; @@ -1163,15 +1163,15 @@ namespace qmu double a_fRes2) { QmuParserTester::c_iCount++; - value_type fVal[2] = {-999, -999 }; // should be equalinitially + qreal fVal[2] = {-999, -999 }; // should be equalinitially try { QmuParser p; // variable - value_type var = 0; - p.DefineVar( _T("a"), &var); + qreal var = 0; + p.DefineVar( "a", &var); p.SetExpr(a_str); var = a_fVar1; @@ -1188,17 +1188,17 @@ namespace qmu } catch(QmuParser::exception_type &e) { - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")"); + mu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; return 1; } catch(std::exception &e) { - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")"); + mu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)"); + mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1214,7 +1214,7 @@ namespace qmu { QmuParserTester::c_iCount++; int iRet(0); - value_type fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different + qreal fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different try { @@ -1227,70 +1227,70 @@ namespace qmu p1.reset(new qmu::QmuParser()); // Add constants - p1->DefineConst( _T("pi"), (value_type)PARSER_CONST_PI); - p1->DefineConst( _T("e"), (value_type)PARSER_CONST_E); - p1->DefineConst( _T("const"), 1); - p1->DefineConst( _T("const1"), 2); - p1->DefineConst( _T("const2"), 3); + p1->DefineConst( "pi", (qreal)PARSER_CONST_PI); + p1->DefineConst( "e", (qreal)PARSER_CONST_E); + p1->DefineConst( "const", 1); + p1->DefineConst( "const1", 2); + p1->DefineConst( "const2", 3); // variables - value_type vVarVal[] = { 1, 2, 3, -2}; - p1->DefineVar( _T("a"), &vVarVal[0]); - p1->DefineVar( _T("aa"), &vVarVal[1]); - p1->DefineVar( _T("b"), &vVarVal[1]); - p1->DefineVar( _T("c"), &vVarVal[2]); - p1->DefineVar( _T("d"), &vVarVal[3]); + qreal vVarVal[] = { 1, 2, 3, -2}; + p1->DefineVar( "a", &vVarVal[0]); + p1->DefineVar( "aa", &vVarVal[1]); + p1->DefineVar( "b", &vVarVal[1]); + p1->DefineVar( "c", &vVarVal[2]); + p1->DefineVar( "d", &vVarVal[3]); // custom value ident functions p1->AddValIdent(&QmuParserTester::IsHexVal); // functions - p1->DefineFun( _T("ping"), Ping); - p1->DefineFun( _T("f1of1"), f1of1); // one parameter - p1->DefineFun( _T("f1of2"), f1of2); // two parameter - p1->DefineFun( _T("f2of2"), f2of2); - p1->DefineFun( _T("f1of3"), f1of3); // three parameter - p1->DefineFun( _T("f2of3"), f2of3); - p1->DefineFun( _T("f3of3"), f3of3); - p1->DefineFun( _T("f1of4"), f1of4); // four parameter - p1->DefineFun( _T("f2of4"), f2of4); - p1->DefineFun( _T("f3of4"), f3of4); - p1->DefineFun( _T("f4of4"), f4of4); - p1->DefineFun( _T("f1of5"), f1of5); // five parameter - p1->DefineFun( _T("f2of5"), f2of5); - p1->DefineFun( _T("f3of5"), f3of5); - p1->DefineFun( _T("f4of5"), f4of5); - p1->DefineFun( _T("f5of5"), f5of5); + p1->DefineFun( "ping", Ping); + p1->DefineFun( "f1of1", f1of1); // one parameter + p1->DefineFun( "f1of2", f1of2); // two parameter + p1->DefineFun( "f2of2", f2of2); + p1->DefineFun( "f1of3", f1of3); // three parameter + p1->DefineFun( "f2of3", f2of3); + p1->DefineFun( "f3of3", f3of3); + p1->DefineFun( "f1of4", f1of4); // four parameter + p1->DefineFun( "f2of4", f2of4); + p1->DefineFun( "f3of4", f3of4); + p1->DefineFun( "f4of4", f4of4); + p1->DefineFun( "f1of5", f1of5); // five parameter + p1->DefineFun( "f2of5", f2of5); + p1->DefineFun( "f3of5", f3of5); + p1->DefineFun( "f4of5", f4of5); + p1->DefineFun( "f5of5", f5of5); // binary operators - p1->DefineOprt( _T("add"), add, 0); - p1->DefineOprt( _T("++"), add, 0); - p1->DefineOprt( _T("&"), land, prLAND); + p1->DefineOprt( "add", add, 0); + p1->DefineOprt( "++", add, 0); + p1->DefineOprt( "&", land, prLAND); // sample functions - p1->DefineFun( _T("min"), Min); - p1->DefineFun( _T("max"), Max); - p1->DefineFun( _T("sum"), Sum); - p1->DefineFun( _T("valueof"), ValueOf); - p1->DefineFun( _T("atof"), StrToFloat); - p1->DefineFun( _T("strfun1"), StrFun1); - p1->DefineFun( _T("strfun2"), StrFun2); - p1->DefineFun( _T("strfun3"), StrFun3); - p1->DefineFun( _T("lastArg"), LastArg); - p1->DefineFun( _T("firstArg"), FirstArg); - p1->DefineFun( _T("order"), FirstArg); + p1->DefineFun( "min", Min); + p1->DefineFun( "max", Max); + p1->DefineFun( "sum", Sum); + p1->DefineFun( "valueof", ValueOf); + p1->DefineFun( "atof", StrToFloat); + p1->DefineFun( "strfun1", StrFun1); + p1->DefineFun( "strfun2", StrFun2); + p1->DefineFun( "strfun3", StrFun3); + p1->DefineFun( "lastArg", LastArg); + p1->DefineFun( "firstArg", FirstArg); + p1->DefineFun( "order", FirstArg); // infix / postfix operator // Note: Identifiers used here do not have any meaning // they are mere placeholders to test certain features. - p1->DefineInfixOprt( _T("$"), sign, prPOW+1); // sign with high priority - p1->DefineInfixOprt( _T("~"), plus2); // high priority - p1->DefineInfixOprt( _T("~~"), plus2); - p1->DefinePostfixOprt( _T("{m}"), Milli); - p1->DefinePostfixOprt( _T("{M}"), Mega); - p1->DefinePostfixOprt( _T("m"), Milli); - p1->DefinePostfixOprt( _T("meg"), Mega); - p1->DefinePostfixOprt( _T("#"), times3); - p1->DefinePostfixOprt( _T("'"), sqr); + p1->DefineInfixOprt( "$", sign, prPOW+1); // sign with high priority + p1->DefineInfixOprt( "~", plus2); // high priority + p1->DefineInfixOprt( "~~", plus2); + p1->DefinePostfixOprt( "{m}", Milli); + p1->DefinePostfixOprt( "{M}", Mega); + p1->DefinePostfixOprt( "m", Milli); + p1->DefinePostfixOprt( "meg", Mega); + p1->DefinePostfixOprt( "#", times3); + p1->DefinePostfixOprt( "'", sqr); p1->SetExpr(a_str); // Test bytecode integrity @@ -1298,7 +1298,7 @@ namespace qmu fVal[0] = p1->Eval(); // result from stringparsing fVal[1] = p1->Eval(); // result from bytecode if (fVal[0]!=fVal[1]) - throw QmuParser::exception_type( _T("Bytecode / string parsing mismatch.") ); + throw QmuParser::exception_type( "Bytecode / string parsing mismatch." ); // Test copy and assignement operators try @@ -1324,25 +1324,25 @@ namespace qmu // Test Eval function for multiple return values // use p2 since it has the optimizer enabled! int nNum; - value_type *v = p2.Eval(nNum); + qreal *v = p2.Eval(nNum); fVal[4] = v[nNum-1]; } catch(std::exception &e) { - mu::console() << _T("\n ") << e.what() << _T("\n"); + mu::console() << "\n " << e.what() << "\n"; } // limited floating point accuracy requires the following test bool bCloseEnough(true); - for (unsigned i=0; i::has_infinity) - bCloseEnough &= (fabs(fVal[i]) != numeric_limits::infinity()); + if (numeric_limits::has_infinity) + bCloseEnough &= (fabs(fVal[i]) != numeric_limits::infinity()); } iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1; @@ -1350,13 +1350,13 @@ namespace qmu if (iRet==1) { - mu::console() << _T("\n fail: ") << a_str.c_str() - << _T(" (incorrect result; expected: ") << a_fRes - << _T(" ;calculated: ") << fVal[0] << _T(",") - << fVal[1] << _T(",") - << fVal[2] << _T(",") - << fVal[3] << _T(",") - << fVal[4] << _T(")."); + mu::console() << "\n fail: " << a_str.c_str() + << " (incorrect result; expected: " << a_fRes + << " ;calculated: " << fVal[0] << "," + << fVal[1] << "," + << fVal[2] << "," + << fVal[3] << "," + << fVal[4] << ")."; } } catch(QmuParser::exception_type &e) @@ -1364,20 +1364,20 @@ namespace qmu if (a_fPass) { if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (copy construction)"); + mu::console() << "\n fail: " << a_str.c_str() << " (copy construction)"; else - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")"); + mu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; return 1; } } catch(std::exception &e) { - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")"); + mu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)"); + mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1389,46 +1389,46 @@ namespace qmu { QmuParserTester::c_iCount++; - value_type vVarVal[] = {1, 2, 3}; // variable values - value_type fVal[2] = {-99, -999}; // results: initially should be different + qreal vVarVal[] = {1, 2, 3}; // variable values + qreal fVal[2] = {-99, -999}; // results: initially should be different int iRet(0); try { QmuParserInt p; - p.DefineConst( _T("const1"), 1); - p.DefineConst( _T("const2"), 2); - p.DefineVar( _T("a"), &vVarVal[0]); - p.DefineVar( _T("b"), &vVarVal[1]); - p.DefineVar( _T("c"), &vVarVal[2]); + p.DefineConst( "const1", 1); + p.DefineConst( "const2", 2); + p.DefineVar( "a", &vVarVal[0]); + p.DefineVar( "b", &vVarVal[1]); + p.DefineVar( "c", &vVarVal[2]); p.SetExpr(a_str); fVal[0] = p.Eval(); // result from stringparsing fVal[1] = p.Eval(); // result from bytecode if (fVal[0]!=fVal[1]) - throw QmuParser::exception_type( _T("Bytecode corrupt.") ); + throw QmuParser::exception_type( "Bytecode corrupt." ); iRet = ( (a_fRes==fVal[0] && a_fPass) || (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1; if (iRet==1) { - mu::console() << _T("\n fail: ") << a_str.c_str() - << _T(" (incorrect result; expected: ") << a_fRes - << _T(" ;calculated: ") << fVal[0]<< _T(")."); + mu::console() << "\n fail: " << a_str.c_str() + << " (incorrect result; expected: " << a_fRes + << " ;calculated: " << fVal[0]<< ")."; } } catch(QmuParser::exception_type &e) { if (a_fPass) { - mu::console() << _T("\n fail: ") << e.GetExpr() << _T(" : ") << e.GetMsg(); + mu::console() << "\n fail: " << e.GetExpr() << " : " << e.GetMsg(); iRet = 1; } } catch(...) { - mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)"); + mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; iRet = 1; // exceptions other than ParserException are not allowed } @@ -1439,7 +1439,7 @@ namespace qmu /** \brief Internal error in test class Test is going to be aborted. */ void QmuParserTester::Abort() const { - mu::console() << _T("Test failed (internal error in test class)") << endl; + mu::console() << "Test failed (internal error in test class)" << endl; while (!getchar()); exit(-1); } diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index d6407060c..8e4cc809a 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -49,118 +49,118 @@ namespace qmu static int c_iCount; // Multiarg callbacks - static value_type f1of1(value_type v) { return v;}; + static qreal f1of1(qreal v) { return v;}; - static value_type f1of2(value_type v, value_type ) {return v;}; - static value_type f2of2(value_type , value_type v) {return v;}; + static qreal f1of2(qreal v, qreal ) {return v;}; + static qreal f2of2(qreal , qreal v) {return v;}; - static value_type f1of3(value_type v, value_type , value_type ) {return v;}; - static value_type f2of3(value_type , value_type v, value_type ) {return v;}; - static value_type f3of3(value_type , value_type , value_type v) {return v;}; + static qreal f1of3(qreal v, qreal , qreal ) {return v;}; + static qreal f2of3(qreal , qreal v, qreal ) {return v;}; + static qreal f3of3(qreal , qreal , qreal v) {return v;}; - static value_type f1of4(value_type v, value_type, value_type , value_type ) {return v;} - static value_type f2of4(value_type , value_type v, value_type , value_type ) {return v;} - static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;} - static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;} + static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;} + static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;} + static qreal f3of4(qreal , qreal, qreal v, qreal ) {return v;} + static qreal f4of4(qreal , qreal, qreal , qreal v) {return v;} - static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; } - static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; } - static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; } - static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; } - static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; } + static qreal f1of5(qreal v, qreal, qreal , qreal , qreal ) { return v; } + static qreal f2of5(qreal , qreal v, qreal , qreal , qreal ) { return v; } + static qreal f3of5(qreal , qreal, qreal v, qreal , qreal ) { return v; } + static qreal f4of5(qreal , qreal, qreal , qreal v, qreal ) { return v; } + static qreal f5of5(qreal , qreal, qreal , qreal , qreal v) { return v; } - static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1a_fVal2) ? a_fVal1 : a_fVal2; } + static qreal Min(qreal a_fVal1, qreal a_fVal2) { return (a_fVal1a_fVal2) ? a_fVal1 : a_fVal2; } - static value_type plus2(value_type v1) { return v1+2; } - static value_type times3(value_type v1) { return v1*3; } - static value_type sqr(value_type v1) { return v1*v1; } - static value_type sign(value_type v) { return -v; } - static value_type add(value_type v1, value_type v2) { return v1+v2; } - static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; } + static qreal plus2(qreal v1) { return v1+2; } + static qreal times3(qreal v1) { return v1*3; } + static qreal sqr(qreal v1) { return v1*v1; } + static qreal sign(qreal v) { return -v; } + static qreal add(qreal v1, qreal v2) { return v1+v2; } + static qreal land(qreal v1, qreal v2) { return (int)v1 & (int)v2; } - static value_type FirstArg(const value_type* a_afArg, int a_iArgc) + static qreal FirstArg(const qreal* a_afArg, int a_iArgc) { if (!a_iArgc) - throw qmu::QmuParser::exception_type( _T("too few arguments for function FirstArg.") ); + throw qmu::QmuParser::exception_type( "too few arguments for function FirstArg." ); return a_afArg[0]; } - static value_type LastArg(const value_type* a_afArg, int a_iArgc) + static qreal LastArg(const qreal* a_afArg, int a_iArgc) { if (!a_iArgc) - throw qmu::QmuParser::exception_type( _T("too few arguments for function LastArg.") ); + throw qmu::QmuParser::exception_type( "too few arguments for function LastArg." ); return a_afArg[a_iArgc-1]; } - static value_type Sum(const value_type* a_afArg, int a_iArgc) + static qreal Sum(const qreal* a_afArg, int a_iArgc) { if (!a_iArgc) - throw qmu::QmuParser::exception_type( _T("too few arguments for function sum.") ); + throw qmu::QmuParser::exception_type( "too few arguments for function sum." ); - value_type fRes=0; + qreal fRes=0; for (int i=0; i> val; - return (value_type)val; + return (qreal)val; } - static value_type StrFun2(const char_type* v1, value_type v2) + static qreal StrFun2(const char_type* v1, qreal v2) { int val(0); stringstream_type(v1) >> val; - return (value_type)(val + v2); + return (qreal)(val + v2); } - static value_type StrFun3(const char_type* v1, value_type v2, value_type v3) + static qreal StrFun3(const char_type* v1, qreal v2, qreal v3) { int val(0); stringstream_type(v1) >> val; return val + v2 + v3; } - static value_type StrToFloat(const char_type* a_szMsg) + static qreal StrToFloat(const char_type* a_szMsg) { - value_type val(0); + qreal val(0); stringstream_type(a_szMsg) >> val; return val; } // postfix operator callback - static value_type Mega(value_type a_fVal) { return a_fVal * (value_type)1e6; } - static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; } - static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; } + static qreal Mega(qreal a_fVal) { return a_fVal * (qreal)1e6; } + static qreal Micro(qreal a_fVal) { return a_fVal * (qreal)1e-6; } + static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; } // Custom value recognition - static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal); + static int IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal); int TestNames(); int TestSyntax(); diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 81a23ed7f..a475abe9f 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -65,7 +65,7 @@ namespace qmu int m_iIdx; ///< An otional index to an external buffer storing the token data TString m_strTok; ///< Token string TString m_strVal; ///< Value for string variables - value_type m_fVal; ///< the value + qreal m_fVal; ///< the value std::auto_ptr m_pCallback; public: diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 81d7f4f20..24a439120 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -514,7 +514,7 @@ namespace qmu Error(ecUNEXPECTED_EOF, m_iPos); if (m_iBrackets>0) - Error(ecMISSING_PARENS, m_iPos, _T(")")); + Error(ecMISSING_PARENS, m_iPos, ")"); m_iSynFlags = 0; a_Tok.Set(cmEND); @@ -722,7 +722,7 @@ namespace qmu assert(m_pParser); string_type strTok; - value_type fVal(0); + qreal fVal(0); int iEnd(0); // 2.) Check for user defined constant @@ -855,7 +855,7 @@ namespace qmu // If a factory is available implicitely create new variables if (m_pFactory) { - value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData); + qreal *fVar = m_pFactory(strTok.c_str(), m_pFactoryData); a_Tok.SetVar(fVar, strTok ); // Do not use m_pParser->DefineVar( strTok, fVar ); @@ -869,7 +869,7 @@ namespace qmu } else { - a_Tok.SetVar((value_type*)&m_fZero, strTok); + a_Tok.SetVar((qreal*)&m_fZero, strTok); m_UsedVar[strTok] = 0; // Add variable to used-var-list } @@ -897,15 +897,15 @@ namespace qmu std::size_t iEnd(0), iSkip(0); // parser over escaped '\"' end replace them with '"' - for(iEnd=(int)strBuf.find( _T("\"") ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( _T("\""), iEnd)) + for(iEnd=(int)strBuf.find( "\"" ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( "\"", iEnd)) { if (strBuf[iEnd-1]!='\\') break; - strBuf.replace(iEnd-1, 2, _T("\"") ); + strBuf.replace(iEnd-1, 2, "\"" ); iSkip++; } if (iEnd==string_type::npos) - Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") ); + Error(ecUNTERMINATED_STRING, m_iPos, "\"" ); string_type strTok(strBuf.begin(), strBuf.begin()+iEnd); diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 2475b79f4..7c22fcb53 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -52,7 +52,7 @@ namespace qmu { private: - typedef QmuParserToken token_type; + typedef QmuParserToken token_type; public: @@ -146,7 +146,7 @@ namespace qmu void *m_pFactoryData; std::list m_vIdentFun; ///< Value token identification function varmap_type m_UsedVar; - value_type m_fZero; ///< Dummy value of zero, referenced by undefined variables + qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables int m_iBrackets; token_type m_lastTok; char_type m_cArgSep; ///< The character used for separating function arguments From 2f97def4bf8e750a5c6c342120ef677041b854a5 Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 25 Apr 2014 18:10:56 +0300 Subject: [PATCH 04/26] Use Q_ASSERT marcros instead MUP_ASSERT and MUP_FAIL. --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.cpp | 22 ++++++++++----------- src/libs/qmuparser/qmuparserdef.h | 29 ---------------------------- 2 files changed, 11 insertions(+), 40 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 244e79fb2..40229e420 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -873,13 +873,13 @@ namespace qmu while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) { token_type opElse = a_stOpt.pop(); - MUP_ASSERT(a_stOpt.size()>0); + Q_ASSERT(a_stOpt.size()>0); // Take the value associated with the else branch from the value stack token_type vVal2 = a_stVal.pop(); - MUP_ASSERT(a_stOpt.size()>0); - MUP_ASSERT(a_stVal.size()>=2); + Q_ASSERT(a_stOpt.size()>0); + Q_ASSERT(a_stVal.size()>=2); // it then else is a ternary operator Pop all three values from the value s // tack and just return the right value @@ -889,8 +889,8 @@ namespace qmu a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2); token_type opIf = a_stOpt.pop(); - MUP_ASSERT(opElse.GetCode()==cmELSE); - MUP_ASSERT(opIf.GetCode()==cmIF); + Q_ASSERT(opElse.GetCode()==cmELSE); + Q_ASSERT(opIf.GetCode()==cmIF); m_vRPN.AddIfElse(cmENDIF); } // while pending if-else-clause found @@ -910,7 +910,7 @@ namespace qmu } else { - MUP_ASSERT(a_stVal.size()>=2); + Q_ASSERT(a_stVal.size()>=2); token_type valTok1 = a_stVal.pop(), valTok2 = a_stVal.pop(), optTok = a_stOpt.pop(), @@ -1044,7 +1044,7 @@ namespace qmu //case cmBO: // unused, listed for compiler optimization purposes //case cmBC: - // MUP_FAIL(INVALID_CODE_IN_BYTECODE); + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; case cmIF: @@ -1060,7 +1060,7 @@ namespace qmu continue; //case cmARG_SEP: - // MUP_FAIL(INVALID_CODE_IN_BYTECODE); + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; // value and variable tokens @@ -1118,7 +1118,7 @@ namespace qmu // The index of the string argument in the string table int iIdxStack = pTok->Fun.idx; - MUP_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); + Q_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); switch(pTok->Fun.argc) // switch according to argument count { @@ -1158,7 +1158,7 @@ namespace qmu //case cmOPRT_BIN: //case cmOPRT_POSTFIX: //case cmOPRT_INFIX: - // MUP_FAIL(INVALID_CODE_IN_BYTECODE); + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; //case cmEND: @@ -1392,7 +1392,7 @@ namespace qmu Error(ecMISSING_ELSE_CLAUSE); // get the last value (= final result) from the stack - MUP_ASSERT(stArgCount.size()==1); + Q_ASSERT(stArgCount.size()==1); m_nFinalResultIdx = stArgCount.top(); if (m_nFinalResultIdx==0) Error(ecINTERNAL_ERROR, 9); diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index b5dc3e89c..2ad34d556 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -58,35 +58,6 @@ #define MUP_STRING_TYPE std::string #endif -#if defined(_DEBUG) - /** \brief Debug macro to force an abortion of the programm with a certain message. - */ - #define MUP_FAIL(MSG) \ - { \ - bool MSG=false; \ - assert(MSG); \ - } - - /** \brief An assertion that does not kill the program. - - This macro is neutralised in UNICODE builds. It's - too difficult to translate. - */ - #define MUP_ASSERT(COND) \ - if (!(COND)) \ - { \ - stringstream_type ss; \ - ss << "Assertion \"" #COND "\" failed: ") \ - << __FILE__ << " line " \ - << __LINE__ << "."; \ - throw ParserError( ss.str() ); \ - } -#else - #define MUP_FAIL(MSG) - #define MUP_ASSERT(COND) -#endif - - namespace qmu { #if defined(_UNICODE) From 59c7405b88a8a128b6a14e4b045bfed12fa377a6 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 09:01:41 +0300 Subject: [PATCH 05/26] QStack instead QmuParserStack. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.pro | 1 - src/libs/qmuparser/qmuparserbase.cpp | 49 +++++---- src/libs/qmuparser/qmuparserbase.h | 22 ++-- src/libs/qmuparser/qmuparserbytecode.cpp | 2 +- src/libs/qmuparser/qmuparserstack.h | 122 ----------------------- 5 files changed, 32 insertions(+), 164 deletions(-) delete mode 100644 src/libs/qmuparser/qmuparserstack.h diff --git a/src/libs/qmuparser/qmuparser.pro b/src/libs/qmuparser/qmuparser.pro index 31b59f338..d65bfa546 100644 --- a/src/libs/qmuparser/qmuparser.pro +++ b/src/libs/qmuparser/qmuparser.pro @@ -45,7 +45,6 @@ HEADERS += \ qmuparser_global.h \ qmuparsertokenreader.h \ qmuparsertoken.h \ - qmuparserstack.h \ qmuparserfixes.h \ qmuparsererror.h \ qmuparserdef.h \ diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 40229e420..ac0846552 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -397,30 +397,32 @@ namespace qmu } } - //--------------------------------------------------------------------------- - /** \brief Set the formula. - \param a_strFormula Formula as string_type - \throw ParserException in case of syntax errors. +//--------------------------------------------------------------------------- +/** \brief Set the formula. + \param a_strFormula Formula as string_type + \throw ParserException in case of syntax errors. - Triggers first time calculation thus the creation of the bytecode and - scanning of used variables. - */ - void QmuParserBase::SetExpr(const string_type &a_sExpr) - { + Triggers first time calculation thus the creation of the bytecode and + scanning of used variables. +*/ +void QmuParserBase::SetExpr(const string_type &a_sExpr) +{ // Check locale compatibility std::locale loc; if (m_pTokenReader->GetArgSep()==std::use_facet >(loc).decimal_point()) - Error(ecLOCALE); + { + Error(ecLOCALE); + } // 20060222: Bugfix for Borland-Kylix: // adding a space to the expression will keep Borlands KYLIX from going wild - // when calling tellg on a stringstream created from the expression after + // when calling tellg on a stringstream created from the expression after // reading a value at the end of an expression. (mu::Parser::IsVal function) // (tellg returns -1 otherwise causing the parser to ignore the value) string_type sBuf(a_sExpr + " " ); m_pTokenReader->SetFormula(sBuf); ReInit(); - } +} //--------------------------------------------------------------------------- /** \brief Get the default symbols used for the built in operators. @@ -786,9 +788,7 @@ namespace qmu \post The function token is removed from the stack \throw exception_type if Argument count does not mach function requirements. */ - void QmuParserBase::ApplyFunc( QmuParserStack &a_stOpt, - QmuParserStack &a_stVal, - int a_iArgCount) const + void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const { assert(m_pTokenReader.get()); @@ -866,8 +866,7 @@ namespace qmu } //--------------------------------------------------------------------------- - void QmuParserBase::ApplyIfElse(QmuParserStack &a_stOpt, - QmuParserStack &a_stVal) const + void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const { // Check if there is an if Else clause to be calculated while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) @@ -900,8 +899,7 @@ namespace qmu /** \brief Performs the necessary steps to write code for the execution of binary operators into the bytecode. */ - void QmuParserBase::ApplyBinOprt(QmuParserStack &a_stOpt, - QmuParserStack &a_stVal) const + void QmuParserBase::ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const { // is it a user defined binary operator? if (a_stOpt.top().GetCode()==cmOPRT_BIN) @@ -940,8 +938,7 @@ namespace qmu \param a_stOpt The operator stack \param a_stVal The value stack */ - void QmuParserBase::ApplyRemainingOprt(QmuParserStack &stOpt, - QmuParserStack &stVal) const + void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStack &stVal) const { while (stOpt.size() && stOpt.top().GetCode() != cmBO && @@ -1179,8 +1176,8 @@ namespace qmu if (!m_pTokenReader->GetExpr().length()) Error(ecUNEXPECTED_EOF, 0); - QmuParserStack stOpt, stVal; - QmuParserStack stArgCount; + QStack stOpt, stVal; + QStack stArgCount; token_type opta, opt; // for storing operators token_type val, tval; // for storing value string_type strBuf; // buffer for string function arguments @@ -1604,10 +1601,10 @@ namespace qmu This function is used for debugging only. */ - void QmuParserBase::StackDump(const QmuParserStack &a_stVal, - const QmuParserStack &a_stOprt) const + void QmuParserBase::StackDump(const QStack &a_stVal, + const QStack &a_stOprt) const { - QmuParserStack stOprt(a_stOprt), + QStack stOprt(a_stOprt), stVal(a_stVal); mu::console() << "\nValue stack:\n"; diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index e5a50bb4f..8db8b044c 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -30,6 +30,7 @@ #include #include #include +#include //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserdef.h" @@ -101,7 +102,7 @@ private: virtual ~QmuParserBase(); - qreal Eval() const; + qreal Eval() const; qreal* Eval(int &nStackSize) const; void Eval(qreal *results, int nBulkSize); @@ -239,17 +240,10 @@ private: funmap_type &a_Storage, const char_type *a_szCharSet ); - void ApplyRemainingOprt(QmuParserStack &a_stOpt, - QmuParserStack &a_stVal) const; - void ApplyBinOprt(QmuParserStack &a_stOpt, - QmuParserStack &a_stVal) const; - - void ApplyIfElse(QmuParserStack &a_stOpt, - QmuParserStack &a_stVal) const; - - void ApplyFunc(QmuParserStack &a_stOpt, - QmuParserStack &a_stVal, - int iArgCount) const; + void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; token_type ApplyStrFunc(const token_type &a_FunTok, const std::vector &a_vArg) const; @@ -268,8 +262,8 @@ private: const QmuParserCallback &a_Callback, const string_type &a_szCharSet) const; - void StackDump(const QmuParserStack &a_stVal, - const QmuParserStack &a_stOprt) const; + void StackDump(const QStack &a_stVal, + const QStack &a_stOprt) const; /** \brief Pointer to the parser function. diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 34609b591..b19b398cb 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -424,7 +424,7 @@ namespace qmu rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit // Determine the if-then-else jump offsets - QmuParserStack stIf, stElse; + QStack stIf, stElse; int idx; for (int i=0; i<(int)m_vRPN.size(); ++i) { diff --git a/src/libs/qmuparser/qmuparserstack.h b/src/libs/qmuparser/qmuparserstack.h deleted file mode 100644 index c5ba528d0..000000000 --- a/src/libs/qmuparser/qmuparserstack.h +++ /dev/null @@ -1,122 +0,0 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERSTACK_H -#define QMUPARSERSTACK_H - -#include -#include -#include -#include - -#include "qmuparsererror.h" -#include "qmuparsertoken.h" - -/** \file - \brief This file defines the stack used by muparser. -*/ - -namespace qmu -{ - - /** \brief Parser stack implementation. - - Stack implementation based on a std::stack. The behaviour of pop() had been - slightly changed in order to get an error code if the stack is empty. - The stack is used within the Parser both as a value stack and as an operator stack. - - \author (C) 2004-2011 Ingo Berg - */ - template - class QmuParserStack - { - private: - - /** \brief Type of the underlying stack implementation. */ - typedef std::stack > impl_type; - - impl_type m_Stack; ///< This is the actual stack. - - public: - - //--------------------------------------------------------------------------- - QmuParserStack() - :m_Stack() - {} - - //--------------------------------------------------------------------------- - virtual ~QmuParserStack() - {} - - //--------------------------------------------------------------------------- - /** \brief Pop a value from the stack. - - Unlike the standard implementation this function will return the value that - is going to be taken from the stack. - - \throw ParserException in case the stack is empty. - \sa pop(int &a_iErrc) - */ - TValueType pop() - { - if (empty()) - throw QmuParserError( "stack is empty." ); - - TValueType el = top(); - m_Stack.pop(); - return el; - } - - /** \brief Push an object into the stack. - - \param a_Val object to push into the stack. - \throw nothrow - */ - void push(const TValueType& a_Val) - { - m_Stack.push(a_Val); - } - - /** \brief Return the number of stored elements. */ - unsigned size() const - { - return (unsigned)m_Stack.size(); - } - - /** \brief Returns true if stack is empty false otherwise. */ - bool empty() const - { - return m_Stack.size()==0; - } - - /** \brief Return reference to the top object in the stack. - - The top object is the one pushed most recently. - */ - TValueType& top() - { - return m_Stack.top(); - } - }; -} // namespace MathUtils - -#endif From 21c38b446d1bac50d81b9aac362adc5d2a0ab4ad Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 10:23:50 +0300 Subject: [PATCH 06/26] Use Qt math function. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 196 ++++++++------------ src/libs/qmuparser/qmuparser.h | 16 -- src/libs/qmuparser/qmuparser.pro | 1 - src/libs/qmuparser/qmuparserbase.cpp | 49 +++-- src/libs/qmuparser/qmuparserbase.h | 3 +- src/libs/qmuparser/qmuparserbytecode.cpp | 98 +++++----- src/libs/qmuparser/qmuparsertemplatemagic.h | 150 --------------- src/libs/qmuparser/qmuparsertest.cpp | 118 ++++++------ src/libs/qmuparser/qmuparsertoken.h | 1 + 9 files changed, 213 insertions(+), 419 deletions(-) delete mode 100644 src/libs/qmuparser/qmuparsertemplatemagic.h diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index fb8a250ce..3f63b4b86 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -21,7 +21,8 @@ ******************************************************************************************************/ #include "qmuparser.h" -#include "qmuparsertemplatemagic.h" +#include +#include //--- Standard includes ------------------------------------------------------------------------ #include @@ -40,28 +41,17 @@ using namespace std; \brief Implementation of the standard floating point QmuParser. */ - - /** \brief Namespace for mathematical applications. */ namespace qmu { - - //--------------------------------------------------------------------------- // Trigonometric function - qreal QmuParser::Sin(qreal v) { return MathImpl::Sin(v); } - qreal QmuParser::Cos(qreal v) { return MathImpl::Cos(v); } - qreal QmuParser::Tan(qreal v) { return MathImpl::Tan(v); } - qreal QmuParser::ASin(qreal v) { return MathImpl::ASin(v); } - qreal QmuParser::ACos(qreal v) { return MathImpl::ACos(v); } - qreal QmuParser::ATan(qreal v) { return MathImpl::ATan(v); } - qreal QmuParser::ATan2(qreal v1, qreal v2) { return MathImpl::ATan2(v1, v2); } - qreal QmuParser::Sinh(qreal v) { return MathImpl::Sinh(v); } - qreal QmuParser::Cosh(qreal v) { return MathImpl::Cosh(v); } - qreal QmuParser::Tanh(qreal v) { return MathImpl::Tanh(v); } - qreal QmuParser::ASinh(qreal v) { return MathImpl::ASinh(v); } - qreal QmuParser::ACosh(qreal v) { return MathImpl::ACosh(v); } - qreal QmuParser::ATanh(qreal v) { return MathImpl::ATanh(v); } + qreal QmuParser::Sinh(qreal v) { return sinh(v); } + qreal QmuParser::Cosh(qreal v) { return cosh(v); } + qreal QmuParser::Tanh(qreal v) { return tanh(v); } + qreal QmuParser::ASinh(qreal v) { return log(v + qSqrt(v * v + 1)); } + qreal QmuParser::ACosh(qreal v) { return log(v + qSqrt(v * v - 1)); } + qreal QmuParser::ATanh(qreal v) { return ((qreal)0.5 * log((1 + v) / (1 - v))); } //--------------------------------------------------------------------------- // Logarithm functions @@ -74,7 +64,7 @@ namespace qmu throw QmuParserError(ecDOMAIN_ERROR, "Log2"); #endif - return MathImpl::Log2(v); + return log(v)/log((qreal)2); } // Logarithm base 10 @@ -85,35 +75,14 @@ namespace qmu throw QmuParserError(ecDOMAIN_ERROR, "Log10"); #endif - return MathImpl::Log10(v); - } - -// Logarithm base e (natural logarithm) - qreal QmuParser::Ln(qreal v) - { - #ifdef MUP_MATH_EXCEPTIONS - if (v<=0) - throw QmuParserError(ecDOMAIN_ERROR, "Ln"); - #endif - - return MathImpl::Log(v); + return log10(v); } //--------------------------------------------------------------------------- // misc - qreal QmuParser::Exp(qreal v) { return MathImpl::Exp(v); } - qreal QmuParser::Abs(qreal v) { return MathImpl::Abs(v); } - qreal QmuParser::Sqrt(qreal v) - { - #ifdef MUP_MATH_EXCEPTIONS - if (v<0) - throw QmuParserError(ecDOMAIN_ERROR, "sqrt"); - #endif - - return MathImpl::Sqrt(v); - } - qreal QmuParser::Rint(qreal v) { return MathImpl::Rint(v); } - qreal QmuParser::Sign(qreal v) { return MathImpl::Sign(v); } + qreal QmuParser::Abs(qreal v) { return (v>=0) ? v : -v; } + qreal QmuParser::Rint(qreal v) { return qFloor(v + (qreal)0.5); } + qreal QmuParser::Sign(qreal v) { return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); } //--------------------------------------------------------------------------- /** \brief Callback for the unary minus operator. @@ -156,39 +125,45 @@ namespace qmu } - //--------------------------------------------------------------------------- - /** \brief Callback for determining the minimum value out of a vector. - \param [in] a_afArg Vector with the function arguments - \param [in] a_iArgc The size of a_afArg - */ - qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc) - { +//--------------------------------------------------------------------------- +/** \brief Callback for determining the minimum value out of a vector. + \param [in] a_afArg Vector with the function arguments + \param [in] a_iArgc The size of a_afArg +*/ +qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc) +{ if (!a_iArgc) - throw exception_type("too few arguments for function min."); + { + throw exception_type("too few arguments for function min."); + } qreal fRes=a_afArg[0]; for (int i=0; i=#!$%&|~'_" ); } - //--------------------------------------------------------------------------- - /** \brief Initialize the default functions. */ - void QmuParser::InitFun() - { - if (qmu::TypeInfo::IsInteger()) - { - // When setting MUP_BASETYPE to an integer type - // Place functions for dealing with integer values here - // ... - // ... - // ... - } - else - { - // trigonometric functions - DefineFun("sin", Sin); - DefineFun("cos", Cos); - DefineFun("tan", Tan); - // arcus functions - DefineFun("asin", ASin); - DefineFun("acos", ACos); - DefineFun("atan", ATan); - DefineFun("atan2", ATan2); - // hyperbolic functions - DefineFun("sinh", Sinh); - DefineFun("cosh", Cosh); - DefineFun("tanh", Tanh); - // arcus hyperbolic functions - DefineFun("asinh", ASinh); - DefineFun("acosh", ACosh); - DefineFun("atanh", ATanh); - // Logarithm functions - DefineFun("log2", Log2); - DefineFun("log10", Log10); - DefineFun("log", Log10); - DefineFun("ln", Ln); - // misc - DefineFun("exp", Exp); - DefineFun("sqrt", Sqrt); - DefineFun("sign", Sign); - DefineFun("rint", Rint); - DefineFun("abs", Abs); - // Functions with variable number of arguments - DefineFun("sum", Sum); - DefineFun("avg", Avg); - DefineFun("min", Min); - DefineFun("max", Max); - } - } +//--------------------------------------------------------------------------- +/** \brief Initialize the default functions. */ +void QmuParser::InitFun() +{ + // trigonometric functions + DefineFun("sin", qSin); + DefineFun("cos", qCos); + DefineFun("tan", qTan); + // arcus functions + DefineFun("asin", qAsin); + DefineFun("acos", qAcos); + DefineFun("atan", qAtan); + DefineFun("atan2", qAtan2); + // hyperbolic functions + DefineFun("sinh", Sinh); + DefineFun("cosh", Cosh); + DefineFun("tanh", Tanh); + // arcus hyperbolic functions + DefineFun("asinh", ASinh); + DefineFun("acosh", ACosh); + DefineFun("atanh", ATanh); + // Logarithm functions + DefineFun("log2", Log2); + DefineFun("log10", Log10); + DefineFun("log", Log10); + DefineFun("ln", qLn); + // misc + DefineFun("exp", qExp); + DefineFun("sqrt", qSqrt); + DefineFun("sign", Sign); + DefineFun("rint", Rint); + DefineFun("abs", Abs); + // Functions with variable number of arguments + DefineFun("sum", Sum); + DefineFun("avg", Avg); + DefineFun("min", Min); + DefineFun("max", Max); +} //--------------------------------------------------------------------------- /** \brief Initialize constants. diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 6832a1fde..b1a078597 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -30,7 +30,6 @@ //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserbase.h" -#include "qmuparsertemplatemagic.h" /** \file \brief Definition of the standard floating point parser. @@ -61,18 +60,8 @@ public: qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; protected: - // Trigonometric functions - static qreal Sin(qreal); - static qreal Cos(qreal); - static qreal Tan(qreal); static qreal Tan2(qreal, qreal); - // arcus functions - static qreal ASin(qreal); - static qreal ACos(qreal); - static qreal ATan(qreal); - static qreal ATan2(qreal, qreal); - // hyperbolic functions static qreal Sinh(qreal); static qreal Cosh(qreal); @@ -84,18 +73,13 @@ protected: // Logarithm functions static qreal Log2(qreal); // Logarithm Base 2 static qreal Log10(qreal); // Logarithm Base 10 - static qreal Ln(qreal); // Logarithm Base e (natural logarithm) // misc - static qreal Exp(qreal); static qreal Abs(qreal); - static qreal Sqrt(qreal); static qreal Rint(qreal); static qreal Sign(qreal); - // Prefix operators // !!! Unary Minus is a MUST if you want to use negative signs !!! static qreal UnaryMinus(qreal); - // Functions with variable number of arguments static qreal Sum(const qreal*, int); // sum static qreal Avg(const qreal*, int); // mean value diff --git a/src/libs/qmuparser/qmuparser.pro b/src/libs/qmuparser/qmuparser.pro index d65bfa546..884db095b 100644 --- a/src/libs/qmuparser/qmuparser.pro +++ b/src/libs/qmuparser/qmuparser.pro @@ -52,7 +52,6 @@ HEADERS += \ qmuparserbytecode.h \ qmuparserbase.h \ qmuparsertest.h \ - qmuparsertemplatemagic.h \ qmuparserint.h \ stable.h diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index ac0846552..786f4aa37 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -21,7 +21,6 @@ ******************************************************************************************************/ #include "qmuparserbase.h" -#include "qmuparsertemplatemagic.h" //--- Standard includes ------------------------------------------------------------------------ #include @@ -266,11 +265,11 @@ namespace qmu stringstream_type ss; - ss << MUP_VERSION; + ss << QMUP_VERSION; if (eInfo==pviFULL) { - ss << " (" << MUP_VERSION_DATE; + ss << " (" << QMUP_VERSION_DATE; ss << std::dec << "; " << sizeof(void*)*8 << "BIT"; #ifdef _DEBUG @@ -1030,7 +1029,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) continue; case cmPOW: - --sidx; Stack[sidx] = MathImpl::Pow(Stack[sidx], Stack[1+sidx]); + --sidx; Stack[sidx] = std::pow(Stack[sidx], Stack[1+sidx]); continue; case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue; @@ -1607,22 +1606,22 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) QStack stOprt(a_stOprt), stVal(a_stVal); - mu::console() << "\nValue stack:\n"; + qmu::console() << "\nValue stack:\n"; while ( !stVal.empty() ) { token_type val = stVal.pop(); if (val.GetType()==tpSTR) - mu::console() << " \"" << val.GetAsString() << "\" "; + qmu::console() << " \"" << val.GetAsString() << "\" "; else - mu::console() << " " << val.GetVal() << " "; + qmu::console() << " " << val.GetVal() << " "; } - mu::console() << "\nOperator stack:\n"; + qmu::console() << "\nOperator stack:\n"; while ( !stOprt.empty() ) { if (stOprt.top().GetCode()<=cmASSIGN) { - mu::console() << "OPRT_INTRNL \"" + qmu::console() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << "\" \n"; } @@ -1630,35 +1629,35 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) { switch(stOprt.top().GetCode()) { - case cmVAR: mu::console() << "VAR\n"; break; - case cmVAL: mu::console() << "VAL\n"; break; - case cmFUNC: mu::console() << "FUNC \"" + case cmVAR: qmu::console() << "VAR\n"; break; + case cmVAL: qmu::console() << "VAL\n"; break; + case cmFUNC: qmu::console() << "FUNC \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmFUNC_BULK: mu::console() << "FUNC_BULK \"" + case cmFUNC_BULK: qmu::console() << "FUNC_BULK \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmOPRT_INFIX: mu::console() << "OPRT_INFIX \"" + case cmOPRT_INFIX: qmu::console() << "OPRT_INFIX \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmOPRT_BIN: mu::console() << "OPRT_BIN \"" + case cmOPRT_BIN: qmu::console() << "OPRT_BIN \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmFUNC_STR: mu::console() << "FUNC_STR\n"; break; - case cmEND: mu::console() << "END\n"; break; - case cmUNKNOWN: mu::console() << "UNKNOWN\n"; break; - case cmBO: mu::console() << "BRACKET \"(\"\n"; break; - case cmBC: mu::console() << "BRACKET \")\"\n"; break; - case cmIF: mu::console() << "IF\n"; break; - case cmELSE: mu::console() << "ELSE\n"; break; - case cmENDIF: mu::console() << "ENDIF\n"; break; - default: mu::console() << stOprt.top().GetCode() << " "; break; + case cmFUNC_STR: qmu::console() << "FUNC_STR\n"; break; + case cmEND: qmu::console() << "END\n"; break; + case cmUNKNOWN: qmu::console() << "UNKNOWN\n"; break; + case cmBO: qmu::console() << "BRACKET \"(\"\n"; break; + case cmBC: qmu::console() << "BRACKET \")\"\n"; break; + case cmIF: qmu::console() << "IF\n"; break; + case cmELSE: qmu::console() << "ELSE\n"; break; + case cmENDIF: qmu::console() << "ENDIF\n"; break; + default: qmu::console() << stOprt.top().GetCode() << " "; break; } } stOprt.pop(); } - mu::console() << dec << endl; + qmu::console() << dec << endl; } //------------------------------------------------------------------------------ diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 8db8b044c..4340a4a23 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -34,7 +34,6 @@ //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserdef.h" -#include "qmuparserstack.h" #include "qmuparsertokenreader.h" #include "qmuparserbytecode.h" #include "qmuparsererror.h" @@ -121,7 +120,7 @@ private: bool HasBuiltInOprt() const; void AddValIdent(identfun_type a_pCallback); - /** \fn void mu::QParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) + /** \fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) \brief Define a parser function without arguments. \param a_strName Name of the function \param a_pFun Pointer to the callback function diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index b19b398cb..e74b04dbe 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -31,8 +31,6 @@ #include "qmuparserdef.h" #include "qmuparsererror.h" #include "qmuparsertoken.h" -#include "qmuparserstack.h" -#include "qmuparsertemplatemagic.h" namespace qmu @@ -166,7 +164,7 @@ namespace qmu m_vRPN.pop_back(); break; - case cmPOW: x = MathImpl::Pow(x, y); + case cmPOW: x = std::pow(x, y); m_vRPN.pop_back(); break; @@ -495,89 +493,89 @@ namespace qmu { if (!m_vRPN.size()) { - mu::console() << "No bytecode available\n"; + qmu::console() << "No bytecode available\n"; return; } - mu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n"; + qmu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n"; for (std::size_t i=0; i -#include "muParserError.h" - - -namespace qmu -{ - //----------------------------------------------------------------------------------------------- - // - // Compile time type detection - // - //----------------------------------------------------------------------------------------------- - - /** \brief A class singling out integer types at compile time using - template meta programming. - */ - template - struct TypeInfo - { - static bool IsInteger() { return false; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - template<> - struct TypeInfo - { - static bool IsInteger() { return true; } - }; - - - //----------------------------------------------------------------------------------------------- - // - // Standard math functions with dummy overload for integer types - // - //----------------------------------------------------------------------------------------------- - - /** \brief A template class for providing wrappers for essential math functions. - - This template is spezialized for several types in order to provide a unified interface - for parser internal math function calls regardless of the data type. - */ - template - struct MathImpl - { - static T Sin(T v) { return sin(v); } - static T Cos(T v) { return cos(v); } - static T Tan(T v) { return tan(v); } - static T ASin(T v) { return asin(v); } - static T ACos(T v) { return acos(v); } - static T ATan(T v) { return atan(v); } - static T ATan2(T v1, T v2) { return atan2(v1, v2); } - static T Sinh(T v) { return sinh(v); } - static T Cosh(T v) { return cosh(v); } - static T Tanh(T v) { return tanh(v); } - static T ASinh(T v) { return log(v + sqrt(v * v + 1)); } - static T ACosh(T v) { return log(v + sqrt(v * v - 1)); } - static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); } - static T Log(T v) { return log(v); } - static T Log2(T v) { return log(v)/log((T)2); } // Logarithm base 2 - static T Log10(T v) { return log10(v); } // Logarithm base 10 - static T Exp(T v) { return exp(v); } - static T Abs(T v) { return (v>=0) ? v : -v; } - static T Sqrt(T v) { return sqrt(v); } - static T Rint(T v) { return floor(v + (T)0.5); } - static T Sign(T v) { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); } - static T Pow(T v1, T v2) { return std::pow(v1, v2); } - }; - - // Create (mostly) dummy math function definitions for integer types. They are mostly - // empty since they are not applicable for integer values. -#define MAKE_MATH_DUMMY(TYPE) \ - template<> \ - struct MathImpl \ - { \ - static TYPE Sin(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Cos(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Tan(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ASin(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ACos(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ATan(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ATan2(TYPE, TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Sinh(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Cosh(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Tanh(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ASinh(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ACosh(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE ATanh(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Log(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Log2(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Log10(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Exp(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Abs(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Sqrt(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Rint(TYPE) { throw QmuParserError("unimplemented function."); } \ - static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \ - static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \ - }; - - MAKE_MATH_DUMMY(char) - MAKE_MATH_DUMMY(short) - MAKE_MATH_DUMMY(int) - MAKE_MATH_DUMMY(long) - -#undef MAKE_MATH_DUMMY -} - -#endif diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index eeacdc29d..24d0f9afd 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -88,7 +88,7 @@ namespace qmu int QmuParserTester::TestInterface() { int iStat = 0; - mu::console() << "testing member functions..."; + qmu::console() << "testing member functions..."; // Test RemoveVar qreal afVal[3] = {1,2,3}; @@ -119,9 +119,9 @@ namespace qmu } if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -130,7 +130,7 @@ namespace qmu int QmuParserTester::TestStrArg() { int iStat = 0; - mu::console() << "testing string arguments..."; + qmu::console() << "testing string arguments..."; iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true); @@ -144,9 +144,9 @@ namespace qmu iStat += EqnTest("strfun3(\"99\",1,2)", 102, true); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -155,7 +155,7 @@ namespace qmu int QmuParserTester::TestBinOprt() { int iStat = 0; - mu::console() << "testing binary operators..."; + qmu::console() << "testing binary operators..."; // built in operators // xor operator @@ -288,9 +288,9 @@ namespace qmu if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -302,7 +302,7 @@ namespace qmu int iStat= 0, iErr = 0; - mu::console() << "testing name restriction enforcement..."; + qmu::console() << "testing name restriction enforcement..."; QmuParser p; @@ -397,9 +397,9 @@ namespace qmu #undef PARSER_THROWCHECK if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -408,7 +408,7 @@ namespace qmu int QmuParserTester::TestSyntax() { int iStat = 0; - mu::console() << "testing syntax engine..."; + qmu::console() << "testing syntax engine..."; iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition @@ -446,9 +446,9 @@ namespace qmu iStat += EqnTest("sin()", 0, false); // unexpected closing bracket if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -457,7 +457,7 @@ namespace qmu int QmuParserTester::TestVarConst() { int iStat = 0; - mu::console() << "testing variable/constant detection..."; + qmu::console() << "testing variable/constant detection..."; // Test if the result changes when a variable changes iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 ); @@ -504,7 +504,7 @@ namespace qmu // Test lookup of defined variables // 4 used variables p.SetExpr( "a+b+c+d" ); - mu::varmap_type UsedVar = p.GetUsedVar(); + qmu::varmap_type UsedVar = p.GetUsedVar(); int iCount = (int)UsedVar.size(); if (iCount!=4) throw false; @@ -514,7 +514,7 @@ namespace qmu if (p.GetVar().size()!=5) throw false; - mu::varmap_type::const_iterator item = UsedVar.begin(); + qmu::varmap_type::const_iterator item = UsedVar.begin(); for (idx=0; item!=UsedVar.end(); ++item) { if (&vVarVal[idx++]!=item->second) @@ -555,9 +555,9 @@ namespace qmu } if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -566,7 +566,7 @@ namespace qmu int QmuParserTester::TestMultiArg() { int iStat = 0; - mu::console() << "testing multiarg functions..."; + qmu::console() << "testing multiarg functions..."; // Compound expressions iStat += EqnTest( "1,2,3", 3, true); @@ -649,9 +649,9 @@ namespace qmu iStat += EqnTest( "sum(,1,2)", 0, false); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -661,7 +661,7 @@ namespace qmu int QmuParserTester::TestInfixOprt() { int iStat(0); - mu::console() << "testing infix operators..."; + qmu::console() << "testing infix operators..."; iStat += EqnTest( "-1", -1, true); iStat += EqnTest( "-(-1)", 1, true); @@ -714,9 +714,9 @@ namespace qmu iStat += EqnTest( "~~ 123", 123+2, true); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -726,7 +726,7 @@ namespace qmu int QmuParserTester::TestPostFix() { int iStat = 0; - mu::console() << "testing postfix operators..."; + qmu::console() << "testing postfix operators..."; // application iStat += EqnTest( "3{m}+5", 5.003, true); @@ -766,9 +766,9 @@ namespace qmu iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -777,7 +777,7 @@ namespace qmu int QmuParserTester::TestExpression() { int iStat = 0; - mu::console() << "testing expression samples..."; + qmu::console() << "testing expression samples..."; qreal b = 2; @@ -846,9 +846,9 @@ namespace qmu iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -859,7 +859,7 @@ namespace qmu int QmuParserTester::TestIfThenElse() { int iStat = 0; - mu::console() << "testing if-then-else operator..."; + qmu::console() << "testing if-then-else operator..."; // Test error detection iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL); @@ -954,9 +954,9 @@ namespace qmu iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -965,7 +965,7 @@ namespace qmu int QmuParserTester::TestException() { int iStat = 0; - mu::console() << "testing error codes..."; + qmu::console() << "testing error codes..."; iStat += ThrowTest("3+", ecUNEXPECTED_EOF); iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS); @@ -1048,9 +1048,9 @@ namespace qmu iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT); if (iStat==0) - mu::console() << "passed" << endl; + qmu::console() << "passed" << endl; else - mu::console() << "\n failed with " << iStat << " errors" << endl; + qmu::console() << "\n failed with " << iStat << " errors" << endl; return iStat; } @@ -1073,28 +1073,28 @@ namespace qmu } catch(QmuParser::exception_type &e) { - mu::console() << "\n" << e.GetMsg() << endl; - mu::console() << e.GetToken() << endl; + qmu::console() << "\n" << e.GetMsg() << endl; + qmu::console() << e.GetToken() << endl; Abort(); } catch(std::exception &e) { - mu::console() << e.what() << endl; + qmu::console() << e.what() << endl; Abort(); } catch(...) { - mu::console() << "Internal error"; + qmu::console() << "Internal error"; Abort(); } if (iStat==0) { - mu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl; + qmu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl; } else { - mu::console() << "Test failed with " << iStat + qmu::console() << "Test failed with " << iStat << " errors (" << QmuParserTester::c_iCount << " expressions)" << endl; } @@ -1130,7 +1130,7 @@ namespace qmu // output the formula in case of an failed test if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) { - mu::console() << "\n " + qmu::console() << "\n " << "Expression: " << a_str << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" << " Expected:" << a_iErrc; @@ -1143,7 +1143,7 @@ namespace qmu bool bRet((a_bFail==false) ? 0 : 1); if (bRet==1) { - mu::console() << "\n " + qmu::console() << "\n " << "Expression: " << a_str << " did evaluate; Expected error:" << a_iErrc; } @@ -1188,17 +1188,17 @@ namespace qmu } catch(QmuParser::exception_type &e) { - mu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; + qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; return 1; } catch(std::exception &e) { - mu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; + qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1329,7 +1329,7 @@ namespace qmu } catch(std::exception &e) { - mu::console() << "\n " << e.what() << "\n"; + qmu::console() << "\n " << e.what() << "\n"; } // limited floating point accuracy requires the following test @@ -1350,7 +1350,7 @@ namespace qmu if (iRet==1) { - mu::console() << "\n fail: " << a_str.c_str() + qmu::console() << "\n fail: " << a_str.c_str() << " (incorrect result; expected: " << a_fRes << " ;calculated: " << fVal[0] << "," << fVal[1] << "," @@ -1364,20 +1364,20 @@ namespace qmu if (a_fPass) { if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) - mu::console() << "\n fail: " << a_str.c_str() << " (copy construction)"; + qmu::console() << "\n fail: " << a_str.c_str() << " (copy construction)"; else - mu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; + qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; return 1; } } catch(std::exception &e) { - mu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; + qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1413,7 +1413,7 @@ namespace qmu (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1; if (iRet==1) { - mu::console() << "\n fail: " << a_str.c_str() + qmu::console() << "\n fail: " << a_str.c_str() << " (incorrect result; expected: " << a_fRes << " ;calculated: " << fVal[0]<< ")."; } @@ -1422,13 +1422,13 @@ namespace qmu { if (a_fPass) { - mu::console() << "\n fail: " << e.GetExpr() << " : " << e.GetMsg(); + qmu::console() << "\n fail: " << e.GetExpr() << " : " << e.GetMsg(); iRet = 1; } } catch(...) { - mu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; iRet = 1; // exceptions other than ParserException are not allowed } @@ -1439,7 +1439,7 @@ namespace qmu /** \brief Internal error in test class Test is going to be aborted. */ void QmuParserTester::Abort() const { - mu::console() << "Test failed (internal error in test class)" << endl; + qmu::console() << "Test failed (internal error in test class)" << endl; while (!getchar()); exit(-1); } diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index a475abe9f..404a3b3a1 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "qmuparsererror.h" #include "qmuparsercallback.h" From d8f0cc28241aa6b23924080621a511f0fcbe6d09 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 10:40:44 +0300 Subject: [PATCH 07/26] Use standard math constants. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 3f63b4b86..2517cd8fb 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -25,16 +25,9 @@ #include //--- Standard includes ------------------------------------------------------------------------ -#include #include #include -/** \brief Pi (what else?). */ -#define QmuParser_CONST_PI 3.141592653589793238462643 - -/** \brief The eulerian number. */ -#define QmuParser_CONST_E 2.718281828459045235360287 - using namespace std; /** \file @@ -80,7 +73,7 @@ namespace qmu //--------------------------------------------------------------------------- // misc - qreal QmuParser::Abs(qreal v) { return (v>=0) ? v : -v; } + qreal QmuParser::Abs(qreal v) { return qAbs(v); } qreal QmuParser::Rint(qreal v) { return qFloor(v + (qreal)0.5); } qreal QmuParser::Sign(qreal v) { return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); } @@ -269,8 +262,8 @@ void QmuParser::InitFun() */ void QmuParser::InitConst() { - DefineConst("_pi", (qreal)QmuParser_CONST_PI); - DefineConst("_e", (qreal)QmuParser_CONST_E); + DefineConst("_pi", (qreal)M_PI); + DefineConst("_e", (qreal)M_E); } //--------------------------------------------------------------------------- From 148d2fb3f7a99704e1f41b33eeb38c44cc48e1f5 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 10:51:14 +0300 Subject: [PATCH 08/26] We don't need parser for integer value. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.pro | 2 - src/libs/qmuparser/qmuparserint.cpp | 277 --------------------------- src/libs/qmuparser/qmuparserint.h | 132 ------------- src/libs/qmuparser/qmuparsertest.cpp | 124 ------------ src/libs/qmuparser/qmuparsertest.h | 4 - 5 files changed, 539 deletions(-) delete mode 100644 src/libs/qmuparser/qmuparserint.cpp delete mode 100644 src/libs/qmuparser/qmuparserint.h diff --git a/src/libs/qmuparser/qmuparser.pro b/src/libs/qmuparser/qmuparser.pro index 884db095b..86ccbd71a 100644 --- a/src/libs/qmuparser/qmuparser.pro +++ b/src/libs/qmuparser/qmuparser.pro @@ -37,7 +37,6 @@ SOURCES += \ qmuparserbytecode.cpp \ qmuparserbase.cpp \ qmuparsertest.cpp \ - qmuparserint.cpp \ stable.cpp HEADERS += \ @@ -52,7 +51,6 @@ HEADERS += \ qmuparserbytecode.h \ qmuparserbase.h \ qmuparsertest.h \ - qmuparserint.h \ stable.h VERSION = 2.2.3 diff --git a/src/libs/qmuparser/qmuparserint.cpp b/src/libs/qmuparser/qmuparserint.cpp deleted file mode 100644 index 729ff1a4c..000000000 --- a/src/libs/qmuparser/qmuparserint.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include "qmuparserint.h" - -#include -#include -#include - -using namespace std; - -/** \file - \brief Implementation of a parser using integer value. -*/ - -/** \brief Namespace for mathematical applications. */ -namespace qmu -{ -qreal QmuParserInt::Abs(qreal v) { return (qreal)Round(fabs((double)v)); } -qreal QmuParserInt::Sign(qreal v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; } -qreal QmuParserInt::Ite(qreal v1, - qreal v2, - qreal v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); } -qreal QmuParserInt::Add(qreal v1, qreal v2) { return Round(v1) + Round(v2); } -qreal QmuParserInt::Sub(qreal v1, qreal v2) { return Round(v1) - Round(v2); } -qreal QmuParserInt::Mul(qreal v1, qreal v2) { return Round(v1) * Round(v2); } -qreal QmuParserInt::Div(qreal v1, qreal v2) { return Round(v1) / Round(v2); } -qreal QmuParserInt::Mod(qreal v1, qreal v2) { return Round(v1) % Round(v2); } -qreal QmuParserInt::Shr(qreal v1, qreal v2) { return Round(v1) >> Round(v2); } -qreal QmuParserInt::Shl(qreal v1, qreal v2) { return Round(v1) << Round(v2); } -qreal QmuParserInt::LogAnd(qreal v1, qreal v2) { return Round(v1) & Round(v2); } -qreal QmuParserInt::LogOr(qreal v1, qreal v2) { return Round(v1) | Round(v2); } -qreal QmuParserInt::And(qreal v1, qreal v2) { return Round(v1) && Round(v2); } -qreal QmuParserInt::Or(qreal v1, qreal v2) { return Round(v1) || Round(v2); } -qreal QmuParserInt::Less(qreal v1, qreal v2) { return Round(v1) < Round(v2); } -qreal QmuParserInt::Greater(qreal v1, qreal v2) { return Round(v1) > Round(v2); } -qreal QmuParserInt::LessEq(qreal v1, qreal v2) { return Round(v1) <= Round(v2); } -qreal QmuParserInt::GreaterEq(qreal v1, qreal v2) { return Round(v1) >= Round(v2); } -qreal QmuParserInt::Equal(qreal v1, qreal v2) { return Round(v1) == Round(v2); } -qreal QmuParserInt::NotEqual(qreal v1, qreal v2) { return Round(v1) != Round(v2); } -qreal QmuParserInt::Not(qreal v) { return !Round(v); } - -qreal QmuParserInt::Pow(qreal v1, qreal v2) -{ - return std::pow((double)Round(v1), (double)Round(v2)); -} - -//--------------------------------------------------------------------------- -// Unary operator Callbacks: Infix operators -qreal QmuParserInt::UnaryMinus(qreal v) -{ - return -Round(v); -} - -//--------------------------------------------------------------------------- -qreal QmuParserInt::Sum(const qreal* a_afArg, int a_iArgc) -{ - if (!a_iArgc) - throw QmuParserError("too few arguments for function sum."); - - qreal fRes=0; - for (int i=0; i> iVal; - if (stream.fail()) - return 0; - - stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading - if (stream.fail()) - iEnd = stream.str().length(); - - if (iEnd==(stringstream_type::pos_type)-1) - return 0; - - *a_iPos += (int)iEnd; - *a_fVal = (qreal)iVal; - return 1; -} - -//--------------------------------------------------------------------------- -/** \brief Check a given position in the expression for the presence of - a hex value. - \param a_szExpr Pointer to the expression string - \param [in/out] a_iPos Pointer to an interger value holding the current parsing - position in the expression. - \param [out] a_fVal Pointer to the position where the detected value shall be stored. - - Hey values must be prefixed with "0x" in order to be detected properly. -*/ -int QmuParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal) -{ - if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) - return 0; - - unsigned iVal(0); - - // New code based on streams for UNICODE compliance: - stringstream_type::pos_type nPos(0); - stringstream_type ss(a_szExpr + 2); - ss >> std::hex >> iVal; - nPos = ss.tellg(); - - if (nPos==(stringstream_type::pos_type)0) - return 1; - - *a_iPos += (int)(2 + nPos); - *a_fVal = (qreal)iVal; - return 1; -} - -//--------------------------------------------------------------------------- -int QmuParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal) -{ - if (a_szExpr[0]!='#') - return 0; - - unsigned iVal(0), - iBits(sizeof(iVal)*8), - i(0); - - for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i> (iBits-i) ); - *a_iPos += i+1; - - return 1; -} - -//--------------------------------------------------------------------------- -/** \brief Constructor. - - Call ParserBase class constructor and trigger Function, Operator and Constant initialization. -*/ -QmuParserInt::QmuParserInt() - :QmuParserBase() -{ - AddValIdent(IsVal); // lowest priority - AddValIdent(IsBinVal); - AddValIdent(IsHexVal); // highest priority - - InitCharSets(); - InitFun(); - InitOprt(); -} - -//--------------------------------------------------------------------------- -void QmuParserInt::InitConst() -{ -} - -//--------------------------------------------------------------------------- -void QmuParserInt::InitCharSets() -{ - DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); - DefineOprtChars( "+-*^/?<>=!%&|~'_" ); - DefineInfixOprtChars( "/+-*^?<>=!%&|~'_" ); -} - -//--------------------------------------------------------------------------- -/** \brief Initialize the default functions. */ -void QmuParserInt::InitFun() -{ - DefineFun( "sign", Sign); - DefineFun( "abs", Abs); - DefineFun( "if", Ite); - DefineFun( "sum", Sum); - DefineFun( "min", Min); - DefineFun( "max", Max); -} - -//--------------------------------------------------------------------------- -/** \brief Initialize operators. */ -void QmuParserInt::InitOprt() -{ - // disable all built in operators, not all of them usefull for integer numbers - // (they don't do rounding of values) - EnableBuiltInOprt(false); - - // Disable all built in operators, they wont work with integer numbers - // since they are designed for floating point numbers - DefineInfixOprt( "-", UnaryMinus); - DefineInfixOprt( "!", Not); - - DefineOprt( "&", LogAnd, prLOGIC); - DefineOprt( "|", LogOr, prLOGIC); - DefineOprt( "&&", And, prLOGIC); - DefineOprt( "||", Or, prLOGIC); - - DefineOprt( "<", Less, prCMP); - DefineOprt( ">", Greater, prCMP); - DefineOprt( "<=", LessEq, prCMP); - DefineOprt( ">=", GreaterEq, prCMP); - DefineOprt( "==", Equal, prCMP); - DefineOprt( "!=", NotEqual, prCMP); - - DefineOprt( "+", Add, prADD_SUB); - DefineOprt( "-", Sub, prADD_SUB); - - DefineOprt( "*", Mul, prMUL_DIV); - DefineOprt( "/", Div, prMUL_DIV); - DefineOprt( "%", Mod, prMUL_DIV); - - DefineOprt( "^", Pow, prPOW, oaRIGHT); - DefineOprt( ">>", Shr, prMUL_DIV+1); - DefineOprt( "<<", Shl, prMUL_DIV+1); -} - -} // namespace qmu diff --git a/src/libs/qmuparser/qmuparserint.h b/src/libs/qmuparser/qmuparserint.h deleted file mode 100644 index 98ef3b1a8..000000000 --- a/src/libs/qmuparser/qmuparserint.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERINT_H -#define QMUPARSERINT_H - -#include "qmuparserbase.h" -#include - - -/** \file - \brief Definition of a parser using integer value. -*/ - - -namespace qmu -{ - -/** \brief Mathematical expressions parser. - - This version of the parser handles only integer numbers. It disables the built in operators thus it is - slower than muParser. Integer values are stored in the double value_type and converted if needed. -*/ -class QmuParserInt : public QmuParserBase -{ -private: - static int Round(qreal v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); }; - - static qreal Abs(qreal); - static qreal Sign(qreal); - static qreal Ite(qreal, qreal, qreal); - // !! The unary Minus is a MUST, otherwise you cant use negative signs !! - static qreal UnaryMinus(qreal); - // Functions with variable number of arguments - static qreal Sum(const qreal* a_afArg, int a_iArgc); // sum - static qreal Min(const qreal* a_afArg, int a_iArgc); // minimum - static qreal Max(const qreal* a_afArg, int a_iArgc); // maximum - // binary operator callbacks - static qreal Add(qreal v1, qreal v2); - static qreal Sub(qreal v1, qreal v2); - static qreal Mul(qreal v1, qreal v2); - static qreal Div(qreal v1, qreal v2); - static qreal Mod(qreal v1, qreal v2); - static qreal Pow(qreal v1, qreal v2); - static qreal Shr(qreal v1, qreal v2); - static qreal Shl(qreal v1, qreal v2); - static qreal LogAnd(qreal v1, qreal v2); - static qreal LogOr(qreal v1, qreal v2); - static qreal And(qreal v1, qreal v2); - static qreal Or(qreal v1, qreal v2); - static qreal Xor(qreal v1, qreal v2); - static qreal Less(qreal v1, qreal v2); - static qreal Greater(qreal v1, qreal v2); - static qreal LessEq(qreal v1, qreal v2); - static qreal GreaterEq(qreal v1, qreal v2); - static qreal Equal(qreal v1, qreal v2); - static qreal NotEqual(qreal v1, qreal v2); - static qreal Not(qreal v1); - - static int IsHexVal(const char_type* a_szExpr, int *a_iPos, qreal *a_iVal); - static int IsBinVal(const char_type* a_szExpr, int *a_iPos, qreal *a_iVal); - static int IsVal (const char_type* a_szExpr, int *a_iPos, qreal *a_iVal); - - /** \brief A facet class used to change decimal and thousands separator. */ - template - class change_dec_sep : public std::numpunct - { - public: - - explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) - :std::numpunct() - ,m_cDecPoint(cDecSep) - ,m_cThousandsSep(cThousandsSep) - ,m_nGroup(nGroup) - {} - - protected: - - virtual char_type do_decimal_point() const - { - return m_cDecPoint; - } - - virtual char_type do_thousands_sep() const - { - return m_cThousandsSep; - } - - virtual std::string do_grouping() const - { - return std::string(1, m_nGroup); - } - - private: - - int m_nGroup; - char_type m_cDecPoint; - char_type m_cThousandsSep; - }; - -public: - QmuParserInt(); - - virtual void InitFun(); - virtual void InitOprt(); - virtual void InitConst(); - virtual void InitCharSets(); -}; - -} // namespace qmu - -#endif - diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 24d0f9afd..965060cce 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -214,79 +214,6 @@ namespace qmu // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true); - // Test user defined binary operators - iStat += EqnTestInt("1 | 2", 3, true); - iStat += EqnTestInt("1 || 2", 1, true); - iStat += EqnTestInt("123 & 456", 72, true); - iStat += EqnTestInt("(123 & 456) % 10", 2, true); - iStat += EqnTestInt("1 && 0", 0, true); - iStat += EqnTestInt("123 && 456", 1, true); - iStat += EqnTestInt("1 << 3", 8, true); - iStat += EqnTestInt("8 >> 3", 1, true); - iStat += EqnTestInt("9 / 4", 2, true); - iStat += EqnTestInt("9 % 4", 1, true); - iStat += EqnTestInt("if(5%2,1,0)", 1, true); - iStat += EqnTestInt("if(4%2,1,0)", 0, true); - iStat += EqnTestInt("-10+1", -9, true); - iStat += EqnTestInt("1+2*3", 7, true); - iStat += EqnTestInt("const1 != const2", 1, true); - iStat += EqnTestInt("const1 != const2", 0, false); - iStat += EqnTestInt("const1 == const2", 0, true); - iStat += EqnTestInt("const1 == 1", 1, true); - iStat += EqnTestInt("10*(const1 == 1)", 10, true); - iStat += EqnTestInt("2*(const1 | const2)", 6, true); - iStat += EqnTestInt("2*(const1 | const2)", 7, false); - iStat += EqnTestInt("const1 < const2", 1, true); - iStat += EqnTestInt("const2 > const1", 1, true); - iStat += EqnTestInt("const1 <= 1", 1, true); - iStat += EqnTestInt("const2 >= 2", 1, true); - iStat += EqnTestInt("2*(const1 + const2)", 6, true); - iStat += EqnTestInt("2*(const1 - const2)", -2, true); - iStat += EqnTestInt("a != b", 1, true); - iStat += EqnTestInt("a != b", 0, false); - iStat += EqnTestInt("a == b", 0, true); - iStat += EqnTestInt("a == 1", 1, true); - iStat += EqnTestInt("10*(a == 1)", 10, true); - iStat += EqnTestInt("2*(a | b)", 6, true); - iStat += EqnTestInt("2*(a | b)", 7, false); - iStat += EqnTestInt("a < b", 1, true); - iStat += EqnTestInt("b > a", 1, true); - iStat += EqnTestInt("a <= 1", 1, true); - iStat += EqnTestInt("b >= 2", 1, true); - iStat += EqnTestInt("2*(a + b)", 6, true); - iStat += EqnTestInt("2*(a - b)", -2, true); - iStat += EqnTestInt("a + (a << b)", 5, true); - iStat += EqnTestInt("-2^2", -4, true); - iStat += EqnTestInt("3--a", 4, true); - iStat += EqnTestInt("3+-3^2", -6, true); - - // Test reading of hex values: - iStat += EqnTestInt("0xff", 255, true); - iStat += EqnTestInt("10+0xff", 265, true); - iStat += EqnTestInt("0xff+10", 265, true); - iStat += EqnTestInt("10*0xff", 2550, true); - iStat += EqnTestInt("0xff*10", 2550, true); - iStat += EqnTestInt("10+0xff+1", 266, true); - iStat += EqnTestInt("1+0xff+10", 266, true); - -// incorrect: '^' is your here, not power -// iStat += EqnTestInt("-(1+2)^2", -9, true); -// iStat += EqnTestInt("-1^3", -1, true); - - // Test precedence - // a=1, b=2, c=3 - iStat += EqnTestInt("a + b * c", 7, true); - iStat += EqnTestInt("a * b + c", 5, true); - iStat += EqnTestInt("a10", 0, true); - iStat += EqnTestInt("a #include // for accumulate #include "qmuparser.h" -#include "qmuparserint.h" /** \file \brief This file contains the parser test class. @@ -195,9 +194,6 @@ namespace qmu double a_fRes2, double a_fVar2); int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true); - - // Test Int Parser - int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass); }; } // namespace Test } // namespace qmu From 541a5becbd135bf94364e640056f6025df998d1e Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 10:53:10 +0300 Subject: [PATCH 09/26] Use standard math constants in tests. --HG-- branch : feature --- src/libs/qmuparser/qmuparsertest.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 965060cce..59eedf24d 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -21,15 +21,12 @@ ******************************************************************************************************/ #include "qmuparsertest.h" +#include #include -#include #include #include -#define PARSER_CONST_PI 3.141592653589793238462643 -#define PARSER_CONST_E 2.718281828459045235360287 - using namespace std; /** \file @@ -594,7 +591,7 @@ namespace qmu iStat += EqnTest( "-(-1)", 1, true); iStat += EqnTest( "-(-1)*2", 2, true); iStat += EqnTest( "-(-2)*sqrt(4)", 4, true); - iStat += EqnTest( "-_pi", -PARSER_CONST_PI, true); + iStat += EqnTest( "-_pi", -M_PI, true); iStat += EqnTest( "-a", -1, true); iStat += EqnTest( "-(a)", -1, true); iStat += EqnTest( "-(-a)", 1, true); @@ -1154,8 +1151,8 @@ namespace qmu p1.reset(new qmu::QmuParser()); // Add constants - p1->DefineConst( "pi", (qreal)PARSER_CONST_PI); - p1->DefineConst( "e", (qreal)PARSER_CONST_E); + p1->DefineConst( "pi", (qreal)M_PI); + p1->DefineConst( "e", (qreal)M_E); p1->DefineConst( "const", 1); p1->DefineConst( "const1", 2); p1->DefineConst( "const2", 3); From 5c3845ff00ffb54334332eb74434c48965a7c828 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 11:00:42 +0300 Subject: [PATCH 10/26] QVector instead std::vector. --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.cpp | 4 ++-- src/libs/qmuparser/qmuparserbase.h | 6 +++--- src/libs/qmuparser/qmuparserbytecode.h | 2 +- src/libs/qmuparser/qmuparsererror.h | 2 +- src/libs/qmuparser/qmuparsertest.cpp | 2 +- src/libs/qmuparser/qmuparsertest.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 786f4aa37..a340d882f 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -748,7 +748,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) \throw exception_type If the function token is not a string function */ QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, - const std::vector &a_vArg) const + const QVector &a_vArg) const { if (a_vArg.back().GetCode()!=cmSTRING) Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); @@ -824,7 +824,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) // Collect the numeric function arguments from the value stack and store them // in a vector - std::vector stArg; + QVector stArg; for (int i=0; i valbuf_type; + typedef QVector valbuf_type; /** \brief Type for a vector of strings. */ - typedef std::vector stringbuf_type; + typedef QVector stringbuf_type; /** \brief Typedef for the token reader. */ typedef QmuParserTokenReader token_reader_type; @@ -245,7 +245,7 @@ private: void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; token_type ApplyStrFunc(const token_type &a_FunTok, - const std::vector &a_vArg) const; + const QVector &a_vArg) const; int GetOprtPrecedence(const token_type &a_Tok) const; EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; diff --git a/src/libs/qmuparser/qmuparserbytecode.h b/src/libs/qmuparser/qmuparserbytecode.h index 3e554f15b..5e9b3db3a 100644 --- a/src/libs/qmuparser/qmuparserbytecode.h +++ b/src/libs/qmuparser/qmuparserbytecode.h @@ -90,7 +90,7 @@ private: typedef QmuParserToken token_type; /** \brief Token vector for storing the RPN. */ - typedef std::vector rpn_type; + typedef QVector rpn_type; /** \brief Position in the Calculation array. */ unsigned m_iStackPos; diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index ea51f42a0..e24ea5ae6 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -110,7 +110,7 @@ public: string_type operator[](unsigned a_iIdx) const; private: - std::vector m_vErrMsg; ///< A vector with the predefined error messages + QVector m_vErrMsg; ///< A vector with the predefined error messages static const self_type m_Instance; ///< The instance pointer }; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 59eedf24d..070b9d144 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -1228,7 +1228,7 @@ namespace qmu try { // Test copy constructor - std::vector vParser; + QVector vParser; vParser.push_back(*(p1.get())); qmu::QmuParser p2 = vParser[0]; // take parser from vector diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 79514f282..4baa0eed0 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -183,7 +183,7 @@ namespace qmu void Run(); private: - std::vector m_vTestFun; + QVector m_vTestFun; void AddTest(testfun_type a_pFun); // Test Double Parser From 9c6cac2ec44468976082a07dcb8351491af34bd4 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 11:04:59 +0300 Subject: [PATCH 11/26] Delete #include . --HG-- branch : feature --- src/libs/qmuparser/qmuparser.h | 3 --- src/libs/qmuparser/qmuparserbase.cpp | 1 - src/libs/qmuparser/qmuparserbytecode.cpp | 1 - src/libs/qmuparser/qmuparserbytecode.h | 1 - src/libs/qmuparser/qmuparsererror.h | 1 - src/libs/qmuparser/qmuparsertoken.h | 1 - 6 files changed, 8 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index b1a078597..2cadae6de 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -25,9 +25,6 @@ #include "qmuparser_global.h" -//--- Standard includes ------------------------------------------------------------------------ -#include - //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserbase.h" diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index a340d882f..0ef9e213d 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index e74b04dbe..910ae6375 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "qmuparserdef.h" diff --git a/src/libs/qmuparser/qmuparserbytecode.h b/src/libs/qmuparser/qmuparserbytecode.h index 5e9b3db3a..5cd7ceca2 100644 --- a/src/libs/qmuparser/qmuparserbytecode.h +++ b/src/libs/qmuparser/qmuparserbytecode.h @@ -26,7 +26,6 @@ #include #include #include -#include #include "qmuparserdef.h" #include "qmuparsererror.h" diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index e24ea5ae6..0413ea194 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "qmuparserdef.h" diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 404a3b3a1..20e2b51bc 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include From 7c1d22c5f49c18d20c9be11f3bb449c8e1f6adb8 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 26 Apr 2014 11:16:19 +0300 Subject: [PATCH 12/26] Try use QString where posible. --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.cpp | 24 ++++++++++++++++++------ src/libs/qmuparser/qmuparserbase.h | 13 +++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 0ef9e213d..019994ceb 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -435,7 +435,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) /** \brief Define the set of valid characters to be used in names of functions, variables, constants. */ - void QmuParserBase::DefineNameChars(const char_type *a_szCharset) + void QmuParserBase::DefineNameChars(const QString &a_szCharset) { m_sNameChars = a_szCharset; } @@ -444,7 +444,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) /** \brief Define the set of valid characters to be used in names of binary operators and postfix operators. */ - void QmuParserBase::DefineOprtChars(const char_type *a_szCharset) + void QmuParserBase::DefineOprtChars(const QString &a_szCharset) { m_sOprtChars = a_szCharset; } @@ -453,7 +453,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) /** \brief Define the set of valid characters to be used in names of infix operators. */ - void QmuParserBase::DefineInfixOprtChars(const char_type *a_szCharset) + void QmuParserBase::DefineInfixOprtChars(const QString &a_szCharset) { m_sInfixOprtChars = a_szCharset; } @@ -465,7 +465,11 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) const char_type* QmuParserBase::ValidNameChars() const { assert(m_sNameChars.size()); - return m_sNameChars.c_str(); + #if defined(_UNICODE) + return m_sNameChars.toStdWString().c_str(); + #else + return m_sNameChars.toStdString().c_str(); + #endif } //--------------------------------------------------------------------------- @@ -475,7 +479,11 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) const char_type* QmuParserBase::ValidOprtChars() const { assert(m_sOprtChars.size()); - return m_sOprtChars.c_str(); + #if defined(_UNICODE) + return m_sOprtChars.toStdWString().c_str(); + #else + return m_sOprtChars.toStdString().c_str(); + #endif } //--------------------------------------------------------------------------- @@ -485,7 +493,11 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) const char_type* QmuParserBase::ValidInfixOprtChars() const { assert(m_sInfixOprtChars.size()); - return m_sInfixOprtChars.c_str(); + #if defined(_UNICODE) + return m_sInfixOprtChars.toStdWString().c_str(); + #else + return m_sInfixOprtChars.toStdString().c_str(); + #endif } //--------------------------------------------------------------------------- diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 73d23b5f1..73e7b1c16 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -31,6 +31,7 @@ #include #include #include +#include //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserdef.h" @@ -160,9 +161,9 @@ private: string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const; const char_type ** GetOprtDef() const; - void DefineNameChars(const char_type *a_szCharset); - void DefineOprtChars(const char_type *a_szCharset); - void DefineInfixOprtChars(const char_type *a_szCharset); + void DefineNameChars(const QString &a_szCharset); + void DefineOprtChars(const QString &a_szCharset); + void DefineInfixOprtChars(const QString &a_szCharset); const char_type* ValidNameChars() const; const char_type* ValidOprtChars() const; @@ -285,9 +286,9 @@ private: bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off - string_type m_sNameChars; ///< Charset for names - string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens - string_type m_sInfixOprtChars; ///< Charset for infix operator tokens + QString m_sNameChars; ///< Charset for names + QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens + QString m_sInfixOprtChars; ///< Charset for infix operator tokens mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses From 0b49785255cb22656d96bf218e697d22f59d40b6 Mon Sep 17 00:00:00 2001 From: dismine Date: Mon, 28 Apr 2014 21:41:38 +0300 Subject: [PATCH 13/26] First success build after all changes. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 9 +- src/libs/qmuparser/qmuparser.h | 2 +- src/libs/qmuparser/qmuparserbase.cpp | 207 +++++++++-------- src/libs/qmuparser/qmuparserbase.h | 59 ++--- src/libs/qmuparser/qmuparserbytecode.cpp | 82 +++---- src/libs/qmuparser/qmuparsercallback.h | 2 +- src/libs/qmuparser/qmuparserdef.h | 67 ++---- src/libs/qmuparser/qmuparsererror.cpp | 78 +++---- src/libs/qmuparser/qmuparsererror.h | 39 ++-- src/libs/qmuparser/qmuparsertest.cpp | 142 ++++++------ src/libs/qmuparser/qmuparsertest.h | 49 ++-- src/libs/qmuparser/qmuparsertokenreader.cpp | 244 ++++++++++++-------- src/libs/qmuparser/qmuparsertokenreader.h | 24 +- 13 files changed, 496 insertions(+), 508 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 2517cd8fb..bfcf74bdf 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -166,11 +166,16 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc) \param [out] a_fVal Pointer where the value should be stored in case one is found. \return 1 if a value was found 0 otherwise. */ - int QmuParser::IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal) + int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) { qreal fVal(0); - stringstream_type stream(a_szExpr); +#if defined(_UNICODE) + std::wstring a_szExprStd = a_szExpr.toStdWString(); +#else + std::string a_szExprStd = a_szExpr.toStdString(); +#endif + stringstream_type stream(a_szExprStd); stream.seekg(0); // todo: check if this really is necessary stream.imbue(QmuParser::s_locale); stream >> fVal; diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 2cadae6de..e0b44d06a 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -83,7 +83,7 @@ protected: static qreal Min(const qreal*, int); // minimum static qreal Max(const qreal*, int); // maximum - static int IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal); + static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); }; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 019994ceb..7b7d1e9c3 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -53,15 +53,9 @@ namespace qmu When defining custom binary operators with #AddOprt(...) make sure not to choose names conflicting with these definitions. */ - const char_type* QmuParserBase::c_DefaultOprt[] = - { - "<=", ">=", "!=", - "==", "<", ">", - "+", "-", "*", - "/", "^", "&&", - "||", "=", "(", - ")", "?", ":", 0 - }; + const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" << "+" + << "-" << "*" << "/" << "^" << "&&" << "||" << "=" + << "(" << ")" << "?" << ":"; //------------------------------------------------------------------------------ /** \brief Constructor. @@ -247,7 +241,7 @@ namespace qmu } //--------------------------------------------------------------------------- - void QmuParserBase::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) + void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) {} //--------------------------------------------------------------------------- @@ -329,10 +323,10 @@ namespace qmu //--------------------------------------------------------------------------- /** \brief Add a function or operator callback to the parser. */ - void QmuParserBase::AddCallback(const string_type &a_strName, + void QmuParserBase::AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage, - const char_type *a_szCharSet ) + const QString &a_szCharSet ) { if (a_Callback.GetAddr()==0) Error(ecINVALID_FUN_PTR); @@ -362,13 +356,19 @@ namespace qmu \throw ParserException if the name contains invalid charakters. */ - void QmuParserBase::CheckOprt(const string_type &a_sName, + void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const string_type &a_szCharSet) const + const QString &a_szCharSet) const { - if ( !a_sName.length() || - (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) || - (a_sName[0]>='0' && a_sName[0]<='9')) +#if defined(_UNICODE) + const std::wstring a_sNameStd = a_sName.toStdWString(); + const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); +#else + const std::string a_sNameStd = a_sName.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9')) { switch(a_Callback.GetCode()) { @@ -379,21 +379,26 @@ namespace qmu } } - //--------------------------------------------------------------------------- - /** \brief Check if a name contains invalid characters. +//--------------------------------------------------------------------------- +/** \brief Check if a name contains invalid characters. - \throw ParserException if the name contains invalid charakters. - */ - void QmuParserBase::CheckName(const string_type &a_sName, - const string_type &a_szCharSet) const - { - if ( !a_sName.length() || - (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) || - (a_sName[0]>='0' && a_sName[0]<='9')) + \throw ParserException if the name contains invalid charakters. +*/ +void QmuParserBase::CheckName(const QString &a_sName, const QString &a_szCharSet) const +{ + #if defined(_UNICODE) + std::wstring a_sNameStd = a_sName.toStdWString(); + std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); + #else + std::string a_sNameStd = a_sName.toStdString(); + std::string a_szCharSetStd = a_szCharSet.toStdString(); + #endif + if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd[0]>='0' && a_sNameStd[0]<='9')) { - Error(ecINVALID_NAME); + Error(ecINVALID_NAME); } - } +} //--------------------------------------------------------------------------- /** \brief Set the formula. @@ -403,7 +408,7 @@ namespace qmu Triggers first time calculation thus the creation of the bytecode and scanning of used variables. */ -void QmuParserBase::SetExpr(const string_type &a_sExpr) +void QmuParserBase::SetExpr(const QString &a_sExpr) { // Check locale compatibility std::locale loc; @@ -415,9 +420,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) // 20060222: Bugfix for Borland-Kylix: // adding a space to the expression will keep Borlands KYLIX from going wild // when calling tellg on a stringstream created from the expression after - // reading a value at the end of an expression. (mu::Parser::IsVal function) + // reading a value at the end of an expression. (qmu::QmuParser::IsVal function) // (tellg returns -1 otherwise causing the parser to ignore the value) - string_type sBuf(a_sExpr + " " ); + QString sBuf(a_sExpr + " " ); m_pTokenReader->SetFormula(sBuf); ReInit(); } @@ -426,9 +431,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) /** \brief Get the default symbols used for the built in operators. \sa c_DefaultOprt */ - const char_type** QmuParserBase::GetOprtDef() const + const QStringList &QmuParserBase::GetOprtDef() const { - return (const char_type **)(&c_DefaultOprt[0]); + return c_DefaultOprt; } //--------------------------------------------------------------------------- @@ -458,53 +463,41 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) m_sInfixOprtChars = a_szCharset; } - //--------------------------------------------------------------------------- - /** \brief Virtual function that defines the characters allowed in name identifiers. - \sa #ValidOprtChars, #ValidPrefixOprtChars - */ - const char_type* QmuParserBase::ValidNameChars() const - { +//--------------------------------------------------------------------------- +/** \brief Virtual function that defines the characters allowed in name identifiers. + \sa #ValidOprtChars, #ValidPrefixOprtChars +*/ +const QString& QmuParserBase::ValidNameChars() const +{ assert(m_sNameChars.size()); - #if defined(_UNICODE) - return m_sNameChars.toStdWString().c_str(); - #else - return m_sNameChars.toStdString().c_str(); - #endif - } + return m_sNameChars; +} //--------------------------------------------------------------------------- /** \brief Virtual function that defines the characters allowed in operator definitions. \sa #ValidNameChars, #ValidPrefixOprtChars */ - const char_type* QmuParserBase::ValidOprtChars() const + const QString &QmuParserBase::ValidOprtChars() const { assert(m_sOprtChars.size()); - #if defined(_UNICODE) - return m_sOprtChars.toStdWString().c_str(); - #else - return m_sOprtChars.toStdString().c_str(); - #endif + return m_sOprtChars; } //--------------------------------------------------------------------------- /** \brief Virtual function that defines the characters allowed in infix operator definitions. \sa #ValidNameChars, #ValidOprtChars */ - const char_type* QmuParserBase::ValidInfixOprtChars() const + const QString &QmuParserBase::ValidInfixOprtChars() const { assert(m_sInfixOprtChars.size()); - #if defined(_UNICODE) - return m_sInfixOprtChars.toStdWString().c_str(); - #else - return m_sInfixOprtChars.toStdString().c_str(); - #endif + return m_sInfixOprtChars; } //--------------------------------------------------------------------------- /** \brief Add a user defined operator. \post Will reset the Parser to string parsing mode. */ - void QmuParserBase::DefinePostfixOprt(const string_type &a_sName, + void QmuParserBase::DefinePostfixOprt(const QString &a_sName, fun_type1 a_pFun, bool a_bAllowOpt) { @@ -536,7 +529,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) \param [in] a_bAllowOpt True if operator is volatile (default=false) \sa EPrec */ - void QmuParserBase::DefineInfixOprt(const string_type &a_sName, + void QmuParserBase::DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec, bool a_bAllowOpt) @@ -558,7 +551,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) Adds a new Binary operator the the parser instance. */ - void QmuParserBase::DefineOprt( const string_type &a_sName, + void QmuParserBase::DefineOprt( const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec, EOprtAssociativity a_eAssociativity, @@ -566,8 +559,12 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) { // Check for conflicts with built in operator names for (int i=0; m_bBuiltInOp && iGetExpr(); } @@ -1129,9 +1132,9 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) switch(pTok->Fun.argc) // switch according to argument count { - case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue; - case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue; - case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue; + case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); continue; + case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); continue; + case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx], Stack[sidx+1]); continue; } continue; @@ -1448,7 +1451,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) \param a_strTok [in] The token string representation associated with the error. \throw ParserException always throws thats the only purpose of this function. */ - void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const + void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const { throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); } @@ -1471,7 +1474,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) Removes a variable if it exists. If the Variable does not exist nothing will be done. */ - void QmuParserBase::RemoveVar(const string_type &a_strVarName) + void QmuParserBase::RemoveVar(const QString &a_strVarName) { varmap_type::iterator item = m_VarDef.find(a_strVarName); if (item!=m_VarDef.end()) @@ -1592,7 +1595,7 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) //------------------------------------------------------------------------------ /** \brief Get the argument separator character. */ - char_type QmuParserBase::GetArgSep() const + QChar QmuParserBase::GetArgSep() const { return m_pTokenReader->GetArgSep(); } @@ -1617,22 +1620,22 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) QStack stOprt(a_stOprt), stVal(a_stVal); - qmu::console() << "\nValue stack:\n"; + qDebug() << "\nValue stack:\n"; while ( !stVal.empty() ) { token_type val = stVal.pop(); if (val.GetType()==tpSTR) - qmu::console() << " \"" << val.GetAsString() << "\" "; + qDebug() << " \"" << val.GetAsString() << "\" "; else - qmu::console() << " " << val.GetVal() << " "; + qDebug() << " " << val.GetVal() << " "; } - qmu::console() << "\nOperator stack:\n"; + qDebug() << "\nOperator stack:\n"; while ( !stOprt.empty() ) { if (stOprt.top().GetCode()<=cmASSIGN) { - qmu::console() << "OPRT_INTRNL \"" + qDebug() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << "\" \n"; } @@ -1640,35 +1643,35 @@ void QmuParserBase::SetExpr(const string_type &a_sExpr) { switch(stOprt.top().GetCode()) { - case cmVAR: qmu::console() << "VAR\n"; break; - case cmVAL: qmu::console() << "VAL\n"; break; - case cmFUNC: qmu::console() << "FUNC \"" + case cmVAR: qDebug() << "VAR\n"; break; + case cmVAL: qDebug() << "VAL\n"; break; + case cmFUNC: qDebug() << "FUNC \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmFUNC_BULK: qmu::console() << "FUNC_BULK \"" + case cmFUNC_BULK: qDebug() << "FUNC_BULK \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmOPRT_INFIX: qmu::console() << "OPRT_INFIX \"" + case cmOPRT_INFIX: qDebug() << "OPRT_INFIX \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmOPRT_BIN: qmu::console() << "OPRT_BIN \"" + case cmOPRT_BIN: qDebug() << "OPRT_BIN \"" << stOprt.top().GetAsString() << "\"\n"; break; - case cmFUNC_STR: qmu::console() << "FUNC_STR\n"; break; - case cmEND: qmu::console() << "END\n"; break; - case cmUNKNOWN: qmu::console() << "UNKNOWN\n"; break; - case cmBO: qmu::console() << "BRACKET \"(\"\n"; break; - case cmBC: qmu::console() << "BRACKET \")\"\n"; break; - case cmIF: qmu::console() << "IF\n"; break; - case cmELSE: qmu::console() << "ELSE\n"; break; - case cmENDIF: qmu::console() << "ENDIF\n"; break; - default: qmu::console() << stOprt.top().GetCode() << " "; break; + case cmFUNC_STR: qDebug() << "FUNC_STR\n"; break; + case cmEND: qDebug() << "END\n"; break; + case cmUNKNOWN: qDebug() << "UNKNOWN\n"; break; + case cmBO: qDebug() << "BRACKET \"(\"\n"; break; + case cmBC: qDebug() << "BRACKET \")\"\n"; break; + case cmIF: qDebug() << "IF\n"; break; + case cmELSE: qDebug() << "ELSE\n"; break; + case cmENDIF: qDebug() << "ENDIF\n"; break; + default: qDebug() << stOprt.top().GetCode() << " "; break; } } stOprt.pop(); } - qmu::console() << dec << endl; + qDebug() << dec; } //------------------------------------------------------------------------------ diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 73e7b1c16..ab1bbc2b8 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -32,6 +32,7 @@ #include #include #include +#include //--- Parser includes -------------------------------------------------------------------------- #include "qmuparserdef.h" @@ -75,13 +76,13 @@ private: typedef QVector valbuf_type; /** \brief Type for a vector of strings. */ - typedef QVector stringbuf_type; + typedef QVector stringbuf_type; /** \brief Typedef for the token reader. */ typedef QmuParserTokenReader token_reader_type; /** \brief Type used for parser tokens. */ - typedef QmuParserToken token_type; + typedef QmuParserToken token_type; /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */ static const int s_MaxNumOpenMPThreads = 4; @@ -108,7 +109,7 @@ private: int GetNumResults() const; - void SetExpr(const string_type &a_sExpr); + void SetExpr(const QString &a_sExpr); void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); void SetDecSep(char_type cDecSep); @@ -128,21 +129,21 @@ private: \param a_bAllowOpt A flag indicating this function may be optimized */ template - void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true) + void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) { AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); } - void DefineOprt(const string_type &a_strName, - fun_type2 a_pFun, - unsigned a_iPri=0, + void DefineOprt(const QString &a_strName, + fun_type2 a_pFun, + unsigned a_iPri=0, EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); - void DefineConst(const string_type &a_sName, qreal a_fVal); - void DefineStrConst(const string_type &a_sName, const string_type &a_strVal); - void DefineVar(const string_type &a_sName, qreal *a_fVar); - void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); - void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); + void DefineConst(const QString &a_sName, qreal a_fVal); + void DefineStrConst(const QString &a_sName, const QString &a_strVal); + void DefineVar(const QString &a_sName, qreal *a_fVar); + void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); + void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); // Clear user defined variables, constants or functions void ClearVar(); @@ -152,29 +153,29 @@ private: void ClearPostfixOprt(); void ClearOprt(); - void RemoveVar(const string_type &a_strVarName); + void RemoveVar(const QString &a_strVarName); const varmap_type& GetUsedVar() const; const varmap_type& GetVar() const; const valmap_type& GetConst() const; - const string_type& GetExpr() const; + const QString &GetExpr() const; const funmap_type& GetFunDef() const; string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const; - const char_type ** GetOprtDef() const; + const QStringList &GetOprtDef() const; void DefineNameChars(const QString &a_szCharset); void DefineOprtChars(const QString &a_szCharset); void DefineInfixOprtChars(const QString &a_szCharset); - const char_type* ValidNameChars() const; - const char_type* ValidOprtChars() const; - const char_type* ValidInfixOprtChars() const; + const QString& ValidNameChars() const; + const QString &ValidOprtChars() const; + const QString &ValidInfixOprtChars() const; void SetArgSep(char_type cArgSep); - char_type GetArgSep() const; + QChar GetArgSep() const; - void Error(EErrorCodes a_iErrc, - int a_iPos = (int)qmu::string_type::npos, - const string_type &a_strTok = string_type() ) const; + void Error(EErrorCodes a_iErrc, + int a_iPos = -1, + const QString &a_strTok = QString() ) const; protected: @@ -185,9 +186,9 @@ private: virtual void InitConst() = 0; virtual void InitOprt() = 0; - virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd); - static const char_type *c_DefaultOprt[]; + static const QStringList c_DefaultOprt; static std::locale s_locale; ///< The locale used by the parser static bool g_DbgDumpCmdCode; static bool g_DbgDumpStack; @@ -235,10 +236,10 @@ private: void InitTokenReader(); void ReInit() const; - void AddCallback( const string_type &a_strName, + void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage, - const char_type *a_szCharSet ); + const QString &a_szCharSet ); void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; @@ -257,10 +258,10 @@ private: qreal ParseCmdCode() const; qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; - void CheckName(const string_type &a_strName, const string_type &a_CharSet) const; - void CheckOprt(const string_type &a_sName, + void CheckName(const QString &a_strName, const QString &a_CharSet) const; + void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const string_type &a_szCharSet) const; + const QString &a_szCharSet) const; void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 910ae6375..5665417f3 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "qmuparserdef.h" #include "qmuparsererror.h" @@ -492,89 +493,76 @@ namespace qmu { if (!m_vRPN.size()) { - qmu::console() << "No bytecode available\n"; + qDebug() << "No bytecode available\n"; return; } - qmu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n"; + qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n"; for (std::size_t i=0; i funmap_type; +typedef std::map funmap_type; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 2ad34d556..0ecb3ac4a 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "qmuparserfixes.h" @@ -49,54 +51,15 @@ //#define MUP_USE_OPENMP #if defined(_UNICODE) - /** \brief Definition of the basic parser string type. */ - #define MUP_STRING_TYPE std::wstring - + /** \brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::wstring #else - - /** \brief Definition of the basic parser string type. */ - #define MUP_STRING_TYPE std::string + /** \brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::string #endif namespace qmu { -#if defined(_UNICODE) - - //------------------------------------------------------------------------------ - /** \brief Encapsulate wcout. */ - inline std::wostream& console() - { - return std::wcout; - } - - /** \brief Encapsulate cin. */ - inline std::wistream& console_in() - { - return std::wcin; - } - -#else - - /** \brief Encapsulate cout. - - Used for supporting UNICODE more easily. - */ - inline std::ostream& console() - { - return std::cout; - } - - /** \brief Encapsulate cin. - - Used for supporting UNICODE more easily. - */ - inline std::istream& console_in() - { - return std::cin; - } - -#endif - //------------------------------------------------------------------------------ /** \brief Bytecode values. @@ -200,7 +163,7 @@ namespace qmu Depends on wether UNICODE is used or not. */ - typedef MUP_STRING_TYPE string_type; + typedef QMUP_STRING_TYPE string_type; /** \brief The character type used by the parser. @@ -216,13 +179,13 @@ namespace qmu // Data container types /** \brief Type used for storing variables. */ - typedef std::map varmap_type; + typedef std::map varmap_type; /** \brief Type used for storing constants. */ - typedef std::map valmap_type; + typedef std::map valmap_type; /** \brief Type for assigning a string name to an index in the internal string table. */ - typedef std::map strmap_type; + typedef std::map strmap_type; // Parser callbacks @@ -299,19 +262,19 @@ namespace qmu typedef qreal (*multfun_type)(const qreal*, int); /** \brief Callback type used for functions taking a string as an argument. */ - typedef qreal (*strfun_type1)(const char_type*); + typedef qreal (*strfun_type1)(const QString &); /** \brief Callback type used for functions taking a string and a value as arguments. */ - typedef qreal (*strfun_type2)(const char_type*, qreal); + typedef qreal (*strfun_type2)(const QString &, qreal); /** \brief Callback type used for functions taking a string and two values as arguments. */ - typedef qreal (*strfun_type3)(const char_type*, qreal, qreal); + typedef qreal (*strfun_type3)(const QString &, qreal, qreal); /** \brief Callback used for functions that identify values in a string. */ - typedef int (*identfun_type)(const char_type *sExpr, int *nPos, qreal *fVal); + typedef int (*identfun_type)(const QString &sExpr, int *nPos, qreal *fVal); /** \brief Callback used for variable creation factory functions. */ - typedef qreal* (*facfun_type)(const char_type*, void*); + typedef qreal* (*facfun_type)(const QString &, void*); } // end of namespace #endif diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index c909f57c5..c073b68ea 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -22,6 +22,8 @@ #include "qmuparsererror.h" +#include + namespace qmu { @@ -34,9 +36,9 @@ namespace qmu } //------------------------------------------------------------------------------ - string_type QmuParserErrorMsg::operator[](unsigned a_iIdx) const + QString QmuParserErrorMsg::operator[](unsigned a_iIdx) const { - return (a_iIdx m_vErrMsg; ///< A vector with the predefined error messages + QVector m_vErrMsg; ///< A vector with the predefined error messages static const self_type m_Instance; ///< The instance pointer }; @@ -124,41 +124,34 @@ class QmuParserError private: /** \brief Replace all ocuurences of a substring with another string. */ - void ReplaceSubString( string_type &strSource, - const string_type &strFind, - const string_type &strReplaceWith); + void ReplaceSubString(QString &strSource, + const QString &strFind, + const QString &strReplaceWith); void Reset(); public: QmuParserError(); explicit QmuParserError(EErrorCodes a_iErrc); - explicit QmuParserError(const string_type &sMsg); - QmuParserError( EErrorCodes a_iErrc, - const string_type &sTok, - const string_type &sFormula = string_type(), - int a_iPos = -1); - QmuParserError( EErrorCodes a_iErrc, - int a_iPos, - const string_type &sTok); - QmuParserError( const char_type *a_szMsg, - int a_iPos = -1, - const string_type &sTok = string_type()); + explicit QmuParserError(const QString &sMsg); + QmuParserError( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1); + QmuParserError(EErrorCodes a_iErrc, int a_iPos, const QString &sTok); + QmuParserError(const QString &a_szMsg, int a_iPos, const QString &sTok = QString()); QmuParserError(const QmuParserError &a_Obj); QmuParserError& operator=(const QmuParserError &a_Obj); ~QmuParserError(); - void SetFormula(const string_type &a_strFormula); - const string_type& GetExpr() const; - const string_type& GetMsg() const; + void SetFormula(const QString &a_strFormula); + const QString &GetExpr() const; + const QString &GetMsg() const; std::size_t GetPos() const; - const string_type& GetToken() const; + const QString &GetToken() const; EErrorCodes GetCode() const; private: - string_type m_strMsg; ///< The message string - string_type m_strFormula; ///< Formula string - string_type m_strTok; ///< Token related with the error + QString m_strMsg; ///< The message string + QString m_strFormula; ///< Formula string + QString m_strTok; ///< Token related with the error int m_iPos; ///< Formula position related to the error EErrorCodes m_iErrc; ///< Error code const QmuParserErrorMsg &m_ErrMsg; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 070b9d144..d4d22919a 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -22,6 +22,7 @@ #include "qmuparsertest.h" #include +#include #include #include @@ -60,32 +61,37 @@ namespace qmu } //--------------------------------------------------------------------------------------------- - int QmuParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal) + int QmuParserTester::IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) { if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) return 0; unsigned iVal(0); + bool ok = false; + iVal = a_szExpr.toUInt(&ok, 16); - // New code based on streams for UNICODE compliance: - stringstream_type::pos_type nPos(0); - stringstream_type ss(a_szExpr + 2); - ss >> std::hex >> iVal; - nPos = ss.tellg(); + if(ok) + { + int nPos = a_szExpr.indexOf(QString().setNum(iVal, 16)); + if(nPos == 0) + return 1; - if (nPos==(stringstream_type::pos_type)0) + *a_iPos += (int)(2 + nPos); + *a_fVal = (qreal)iVal; return 1; + } + else + { + return 0; + } - *a_iPos += (int)(2 + nPos); - *a_fVal = (qreal)iVal; - return 1; } //--------------------------------------------------------------------------------------------- int QmuParserTester::TestInterface() { int iStat = 0; - qmu::console() << "testing member functions..."; + qDebug() << "testing member functions..."; // Test RemoveVar qreal afVal[3] = {1,2,3}; @@ -116,9 +122,9 @@ namespace qmu } if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -127,7 +133,7 @@ namespace qmu int QmuParserTester::TestStrArg() { int iStat = 0; - qmu::console() << "testing string arguments..."; + qDebug() << "testing string arguments..."; iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true); @@ -141,9 +147,9 @@ namespace qmu iStat += EqnTest("strfun3(\"99\",1,2)", 102, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -152,7 +158,7 @@ namespace qmu int QmuParserTester::TestBinOprt() { int iStat = 0; - qmu::console() << "testing binary operators..."; + qDebug() << "testing binary operators..."; // built in operators // xor operator @@ -212,9 +218,9 @@ namespace qmu iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -226,7 +232,7 @@ namespace qmu int iStat= 0, iErr = 0; - qmu::console() << "testing name restriction enforcement..."; + qDebug() << "testing name restriction enforcement..."; QmuParser p; @@ -321,9 +327,9 @@ namespace qmu #undef PARSER_THROWCHECK if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -332,7 +338,7 @@ namespace qmu int QmuParserTester::TestSyntax() { int iStat = 0; - qmu::console() << "testing syntax engine..."; + qDebug() << "testing syntax engine..."; iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition @@ -370,9 +376,9 @@ namespace qmu iStat += EqnTest("sin()", 0, false); // unexpected closing bracket if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -381,7 +387,7 @@ namespace qmu int QmuParserTester::TestVarConst() { int iStat = 0; - qmu::console() << "testing variable/constant detection..."; + qDebug() << "testing variable/constant detection..."; // Test if the result changes when a variable changes iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 ); @@ -479,9 +485,9 @@ namespace qmu } if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -490,7 +496,7 @@ namespace qmu int QmuParserTester::TestMultiArg() { int iStat = 0; - qmu::console() << "testing multiarg functions..."; + qDebug() << "testing multiarg functions..."; // Compound expressions iStat += EqnTest( "1,2,3", 3, true); @@ -573,9 +579,9 @@ namespace qmu iStat += EqnTest( "sum(,1,2)", 0, false); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -585,7 +591,7 @@ namespace qmu int QmuParserTester::TestInfixOprt() { int iStat(0); - qmu::console() << "testing infix operators..."; + qDebug() << "testing infix operators..."; iStat += EqnTest( "-1", -1, true); iStat += EqnTest( "-(-1)", 1, true); @@ -638,9 +644,9 @@ namespace qmu iStat += EqnTest( "~~ 123", 123+2, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -650,7 +656,7 @@ namespace qmu int QmuParserTester::TestPostFix() { int iStat = 0; - qmu::console() << "testing postfix operators..."; + qDebug() << "testing postfix operators..."; // application iStat += EqnTest( "3{m}+5", 5.003, true); @@ -690,9 +696,9 @@ namespace qmu iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -701,7 +707,7 @@ namespace qmu int QmuParserTester::TestExpression() { int iStat = 0; - qmu::console() << "testing expression samples..."; + qDebug() << "testing expression samples..."; qreal b = 2; @@ -770,9 +776,9 @@ namespace qmu iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -783,7 +789,7 @@ namespace qmu int QmuParserTester::TestIfThenElse() { int iStat = 0; - qmu::console() << "testing if-then-else operator..."; + qDebug() << "testing if-then-else operator..."; // Test error detection iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL); @@ -878,9 +884,9 @@ namespace qmu iStat += EqnTest("a=0?5:b=1?3:4, b", 3, true); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed"; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors"; return iStat; } @@ -889,7 +895,7 @@ namespace qmu int QmuParserTester::TestException() { int iStat = 0; - qmu::console() << "testing error codes..."; + qDebug() << "testing error codes..."; iStat += ThrowTest("3+", ecUNEXPECTED_EOF); iStat += ThrowTest("3+)", ecUNEXPECTED_PARENS); @@ -972,9 +978,9 @@ namespace qmu iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT); if (iStat==0) - qmu::console() << "passed" << endl; + qDebug() << "passed" ; else - qmu::console() << "\n failed with " << iStat << " errors" << endl; + qDebug() << "\n failed with " << iStat << " errors" ; return iStat; } @@ -997,37 +1003,37 @@ namespace qmu } catch(QmuParser::exception_type &e) { - qmu::console() << "\n" << e.GetMsg() << endl; - qmu::console() << e.GetToken() << endl; + qDebug() << "\n" << e.GetMsg() ; + qDebug() << e.GetToken() ; Abort(); } catch(std::exception &e) { - qmu::console() << e.what() << endl; + qDebug() << e.what() ; Abort(); } catch(...) { - qmu::console() << "Internal error"; + qDebug() << "Internal error"; Abort(); } if (iStat==0) { - qmu::console() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" << endl; + qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" ; } else { - qmu::console() << "Test failed with " << iStat + qDebug() << "Test failed with " << iStat << " errors (" << QmuParserTester::c_iCount - << " expressions)" << endl; + << " expressions)" ; } QmuParserTester::c_iCount = 0; } //--------------------------------------------------------------------------- - int QmuParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail) + int QmuParserTester::ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail) { QmuParserTester::c_iCount++; @@ -1054,7 +1060,7 @@ namespace qmu // output the formula in case of an failed test if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) { - qmu::console() << "\n " + qDebug() << "\n " << "Expression: " << a_str << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" << " Expected:" << a_iErrc; @@ -1067,7 +1073,7 @@ namespace qmu bool bRet((a_bFail==false) ? 0 : 1); if (bRet==1) { - qmu::console() << "\n " + qDebug() << "\n " << "Expression: " << a_str << " did evaluate; Expected error:" << a_iErrc; } @@ -1080,7 +1086,7 @@ namespace qmu \return 1 in case of a failure, 0 otherwise. */ - int QmuParserTester::EqnTestWithVarChange(const string_type &a_str, + int QmuParserTester::EqnTestWithVarChange(const QString &a_str, double a_fVar1, double a_fRes1, double a_fVar2, @@ -1112,17 +1118,17 @@ namespace qmu } catch(QmuParser::exception_type &e) { - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; return 1; } catch(std::exception &e) { - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1134,7 +1140,7 @@ namespace qmu \return 1 in case of a failure, 0 otherwise. */ - int QmuParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) + int QmuParserTester::EqnTest(const QString &a_str, double a_fRes, bool a_fPass) { QmuParserTester::c_iCount++; int iRet(0); @@ -1253,7 +1259,7 @@ namespace qmu } catch(std::exception &e) { - qmu::console() << "\n " << e.what() << "\n"; + qDebug() << "\n " << e.what() << "\n"; } // limited floating point accuracy requires the following test @@ -1274,7 +1280,7 @@ namespace qmu if (iRet==1) { - qmu::console() << "\n fail: " << a_str.c_str() + qDebug() << "\n fail: " << a_str << " (incorrect result; expected: " << a_fRes << " ;calculated: " << fVal[0] << "," << fVal[1] << "," @@ -1288,20 +1294,20 @@ namespace qmu if (a_fPass) { if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) - qmu::console() << "\n fail: " << a_str.c_str() << " (copy construction)"; + qDebug() << "\n fail: " << a_str << " (copy construction)"; else - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.GetMsg() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; return 1; } } catch(std::exception &e) { - qmu::console() << "\n fail: " << a_str.c_str() << " (" << e.what() << ")"; + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; return 1; // always return a failure since this exception is not expected } catch(...) { - qmu::console() << "\n fail: " << a_str.c_str() << " (unexpected exception)"; + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; return 1; // exceptions other than ParserException are not allowed } @@ -1312,7 +1318,7 @@ namespace qmu /** \brief Internal error in test class Test is going to be aborted. */ void QmuParserTester::Abort() const { - qmu::console() << "Test failed (internal error in test class)" << endl; + qDebug() << "Test failed (internal error in test class)" ; while (!getchar()); exit(-1); } diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 4baa0eed0..b92338b3f 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -27,6 +27,7 @@ #include #include // for accumulate #include "qmuparser.h" +#include /** \file \brief This file contains the parser test class. @@ -48,14 +49,14 @@ namespace qmu static int c_iCount; // Multiarg callbacks - static qreal f1of1(qreal v) { return v;}; + static qreal f1of1(qreal v) { return v;} - static qreal f1of2(qreal v, qreal ) {return v;}; - static qreal f2of2(qreal , qreal v) {return v;}; + static qreal f1of2(qreal v, qreal ) {return v;} + static qreal f2of2(qreal , qreal v) {return v;} - static qreal f1of3(qreal v, qreal , qreal ) {return v;}; - static qreal f2of3(qreal , qreal v, qreal ) {return v;}; - static qreal f3of3(qreal , qreal , qreal v) {return v;}; + static qreal f1of3(qreal v, qreal , qreal ) {return v;} + static qreal f2of3(qreal , qreal v, qreal ) {return v;} + static qreal f3of3(qreal , qreal , qreal v) {return v;} static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;} static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;} @@ -120,36 +121,32 @@ namespace qmu return 10; } - static qreal ValueOf(const char_type*) + static qreal ValueOf(const QString &) { return 123; } - static qreal StrFun1(const char_type* v1) + static qreal StrFun1(const QString & v1) { - int val(0); - stringstream_type(v1) >> val; + int val = v1.toInt(); return (qreal)val; } - static qreal StrFun2(const char_type* v1, qreal v2) + static qreal StrFun2(const QString & v1, qreal v2) { - int val(0); - stringstream_type(v1) >> val; + int val = v1.toInt(); return (qreal)(val + v2); } - static qreal StrFun3(const char_type* v1, qreal v2, qreal v3) + static qreal StrFun3(const QString & v1, qreal v2, qreal v3) { - int val(0); - stringstream_type(v1) >> val; + int val = v1.toInt(); return val + v2 + v3; } - static qreal StrToFloat(const char_type* a_szMsg) + static qreal StrToFloat(const QString & a_szMsg) { - qreal val(0); - stringstream_type(a_szMsg) >> val; + qreal val = a_szMsg.toDouble(); return val; } @@ -159,7 +156,7 @@ namespace qmu static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; } // Custom value recognition - static int IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal); + static int IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); int TestNames(); int TestSyntax(); @@ -187,13 +184,13 @@ namespace qmu void AddTest(testfun_type a_pFun); // Test Double Parser - int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass); - int EqnTestWithVarChange(const string_type& a_str, - double a_fRes1, - double a_fVar1, - double a_fRes2, + int EqnTest(const QString &a_str, double a_fRes, bool a_fPass); + int EqnTestWithVarChange(const QString &a_str, + double a_fRes1, + double a_fVar1, + double a_fRes2, double a_fVar2); - int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true); + int ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail = true); }; } // namespace Test } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 24a439120..f21e80bf8 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include "qmuparsertokenreader.h" #include "qmuparserbase.h" @@ -191,7 +193,7 @@ namespace qmu \return #m_strFormula \throw nothrow */ - const string_type& QmuParserTokenReader::GetExpr() const + const QString& QmuParserTokenReader::GetExpr() const { return m_strFormula; } @@ -209,7 +211,7 @@ namespace qmu Sets the formula position index to zero and set Syntax flags to default for initial formula parsing. \pre [assert] triggered if a_szFormula==0 */ - void QmuParserTokenReader::SetFormula(const string_type &a_strFormula) + void QmuParserTokenReader::SetFormula(const QString &a_strFormula) { m_strFormula = a_strFormula; ReInit(); @@ -253,13 +255,19 @@ namespace qmu { assert(m_pParser); - std::stack FunArgs; - const char_type *szFormula = m_strFormula.c_str(); + //std::stack FunArgs; +#if defined(_UNICODE) + const char_type *szFormula = m_strFormula.toStdWString().c_str(); +#else + const char_type *szFormula = m_strFormula.toStdString().c_str(); +#endif token_type tok; // Ignore all non printable characters when reading the expression while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20) + { ++m_iPos; + } if ( IsEOF(tok) ) return SaveBeforeReturn(tok); // Check for end of formula if ( IsOprt(tok) ) return SaveBeforeReturn(tok); // Check for user defined binary operator @@ -280,19 +288,23 @@ namespace qmu // (The GetUsedVar function must suppress the error for // undefined variables in order to collect all variable // names including the undefined ones.) - if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) + if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) + { return SaveBeforeReturn(tok); + } // Check for unknown token // // !!! From this point on there is no exit without an exception possible... // - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd!=m_iPos) + { Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok); + } - Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos)); + Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid(m_iPos)); return token_type(); // never reached } @@ -309,59 +321,86 @@ namespace qmu m_pConstDef = &a_pParent->m_ConstDef; } - //--------------------------------------------------------------------------- - /** \brief Extract all characters that belong to a certain charset. +//--------------------------------------------------------------------------- +/** \brief Extract all characters that belong to a certain charset. - \param a_szCharSet [in] Const char array of the characters allowed in the token. - \param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. - \param a_iPos [in] Position in the string from where to start reading. - \return The Position of the first character not listed in a_szCharSet. - \throw nothrow - */ - int QmuParserTokenReader::ExtractToken(const char_type *a_szCharSet, - string_type &a_sTok, - int a_iPos) const - { - int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos); +\param a_szCharSet [in] Const char array of the characters allowed in the token. +\param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. +\param a_iPos [in] Position in the string from where to start reading. +\return The Position of the first character not listed in a_szCharSet. +\throw nothrow +*/ +int QmuParserTokenReader::ExtractToken(const QString &a_szCharSet, QString &a_sTok, int a_iPos) const +{ +#if defined(_UNICODE) + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); +#else + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + + int iEnd = (int)m_strFormulaStd.find_first_not_of(a_szCharSetStd, a_iPos); if (iEnd==(int)string_type::npos) - iEnd = (int)m_strFormula.length(); - - // Assign token string if there was something found - if (a_iPos!=iEnd) - a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd); - - return iEnd; - } - - //--------------------------------------------------------------------------- - /** \brief Check Expression for the presence of a binary operator token. - - Userdefined binary operator "++" gives inconsistent parsing result for - the equations "a++b" and "a ++ b" if alphabetic characters are allowed - in operator tokens. To avoid this this function checks specifically - for operator tokens. - */ - int QmuParserTokenReader::ExtractOperatorToken(string_type &a_sTok, - int a_iPos) const - { - int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos); - if (iEnd==(int)string_type::npos) - iEnd = (int)m_strFormula.length(); + { + iEnd = (int)m_strFormulaStd.length(); + } // Assign token string if there was something found if (a_iPos!=iEnd) { - a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd); - return iEnd; + #if defined(_UNICODE) + a_sTok = QString().fromStdWString(std::wstring( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd)); + #else + a_sTok = QString().fromStdString(std::string( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd)); + #endif + } + + return iEnd; +} + +//--------------------------------------------------------------------------- +/** \brief Check Expression for the presence of a binary operator token. + +Userdefined binary operator "++" gives inconsistent parsing result for +the equations "a++b" and "a ++ b" if alphabetic characters are allowed +in operator tokens. To avoid this this function checks specifically +for operator tokens. +*/ +int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) const +{ +#if defined(_UNICODE) + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString(); +#else + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); +#endif + int iEnd = (int)m_strFormulaStd.find_first_not_of(oprtCharsStd, a_iPos); + if (iEnd==(int)string_type::npos) + { + iEnd = (int)m_strFormulaStd.length(); + } + + // Assign token string if there was something found + if (a_iPos!=iEnd) + { + #if defined(_UNICODE) + a_sTok = QString().fromStdWString(string_type(m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd)); + #else + a_sTok = QString().fromStdString(string_type(m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd)); + #endif + return iEnd; } else { - // There is still the chance of having to deal with an operator consisting exclusively - // of alphabetic characters. - return ExtractToken(QMUP_CHARS, a_sTok, a_iPos); + // There is still the chance of having to deal with an operator consisting exclusively + // of alphabetic characters. + return ExtractToken(QMUP_CHARS, a_sTok, a_iPos); } - } +} //--------------------------------------------------------------------------- /** \brief Check if a built in operator or other token can be found @@ -370,15 +409,14 @@ namespace qmu */ bool QmuParserTokenReader::IsBuiltIn(token_type &a_Tok) { - const char_type **const pOprtDef = m_pParser->GetOprtDef(), - *const szFormula = m_strFormula.c_str(); + const QStringList pOprtDef = m_pParser->GetOprtDef(); // Compare token with function and operator strings // check string for operator/function - for (int i=0; pOprtDef[i]; i++) + for (int i=0; i < pOprtDef.size(); ++i) { - std::size_t len( std::char_traits::length(pOprtDef[i]) ); - if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) ) + int len = pOprtDef.at(i).length(); + if ( pOprtDef.at(i) == m_strFormula.mid(m_iPos, m_iPos + len) ) { switch(i) { @@ -404,7 +442,7 @@ namespace qmu // The assignement operator need special treatment if (i==cmASSIGN && m_iSynFlags & noASSIGN) - Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i)); if (!m_pParser->HasBuiltInOprt()) continue; if (m_iSynFlags & noOPT) @@ -415,7 +453,7 @@ namespace qmu if ( IsInfixOpTok(a_Tok) ) return true; - Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i)); } m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; @@ -424,7 +462,7 @@ namespace qmu case cmBO: if (m_iSynFlags & noBO) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); if (m_lastTok.GetCode()==cmFUNC) m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; @@ -436,24 +474,24 @@ namespace qmu case cmBC: if (m_iSynFlags & noBC) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; if (--m_iBrackets<0) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); break; case cmELSE: if (m_iSynFlags & noELSE) - Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i)); m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; break; case cmIF: if (m_iSynFlags & noIF) - Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]); + Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i)); m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; break; @@ -462,8 +500,8 @@ namespace qmu Error(ecINTERNAL_ERROR); } // switch operator id - m_iPos += (int)len; - a_Tok.Set( (ECmdCode)i, pOprtDef[i] ); + m_iPos += len; + a_Tok.Set( (ECmdCode)i, pOprtDef.at(i) ); return true; } // if operator string found } // end of for all operator strings @@ -474,17 +512,17 @@ namespace qmu //--------------------------------------------------------------------------- bool QmuParserTokenReader::IsArgSep(token_type &a_Tok) { - const char_type* szFormula = m_strFormula.c_str(); - - if (szFormula[m_iPos]==m_cArgSep) + if (m_strFormula.at(m_iPos)==m_cArgSep) { // copy the separator into null terminated string - char_type szSep[2]; + QString szSep; szSep[0] = m_cArgSep; szSep[1] = 0; if (m_iSynFlags & noARG_SEP) + { Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep); + } m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; m_iPos++; @@ -505,7 +543,11 @@ namespace qmu */ bool QmuParserTokenReader::IsEOF(token_type &a_Tok) { - const char_type* szFormula = m_strFormula.c_str(); +#if defined(_UNICODE) + const char_type* szFormula = m_strFormula.toStdWString().c_str(); +#else + const char_type* szFormula = m_strFormula.toStdString().c_str(); +#endif // check for EOF if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/) @@ -530,7 +572,7 @@ namespace qmu */ bool QmuParserTokenReader::IsInfixOpTok(token_type &a_Tok) { - string_type sTok; + QString sTok; int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos); if (iEnd==m_iPos) return false; @@ -539,7 +581,7 @@ namespace qmu funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); for ( ; it!=m_pInfixOprtDef->rend(); ++it) { - if (sTok.find(it->first)!=0) + if (sTok.indexOf(it->first)!=0) continue; a_Tok.Set(it->second, it->first); @@ -575,7 +617,7 @@ namespace qmu */ bool QmuParserTokenReader::IsFunTok(token_type &a_Tok) { - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd==m_iPos) return false; @@ -585,13 +627,12 @@ namespace qmu return false; // Check if the next sign is an opening bracket - const char_type *szFormula = m_strFormula.c_str(); - if (szFormula[iEnd]!='(') + if (m_strFormula.at(iEnd)!='(') return false; a_Tok.Set(item->second, strTok); - m_iPos = (int)iEnd; + m_iPos = iEnd; if (m_iSynFlags & noFUN) Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString()); @@ -606,18 +647,19 @@ namespace qmu */ bool QmuParserTokenReader::IsOprt(token_type &a_Tok) { - const char_type *const szExpr = m_strFormula.c_str(); - string_type strTok; + QString strTok; int iEnd = ExtractOperatorToken(strTok, m_iPos); if (iEnd==m_iPos) return false; // Check if the operator is a built in operator, if so ignore it here - const char_type **const pOprtDef = m_pParser->GetOprtDef(); - for (int i=0; m_pParser->HasBuiltInOprt() && pOprtDef[i]; ++i) + const QStringList pOprtDef = m_pParser->GetOprtDef(); + QStringList::const_iterator constIterator; + for (constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd(); + ++constIterator) { - if (string_type(pOprtDef[i])==strTok) + if ((*constIterator)==strTok) return false; } @@ -630,8 +672,8 @@ namespace qmu funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); for ( ; it!=m_pOprtDef->rend(); ++it) { - const string_type &sID = it->first; - if ( sID == string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) ) + const QString &sID = it->first; + if ( sID == m_strFormula.mid(m_iPos, m_iPos + sID.length()) ) { a_Tok.Set(it->second, strTok); @@ -686,7 +728,7 @@ namespace qmu // token readers. // Test if there could be a postfix operator - string_type sTok; + QString sTok; int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos); if (iEnd==m_iPos) return false; @@ -695,11 +737,11 @@ namespace qmu funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); for ( ; it!=m_pPostOprtDef->rend(); ++it) { - if (sTok.find(it->first)!=0) + if (sTok.indexOf(it->first)!=0) continue; a_Tok.Set(it->second, sTok); - m_iPos += (int)it->first.length(); + m_iPos += it->first.length(); m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; return true; @@ -721,7 +763,7 @@ namespace qmu assert(m_pConstDef); assert(m_pParser); - string_type strTok; + QString strTok; qreal fVal(0); int iEnd(0); @@ -737,7 +779,7 @@ namespace qmu a_Tok.SetVal(item->second, strTok); if (m_iSynFlags & noVAL) - Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok); + Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok); m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; return true; @@ -750,11 +792,11 @@ namespace qmu for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item) { int iStart = m_iPos; - if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 ) + if ( (*item)(m_strFormula.mid(m_iPos), &m_iPos, &fVal)==1 ) { - strTok.assign(m_strFormula.c_str(), iStart, m_iPos); + strTok = m_strFormula.mid(iStart, m_iPos); if (m_iSynFlags & noVAL) - Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok); + Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok); a_Tok.SetVal(fVal, strTok); m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; @@ -775,7 +817,7 @@ namespace qmu if (!m_pVarDef->size()) return false; - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd==m_iPos) return false; @@ -806,7 +848,7 @@ namespace qmu if (!m_pStrVarDef || !m_pStrVarDef->size()) return false; - string_type strTok; + QString strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd==m_iPos) return false; @@ -838,7 +880,7 @@ namespace qmu */ bool QmuParserTokenReader::IsUndefVarTok(token_type &a_Tok) { - string_type strTok; + QString strTok; int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) ); if ( iEnd==m_iPos ) return false; @@ -855,7 +897,7 @@ namespace qmu // If a factory is available implicitely create new variables if (m_pFactory) { - qreal *fVar = m_pFactory(strTok.c_str(), m_pFactoryData); + qreal *fVar = m_pFactory(strTok, m_pFactoryData); a_Tok.SetVar(fVar, strTok ); // Do not use m_pParser->DefineVar( strTok, fVar ); @@ -893,21 +935,21 @@ namespace qmu if (m_strFormula[m_iPos]!='"') return false; - string_type strBuf(&m_strFormula[m_iPos+1]); - std::size_t iEnd(0), iSkip(0); + QString strBuf(m_strFormula[m_iPos+1]); + int iEnd(0), iSkip(0); // parser over escaped '\"' end replace them with '"' - for(iEnd=(int)strBuf.find( "\"" ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( "\"", iEnd)) + for(iEnd=strBuf.indexOf( "\"" ); iEnd!=0 && iEnd!=-1; iEnd=strBuf.indexOf( "\"", iEnd)) { if (strBuf[iEnd-1]!='\\') break; strBuf.replace(iEnd-1, 2, "\"" ); iSkip++; } - if (iEnd==string_type::npos) + if (iEnd==-1) Error(ecUNTERMINATED_STRING, m_iPos, "\"" ); - string_type strTok(strBuf.begin(), strBuf.begin()+iEnd); + QString strTok = strBuf.mid(0, iEnd); if (m_iSynFlags & noSTR) Error(ecUNEXPECTED_STR, m_iPos, strTok); @@ -915,7 +957,7 @@ namespace qmu m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size()); - m_iPos += (int)strTok.length() + 2 + (int)iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iPos += (int)strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); return true; @@ -933,7 +975,7 @@ namespace qmu */ void QmuParserTokenReader::Error( EErrorCodes a_iErrc, int a_iPos, - const string_type &a_sTok) const + const QString &a_sTok) const { m_pParser->Error(a_iErrc, a_iPos, a_sTok); } @@ -945,7 +987,7 @@ namespace qmu } //--------------------------------------------------------------------------- - char_type QmuParserTokenReader::GetArgSep() const + QChar QmuParserTokenReader::GetArgSep() const { return m_cArgSep; } diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 7c22fcb53..de73388eb 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -52,7 +52,7 @@ namespace qmu { private: - typedef QmuParserToken token_type; + typedef QmuParserToken token_type; public: @@ -61,13 +61,13 @@ namespace qmu void AddValIdent(identfun_type a_pCallback); void SetVarCreator(facfun_type a_pFactory, void *pUserData); - void SetFormula(const string_type &a_strFormula); + void SetFormula(const QString &a_strFormula); void SetArgSep(char_type cArgSep); int GetPos() const; - const string_type& GetExpr() const; + const QString &GetExpr() const; varmap_type& GetUsedVar(); - char_type GetArgSep() const; + QChar GetArgSep() const; void IgnoreUndefVar(bool bIgnore); void ReInit(); @@ -106,10 +106,8 @@ namespace qmu void Assign(const QmuParserTokenReader &a_Reader); void SetParent(QmuParserBase *a_pParent); - int ExtractToken(const char_type *a_szCharSet, - string_type &a_strTok, - int a_iPos) const; - int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const; + int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const; + int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; bool IsBuiltIn(token_type &a_Tok); bool IsArgSep(token_type &a_Tok); @@ -123,14 +121,14 @@ namespace qmu bool IsStrVarTok(token_type &a_Tok); bool IsUndefVarTok(token_type &a_Tok); bool IsString(token_type &a_Tok); - void Error(EErrorCodes a_iErrc, - int a_iPos = -1, - const string_type &a_sTok = string_type() ) const; + void Error(EErrorCodes a_iErrc, + int a_iPos = -1, + const QString &a_sTok = QString() ) const; token_type& SaveBeforeReturn(const token_type &tok); QmuParserBase *m_pParser; - string_type m_strFormula; + QString m_strFormula; int m_iPos; int m_iSynFlags; bool m_bIgnoreUndefVar; @@ -149,7 +147,7 @@ namespace qmu qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables int m_iBrackets; token_type m_lastTok; - char_type m_cArgSep; ///< The character used for separating function arguments + QChar m_cArgSep; ///< The character used for separating function arguments }; } // namespace qmu From 2c77a73343c4580fb1221cf3cb1e6dab11970c87 Mon Sep 17 00:00:00 2001 From: dismine Date: Wed, 30 Apr 2014 08:32:29 +0300 Subject: [PATCH 14/26] Apply project code style. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 588 +-- src/libs/qmuparser/qmuparser.h | 108 +- src/libs/qmuparser/qmuparserbase.cpp | 3576 ++++++++++--------- src/libs/qmuparser/qmuparserbase.h | 464 ++- src/libs/qmuparser/qmuparserbytecode.cpp | 1143 +++--- src/libs/qmuparser/qmuparserbytecode.h | 138 +- src/libs/qmuparser/qmuparsercallback.cpp | 782 ++-- src/libs/qmuparser/qmuparsercallback.h | 60 +- src/libs/qmuparser/qmuparserdef.h | 556 ++- src/libs/qmuparser/qmuparsererror.cpp | 655 ++-- src/libs/qmuparser/qmuparsererror.h | 322 +- src/libs/qmuparser/qmuparserfixes.h | 4 +- src/libs/qmuparser/qmuparsertest.cpp | 2741 +++++++------- src/libs/qmuparser/qmuparsertest.h | 502 +-- src/libs/qmuparser/qmuparsertoken.h | 92 +- src/libs/qmuparser/qmuparsertokenreader.cpp | 1992 +++++------ src/libs/qmuparser/qmuparsertokenreader.h | 8 +- 17 files changed, 7033 insertions(+), 6698 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index bfcf74bdf..05744f952 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -24,322 +24,366 @@ #include #include -//--- Standard includes ------------------------------------------------------------------------ -#include -#include - using namespace std; -/** \file - \brief Implementation of the standard floating point QmuParser. -*/ +/** + * @file + * @brief Implementation of the standard floating point QmuParser. + */ -/** \brief Namespace for mathematical applications. */ +/** + * @brief Namespace for mathematical applications. + */ namespace qmu { - //--------------------------------------------------------------------------- - // Trigonometric function - qreal QmuParser::Sinh(qreal v) { return sinh(v); } - qreal QmuParser::Cosh(qreal v) { return cosh(v); } - qreal QmuParser::Tanh(qreal v) { return tanh(v); } - qreal QmuParser::ASinh(qreal v) { return log(v + qSqrt(v * v + 1)); } - qreal QmuParser::ACosh(qreal v) { return log(v + qSqrt(v * v - 1)); } - qreal QmuParser::ATanh(qreal v) { return ((qreal)0.5 * log((1 + v) / (1 - v))); } +// Trigonometric function +qreal QmuParser::Sinh(qreal v) +{ + return sinh(v); +} - //--------------------------------------------------------------------------- - // Logarithm functions +qreal QmuParser::Cosh(qreal v) +{ + return cosh(v); +} - // Logarithm base 2 - qreal QmuParser::Log2(qreal v) - { - #ifdef MUP_MATH_EXCEPTIONS - if (v<=0) - throw QmuParserError(ecDOMAIN_ERROR, "Log2"); - #endif +qreal QmuParser::Tanh(qreal v) +{ + return tanh(v); +} - return log(v)/log((qreal)2); - } +qreal QmuParser::ASinh(qreal v) +{ + return log(v + qSqrt(v * v + 1)); +} - // Logarithm base 10 - qreal QmuParser::Log10(qreal v) - { - #ifdef MUP_MATH_EXCEPTIONS - if (v<=0) - throw QmuParserError(ecDOMAIN_ERROR, "Log10"); - #endif +qreal QmuParser::ACosh(qreal v) +{ + return log(v + qSqrt(v * v - 1)); +} - return log10(v); - } +qreal QmuParser::ATanh(qreal v) +{ + return ((qreal)0.5 * log((1 + v) / (1 - v))); +} +//---------------------------------------------------------------------------------------------------------------------- +// Logarithm functions - //--------------------------------------------------------------------------- - // misc - qreal QmuParser::Abs(qreal v) { return qAbs(v); } - qreal QmuParser::Rint(qreal v) { return qFloor(v + (qreal)0.5); } - qreal QmuParser::Sign(qreal v) { return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); } +// Logarithm base 2 +qreal QmuParser::Log2(qreal v) +{ +#ifdef MUP_MATH_EXCEPTIONS + if (v<=0) + { + throw QmuParserError(ecDOMAIN_ERROR, "Log2"); + } +#endif + return log(v)/log((qreal)2); +} - //--------------------------------------------------------------------------- - /** \brief Callback for the unary minus operator. - \param v The value to negate - \return -v - */ - qreal QmuParser::UnaryMinus(qreal v) - { - return -v; - } +// Logarithm base 10 +qreal QmuParser::Log10(qreal v) +{ +#ifdef MUP_MATH_EXCEPTIONS + if (v<=0) + { + throw QmuParserError(ecDOMAIN_ERROR, "Log10"); + } +#endif + return log10(v); +} - //--------------------------------------------------------------------------- - /** \brief Callback for adding multiple values. - \param [in] a_afArg Vector with the function arguments - \param [in] a_iArgc The size of a_afArg - */ - qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc) - { - if (!a_iArgc) - throw exception_type("too few arguments for function sum."); +//---------------------------------------------------------------------------------------------------------------------- +// misc +qreal QmuParser::Abs(qreal v) +{ + return qAbs(v); +} - qreal fRes=0; - for (int i=0; i0) ? 1 : 0); +} - qreal fRes=0; - for (int i=0; i> fVal; + stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading -#if defined(_UNICODE) - std::wstring a_szExprStd = a_szExpr.toStdWString(); -#else - std::string a_szExprStd = a_szExpr.toStdString(); -#endif - stringstream_type stream(a_szExprStd); - stream.seekg(0); // todo: check if this really is necessary - stream.imbue(QmuParser::s_locale); - stream >> fVal; - stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading + if (iEnd==(stringstream_type::pos_type)-1) + { + return 0; + } - if (iEnd==(stringstream_type::pos_type)-1) - return 0; + *a_iPos += (int)iEnd; + *a_fVal = fVal; + return 1; +} - *a_iPos += (int)iEnd; - *a_fVal = fVal; - return 1; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor. + * + * Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization. + */ +QmuParser::QmuParser():QmuParserBase() +{ + AddValIdent(IsVal); + InitCharSets(); + InitFun(); + InitConst(); + InitOprt(); +} - //--------------------------------------------------------------------------- - /** \brief Constructor. +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the character sets. + * @sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars + * + * This function is used for initializing the default character sets that define + * the characters to be useable in function and variable names and operators. + */ +void QmuParser::InitCharSets() +{ + DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); + DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" ); + DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" ); +} - Call QmuParserBase class constructor and trigger Function, Operator and Constant initialization. - */ - QmuParser::QmuParser() - :QmuParserBase() - { - AddValIdent(IsVal); - - InitCharSets(); - InitFun(); - InitConst(); - InitOprt(); - } - - //--------------------------------------------------------------------------- - /** \brief Define the character sets. - \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars - - This function is used for initializing the default character sets that define - the characters to be useable in function and variable names and operators. - */ - void QmuParser::InitCharSets() - { - DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); - DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" ); - DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" ); - } - -//--------------------------------------------------------------------------- -/** \brief Initialize the default functions. */ +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize the default functions. + */ void QmuParser::InitFun() { - // trigonometric functions - DefineFun("sin", qSin); - DefineFun("cos", qCos); - DefineFun("tan", qTan); - // arcus functions - DefineFun("asin", qAsin); - DefineFun("acos", qAcos); - DefineFun("atan", qAtan); - DefineFun("atan2", qAtan2); - // hyperbolic functions - DefineFun("sinh", Sinh); - DefineFun("cosh", Cosh); - DefineFun("tanh", Tanh); - // arcus hyperbolic functions - DefineFun("asinh", ASinh); - DefineFun("acosh", ACosh); - DefineFun("atanh", ATanh); - // Logarithm functions - DefineFun("log2", Log2); - DefineFun("log10", Log10); - DefineFun("log", Log10); - DefineFun("ln", qLn); - // misc - DefineFun("exp", qExp); - DefineFun("sqrt", qSqrt); - DefineFun("sign", Sign); - DefineFun("rint", Rint); - DefineFun("abs", Abs); - // Functions with variable number of arguments - DefineFun("sum", Sum); - DefineFun("avg", Avg); - DefineFun("min", Min); - DefineFun("max", Max); + // trigonometric functions + DefineFun("sin", qSin); + DefineFun("cos", qCos); + DefineFun("tan", qTan); + // arcus functions + DefineFun("asin", qAsin); + DefineFun("acos", qAcos); + DefineFun("atan", qAtan); + DefineFun("atan2", qAtan2); + // hyperbolic functions + DefineFun("sinh", Sinh); + DefineFun("cosh", Cosh); + DefineFun("tanh", Tanh); + // arcus hyperbolic functions + DefineFun("asinh", ASinh); + DefineFun("acosh", ACosh); + DefineFun("atanh", ATanh); + // Logarithm functions + DefineFun("log2", Log2); + DefineFun("log10", Log10); + DefineFun("log", Log10); + DefineFun("ln", qLn); + // misc + DefineFun("exp", qExp); + DefineFun("sqrt", qSqrt); + DefineFun("sign", Sign); + DefineFun("rint", Rint); + DefineFun("abs", Abs); + // Functions with variable number of arguments + DefineFun("sum", Sum); + DefineFun("avg", Avg); + DefineFun("min", Min); + DefineFun("max", Max); } - //--------------------------------------------------------------------------- - /** \brief Initialize constants. +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize constants. + * + * By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian + * number ("_e"). + */ +void QmuParser::InitConst() +{ + DefineConst("_pi", (qreal)M_PI); + DefineConst("_e", (qreal)M_E); +} - By default the QmuParser recognizes two constants. Pi ("pi") and the eulerian - number ("_e"). - */ - void QmuParser::InitConst() - { - DefineConst("_pi", (qreal)M_PI); - DefineConst("_e", (qreal)M_E); - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize operators. + * + * By default only the unary minus operator is added. + */ +void QmuParser::InitOprt() +{ + DefineInfixOprt("-", UnaryMinus); +} - //--------------------------------------------------------------------------- - /** \brief Initialize operators. - - By default only the unary minus operator is added. - */ - void QmuParser::InitOprt() - { - DefineInfixOprt("-", UnaryMinus); - } - - //--------------------------------------------------------------------------- - void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) - { - // this is just sample code to illustrate modifying variable names on the fly. - // I'm not sure anyone really needs such a feature... - /* +//---------------------------------------------------------------------------------------------------------------------- +void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) +{ + // this is just sample code to illustrate modifying variable names on the fly. + // I'm not sure anyone really needs such a feature... + /* - string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd); - string sRepl = std::string("_") + sVar + "_"; + string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd); + string sRepl = std::string("_") + sVar + "_"; - int nOrigVarEnd = nEnd; - cout << "variable detected!\n"; - cout << " Expr: " << *pExpr << "\n"; - cout << " Start: " << nStart << "\n"; - cout << " End: " << nEnd << "\n"; - cout << " Var: \"" << sVar << "\"\n"; - cout << " Repl: \"" << sRepl << "\"\n"; - nEnd = nStart + sRepl.length(); - cout << " End: " << nEnd << "\n"; - pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl); - cout << " New expr: " << *pExpr << "\n"; - */ - } + int nOrigVarEnd = nEnd; + cout << "variable detected!\n"; + cout << " Expr: " << *pExpr << "\n"; + cout << " Start: " << nStart << "\n"; + cout << " End: " << nEnd << "\n"; + cout << " Var: \"" << sVar << "\"\n"; + cout << " Repl: \"" << sRepl << "\"\n"; + nEnd = nStart + sRepl.length(); + cout << " End: " << nEnd << "\n"; + pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl); + cout << " New expr: " << *pExpr << "\n"; + */ +} - //--------------------------------------------------------------------------- - /** \brief Numerically differentiate with regard to a variable. - \param [in] a_Var Pointer to the differentiation variable. - \param [in] a_fPos Position at which the differentiation should take place. - \param [in] a_fEpsilon Epsilon used for the numerical differentiation. +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Numerically differentiate with regard to a variable. + * @param [in] a_Var Pointer to the differentiation variable. + * @param [in] a_fPos Position at which the differentiation should take place. + * @param [in] a_fEpsilon Epsilon used for the numerical differentiation. + * + * Numerical differentiation uses a 5 point operator yielding a 4th order + * formula. The default value for epsilon is 0.00074 which is + * numeric_limits::epsilon() ^ (1/5) as suggested in the muQmuParser + * forum: + * + * http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 + */ +qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const +{ + qreal fRes(0), + fBuf(*a_Var), + f[4] = {0,0,0,0}, + fEpsilon(a_fEpsilon); - Numerical differentiation uses a 5 point operator yielding a 4th order - formula. The default value for epsilon is 0.00074 which is - numeric_limits::epsilon() ^ (1/5) as suggested in the muQmuParser - forum: + // Backwards compatible calculation of epsilon inc case the user doesnt provide + // his own epsilon + if (fEpsilon==0) + { + fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos; + } - http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 - */ - qreal QmuParser::Diff(qreal *a_Var, - qreal a_fPos, - qreal a_fEpsilon) const - { - qreal fRes(0), - fBuf(*a_Var), - f[4] = {0,0,0,0}, - fEpsilon(a_fEpsilon); + *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); + *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); + *a_Var = a_fPos-1 * fEpsilon; f[2] = Eval(); + *a_Var = a_fPos-2 * fEpsilon; f[3] = Eval(); + *a_Var = fBuf; // restore variable - // Backwards compatible calculation of epsilon inc case the user doesnt provide - // his own epsilon - if (fEpsilon==0) - fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos; - - *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); - *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); - *a_Var = a_fPos-1 * fEpsilon; f[2] = Eval(); - *a_Var = a_fPos-2 * fEpsilon; f[3] = Eval(); - *a_Var = fBuf; // restore variable - - fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon); - return fRes; - } + fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon); + return fRes; +} } // namespace qmu diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index e0b44d06a..685fecd02 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -24,67 +24,63 @@ #define QMUPARSER_H #include "qmuparser_global.h" - -//--- Parser includes -------------------------------------------------------------------------- #include "qmuparserbase.h" -/** \file - \brief Definition of the standard floating point parser. -*/ +/** + * @file + * @brief Definition of the standard floating point parser. + */ namespace qmu { - /** \brief Mathematical expressions parser. - - Standard implementation of the mathematical expressions parser. - Can be used as a reference implementation for subclassing the parser. - - - (C) 2011 Ingo Berg
- muparser(at)gmx.de -
- */ -/* final */ class QMUPARSERSHARED_EXPORT QmuParser : public QmuParserBase -{ - -public: - QmuParser(); - virtual void InitCharSets(); - virtual void InitFun(); - virtual void InitConst(); - virtual void InitOprt(); - virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); - - qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; -protected: - // Trigonometric functions - static qreal Tan2(qreal, qreal); - // hyperbolic functions - static qreal Sinh(qreal); - static qreal Cosh(qreal); - static qreal Tanh(qreal); - // arcus hyperbolic functions - static qreal ASinh(qreal); - static qreal ACosh(qreal); - static qreal ATanh(qreal); - // Logarithm functions - static qreal Log2(qreal); // Logarithm Base 2 - static qreal Log10(qreal); // Logarithm Base 10 - // misc - static qreal Abs(qreal); - static qreal Rint(qreal); - static qreal Sign(qreal); - // Prefix operators - // !!! Unary Minus is a MUST if you want to use negative signs !!! - static qreal UnaryMinus(qreal); - // Functions with variable number of arguments - static qreal Sum(const qreal*, int); // sum - static qreal Avg(const qreal*, int); // mean value - static qreal Min(const qreal*, int); // minimum - static qreal Max(const qreal*, int); // maximum - - static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); -}; + /** @brief Mathematical expressions parser. + * + * Standard implementation of the mathematical expressions parser. + * Can be used as a reference implementation for subclassing the parser. + * + * + * (C) 2011 Ingo Berg
+ * muparser(at)gmx.de + *
+ */ + /* final */ class QMUPARSERSHARED_EXPORT QmuParser : public QmuParserBase + { + public: + QmuParser(); + virtual void InitCharSets(); + virtual void InitFun(); + virtual void InitConst(); + virtual void InitOprt(); + virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; + protected: + static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); + // Trigonometric functions + static qreal Tan2(qreal, qreal); + // hyperbolic functions + static qreal Sinh(qreal); + static qreal Cosh(qreal); + static qreal Tanh(qreal); + // arcus hyperbolic functions + static qreal ASinh(qreal); + static qreal ACosh(qreal); + static qreal ATanh(qreal); + // Logarithm functions + static qreal Log2(qreal); // Logarithm Base 2 + static qreal Log10(qreal); // Logarithm Base 10 + // misc + static qreal Abs(qreal); + static qreal Rint(qreal); + static qreal Sign(qreal); + // Prefix operators + // !!! Unary Minus is a MUST if you want to use negative signs !!! + static qreal UnaryMinus(qreal); + // Functions with variable number of arguments + static qreal Sum(const qreal*, int); // sum + static qreal Avg(const qreal*, int); // mean value + static qreal Min(const qreal*, int); // minimum + static qreal Max(const qreal*, int); // maximum + }; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 7b7d1e9c3..0f46773c7 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -21,1762 +21,1980 @@ ******************************************************************************************************/ #include "qmuparserbase.h" - -//--- Standard includes ------------------------------------------------------------------------ -#include -#include -#include -#include -#include -#include - +#include +#include #ifdef QMUP_USE_OPENMP - #include + #include #endif using namespace std; -/** \file - \brief This file contains the basic implementation of the muparser engine. -*/ +/** + * @file + * @brief This file contains the basic implementation of the muparser engine. + */ namespace qmu { - std::locale QmuParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep('.')); +std::locale QmuParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep('.')); - bool QmuParserBase::g_DbgDumpCmdCode = false; - bool QmuParserBase::g_DbgDumpStack = false; +bool QmuParserBase::g_DbgDumpCmdCode = false; +bool QmuParserBase::g_DbgDumpStack = false; - //------------------------------------------------------------------------------ - /** \brief Identifiers for built in binary operators. +/** + * @brief Identifiers for built in binary operators. + * + * When defining custom binary operators with #AddOprt(...) make sure not to choose + * names conflicting with these definitions. + */ +const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" + << "+" << "-" << "*" << "/" << "^" << "&&" + << "||" << "=" << "(" << ")" << "?" << ":"; - When defining custom binary operators with #AddOprt(...) make sure not to choose - names conflicting with these definitions. - */ - const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" << "+" - << "-" << "*" << "/" << "^" << "&&" << "||" << "=" - << "(" << ")" << "?" << ":"; +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor. + * @param a_szFormula the formula to interpret. + * @throw ParserException if a_szFormula is null. + */ +QmuParserBase::QmuParserBase() + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(), + m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), + m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + m_nFinalResultIdx(0) +{ + InitTokenReader(); +} - //------------------------------------------------------------------------------ - /** \brief Constructor. - \param a_szFormula the formula to interpret. - \throw ParserException if a_szFormula is null. - */ - QmuParserBase::QmuParserBase() - :m_pParseFormula(&QmuParserBase::ParseString) - ,m_vRPN() - ,m_vStringBuf() - ,m_pTokenReader() - ,m_FunDef() - ,m_PostOprtDef() - ,m_InfixOprtDef() - ,m_OprtDef() - ,m_ConstDef() - ,m_StrVarDef() - ,m_VarDef() - ,m_bBuiltInOp(true) - ,m_sNameChars() - ,m_sOprtChars() - ,m_sInfixOprtChars() - ,m_nIfElseCounter(0) - ,m_vStackBuffer() - ,m_nFinalResultIdx(0) - { - InitTokenReader(); - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy constructor. + * + * Tha parser can be safely copy constructed but the bytecode is reset during copy construction. + */ +QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) +:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(), + m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), + m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0) +{ + m_pTokenReader.reset(new token_reader_type(this)); + Assign(a_Parser); +} - //--------------------------------------------------------------------------- - /** \brief Copy constructor. +//---------------------------------------------------------------------------------------------------------------------- +QmuParserBase::~QmuParserBase() +{} - Tha parser can be safely copy constructed but the bytecode is reset during - copy construction. - */ - QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) - :m_pParseFormula(&QmuParserBase::ParseString) - ,m_vRPN() - ,m_vStringBuf() - ,m_pTokenReader() - ,m_FunDef() - ,m_PostOprtDef() - ,m_InfixOprtDef() - ,m_OprtDef() - ,m_ConstDef() - ,m_StrVarDef() - ,m_VarDef() - ,m_bBuiltInOp(true) - ,m_sNameChars() - ,m_sOprtChars() - ,m_sInfixOprtChars() - ,m_nIfElseCounter(0) - { - m_pTokenReader.reset(new token_reader_type(this)); - Assign(a_Parser); - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Assignement operator. + * + * Implemented by calling Assign(a_Parser). Self assignement is suppressed. + * @param a_Parser Object to copy to this. + * @return *this + * @throw nothrow + */ +QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) +{ + Assign(a_Parser); + return *this; +} - //--------------------------------------------------------------------------- - QmuParserBase::~QmuParserBase() - {} +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy state of a parser object to this. + * + * Clears Variables and Functions of this parser. + * Copies the states of all internal variables. + * Resets parse function to string parse mode. + * + * @param a_Parser the source object. + */ +void QmuParserBase::Assign(const QmuParserBase &a_Parser) +{ + if (&a_Parser==this) + { + return; + } - //--------------------------------------------------------------------------- - /** \brief Assignement operator. + // Don't copy bytecode instead cause the parser to create new bytecode + // by resetting the parse function. + ReInit(); - Implemented by calling Assign(a_Parser). Self assignement is suppressed. - \param a_Parser Object to copy to this. - \return *this - \throw nothrow - */ - QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) - { - Assign(a_Parser); - return *this; - } + m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants + m_VarDef = a_Parser.m_VarDef; // Copy user defined variables + m_bBuiltInOp = a_Parser.m_bBuiltInOp; + m_vStringBuf = a_Parser.m_vStringBuf; + m_vStackBuffer = a_Parser.m_vStackBuffer; + m_nFinalResultIdx = a_Parser.m_nFinalResultIdx; + m_StrVarDef = a_Parser.m_StrVarDef; + m_vStringVarBuf = a_Parser.m_vStringVarBuf; + m_nIfElseCounter = a_Parser.m_nIfElseCounter; + m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this)); - //--------------------------------------------------------------------------- - /** \brief Copy state of a parser object to this. + // Copy function and operator callbacks + m_FunDef = a_Parser.m_FunDef; // Copy function definitions + m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators + m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation + m_OprtDef = a_Parser.m_OprtDef; // binary operators - Clears Variables and Functions of this parser. - Copies the states of all internal variables. - Resets parse function to string parse mode. + m_sNameChars = a_Parser.m_sNameChars; + m_sOprtChars = a_Parser.m_sOprtChars; + m_sInfixOprtChars = a_Parser.m_sInfixOprtChars; +} - \param a_Parser the source object. - */ - void QmuParserBase::Assign(const QmuParserBase &a_Parser) - { - if (&a_Parser==this) - return; +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set the decimal separator. + * @param cDecSep Decimal separator as a character value. + * @sa SetThousandsSep + * + * By default muparser uses the "C" locale. The decimal separator of this + * locale is overwritten by the one provided here. + */ +void QmuParserBase::SetDecSep(char_type cDecSep) +{ + char_type cThousandsSep = std::use_facet< change_dec_sep >(s_locale).thousands_sep(); + s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); +} - // Don't copy bytecode instead cause the parser to create new bytecode - // by resetting the parse function. - ReInit(); +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Sets the thousands operator. + * @param cThousandsSep The thousands separator as a character + * @sa SetDecSep + * + * By default muparser uses the "C" locale. The thousands separator of this + * locale is overwritten by the one provided here. + */ +void QmuParserBase::SetThousandsSep(char_type cThousandsSep) +{ + char_type cDecSep = std::use_facet< change_dec_sep >(s_locale).decimal_point(); + s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); +} - m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants - m_VarDef = a_Parser.m_VarDef; // Copy user defined variables - m_bBuiltInOp = a_Parser.m_bBuiltInOp; - m_vStringBuf = a_Parser.m_vStringBuf; - m_vStackBuffer = a_Parser.m_vStackBuffer; - m_nFinalResultIdx = a_Parser.m_nFinalResultIdx; - m_StrVarDef = a_Parser.m_StrVarDef; - m_vStringVarBuf = a_Parser.m_vStringVarBuf; - m_nIfElseCounter = a_Parser.m_nIfElseCounter; - m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this)); +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Resets the locale. + * + * The default locale used "." as decimal separator, no thousands separator and "," as function argument separator. + */ +void QmuParserBase::ResetLocale() +{ + s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); + SetArgSep(','); +} - // Copy function and operator callbacks - m_FunDef = a_Parser.m_FunDef; // Copy function definitions - m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators - m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation - m_OprtDef = a_Parser.m_OprtDef; // binary operators +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize the token reader. + * + * Create new token reader object and submit pointers to function, operator, constant and variable definitions. + * + * @post m_pTokenReader.get()!=0 + * @throw nothrow + */ +void QmuParserBase::InitTokenReader() +{ + m_pTokenReader.reset(new token_reader_type(this)); +} - m_sNameChars = a_Parser.m_sNameChars; - m_sOprtChars = a_Parser.m_sOprtChars; - m_sInfixOprtChars = a_Parser.m_sInfixOprtChars; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Reset parser to string parsing mode and clear internal buffers. + * + * Clear bytecode, reset the token reader. + * @throw nothrow + */ +void QmuParserBase::ReInit() const +{ + m_pParseFormula = &QmuParserBase::ParseString; + m_vStringBuf.clear(); + m_vRPN.clear(); + m_pTokenReader->ReInit(); + m_nIfElseCounter = 0; +} - //--------------------------------------------------------------------------- - /** \brief Set the decimal separator. - \param cDecSep Decimal separator as a character value. - \sa SetThousandsSep +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) +{} - By default muparser uses the "C" locale. The decimal separator of this - locale is overwritten by the one provided here. - */ - void QmuParserBase::SetDecSep(char_type cDecSep) - { - char_type cThousandsSep = std::use_facet< change_dec_sep >(s_locale).thousands_sep(); - s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); - } - - //--------------------------------------------------------------------------- - /** \brief Sets the thousands operator. - \param cThousandsSep The thousands separator as a character - \sa SetDecSep +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the version of muparser. + * @param eInfo A flag indicating whether the full version info should be returned or not. + * + * Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS are returned only if eInfo==pviFULL. + */ +QString QmuParserBase::GetVersion(EParserVersionInfo eInfo) const +{ + QString versionInfo; + QTextStream ss(&versionInfo); - By default muparser uses the "C" locale. The thousands separator of this - locale is overwritten by the one provided here. - */ - void QmuParserBase::SetThousandsSep(char_type cThousandsSep) - { - char_type cDecSep = std::use_facet< change_dec_sep >(s_locale).decimal_point(); - s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); - } + ss << QMUP_VERSION; - //--------------------------------------------------------------------------- - /** \brief Resets the locale. + if (eInfo==pviFULL) + { + ss << " (" << QMUP_VERSION_DATE; + ss << "; " << sizeof(void*)*8 << "BIT"; - The default locale used "." as decimal separator, no thousands separator and - "," as function argument separator. - */ - void QmuParserBase::ResetLocale() - { - s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); - SetArgSep(','); - } + #ifdef _DEBUG + ss << "; DEBUG"; + #else + ss << "; RELEASE"; + #endif - //--------------------------------------------------------------------------- - /** \brief Initialize the token reader. + #ifdef _UNICODE + ss << "; UNICODE"; + #else + #ifdef _MBCS + ss << "; MBCS"; + #else + ss << "; ASCII"; + #endif + #endif - Create new token reader object and submit pointers to function, operator, - constant and variable definitions. + #ifdef QMUP_USE_OPENMP + ss << "; OPENMP"; + //#else + // ss << "; NO_OPENMP"; + #endif - \post m_pTokenReader.get()!=0 - \throw nothrow - */ - void QmuParserBase::InitTokenReader() - { - m_pTokenReader.reset(new token_reader_type(this)); - } + #if defined(MUP_MATH_EXCEPTIONS) + ss << "; MATHEXC"; + //#else + // ss << "; NO_MATHEXC"; + #endif - //--------------------------------------------------------------------------- - /** \brief Reset parser to string parsing mode and clear internal buffers. + ss << ")"; + } + return versionInfo; +} - Clear bytecode, reset the token reader. - \throw nothrow - */ - void QmuParserBase::ReInit() const - { - m_pParseFormula = &QmuParserBase::ParseString; - m_vStringBuf.clear(); - m_vRPN.clear(); - m_pTokenReader->ReInit(); - m_nIfElseCounter = 0; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a value parsing function. + * + * When parsing an expression muParser tries to detect values in the expression string using different valident + * callbacks. Thuis it's possible to parse for hex values, binary values and floating point values. + */ +void QmuParserBase::AddValIdent(identfun_type a_pCallback) +{ + m_pTokenReader->AddValIdent(a_pCallback); +} - //--------------------------------------------------------------------------- - void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) - {} +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set a function that can create variable pointer for unknown expression variables. + * @param a_pFactory A pointer to the variable factory. + * @param pUserData A user defined context pointer. + */ +void QmuParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData) +{ + m_pTokenReader->SetVarCreator(a_pFactory, pUserData); +} - //--------------------------------------------------------------------------- - /** \brief Returns the version of muparser. - \param eInfo A flag indicating whether the full version info should be - returned or not. +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a function or operator callback to the parser. + */ +void QmuParserBase::AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, + funmap_type &a_Storage, const QString &a_szCharSet ) +{ + if (a_Callback.GetAddr()==0) + { + Error(ecINVALID_FUN_PTR); + } - Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS - are returned only if eInfo==pviFULL. - */ - string_type QmuParserBase::GetVersion(EParserVersionInfo eInfo) const - { - string_type sCompileTimeSettings; - - stringstream_type ss; + const funmap_type *pFunMap = &a_Storage; - ss << QMUP_VERSION; + // Check for conflicting operator or function names + if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } - if (eInfo==pviFULL) - { - ss << " (" << QMUP_VERSION_DATE; - ss << std::dec << "; " << sizeof(void*)*8 << "BIT"; + if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } -#ifdef _DEBUG - ss << "; DEBUG"; -#else - ss << "; RELEASE"; -#endif + if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } -#ifdef _UNICODE - ss << "; UNICODE"; -#else - #ifdef _MBCS - ss << "; MBCS"; - #else - ss << "; ASCII"; - #endif -#endif + if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } -#ifdef QMUP_USE_OPENMP - ss << "; OPENMP"; -//#else -// ss << "; NO_OPENMP"; -#endif + CheckOprt(a_strName, a_Callback, a_szCharSet); + a_Storage[a_strName] = a_Callback; + ReInit(); +} -#if defined(MUP_MATH_EXCEPTIONS) - ss << "; MATHEXC"; -//#else -// ss << "; NO_MATHEXC"; -#endif - - ss << ")"; - } - - return ss.str(); - } - - //--------------------------------------------------------------------------- - /** \brief Add a value parsing function. - - When parsing an expression muParser tries to detect values in the expression - string using different valident callbacks. Thuis it's possible to parse - for hex values, binary values and floating point values. - */ - void QmuParserBase::AddValIdent(identfun_type a_pCallback) - { - m_pTokenReader->AddValIdent(a_pCallback); - } - - //--------------------------------------------------------------------------- - /** \brief Set a function that can create variable pointer for unknown expression variables. - \param a_pFactory A pointer to the variable factory. - \param pUserData A user defined context pointer. - */ - void QmuParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData) - { - m_pTokenReader->SetVarCreator(a_pFactory, pUserData); - } - - //--------------------------------------------------------------------------- - /** \brief Add a function or operator callback to the parser. */ - void QmuParserBase::AddCallback(const QString &a_strName, - const QmuParserCallback &a_Callback, - funmap_type &a_Storage, - const QString &a_szCharSet ) - { - if (a_Callback.GetAddr()==0) - Error(ecINVALID_FUN_PTR); - - const funmap_type *pFunMap = &a_Storage; - - // Check for conflicting operator or function names - if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() ) - Error(ecNAME_CONFLICT, -1, a_strName); - - if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() ) - Error(ecNAME_CONFLICT, -1, a_strName); - - if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() ) - Error(ecNAME_CONFLICT, -1, a_strName); - - if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() ) - Error(ecNAME_CONFLICT, -1, a_strName); - - CheckOprt(a_strName, a_Callback, a_szCharSet); - a_Storage[a_strName] = a_Callback; - ReInit(); - } - - //--------------------------------------------------------------------------- - /** \brief Check if a name contains invalid characters. - - \throw ParserException if the name contains invalid charakters. - */ - void QmuParserBase::CheckOprt(const QString &a_sName, - const QmuParserCallback &a_Callback, - const QString &a_szCharSet) const - { +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a name contains invalid characters. + * + * @throw ParserException if the name contains invalid charakters. + */ +void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, + const QString &a_szCharSet) const +{ #if defined(_UNICODE) - const std::wstring a_sNameStd = a_sName.toStdWString(); - const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); + const std::wstring a_sNameStd = a_sName.toStdWString(); + const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); #else - const std::string a_sNameStd = a_sName.toStdString(); - const std::string a_szCharSetStd = a_szCharSet.toStdString(); + const std::string a_sNameStd = a_sName.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); #endif - if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || - (a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9')) - { - switch(a_Callback.GetCode()) - { - case cmOPRT_POSTFIX: Error(ecINVALID_POSTFIX_IDENT, -1, a_sName); - case cmOPRT_INFIX: Error(ecINVALID_INFIX_IDENT, -1, a_sName); - default: Error(ecINVALID_NAME, -1, a_sName); - } - } - } + if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9')) + { + switch(a_Callback.GetCode()) + { + case cmOPRT_POSTFIX: + Error(ecINVALID_POSTFIX_IDENT, -1, a_sName); + break; + case cmOPRT_INFIX: + Error(ecINVALID_INFIX_IDENT, -1, a_sName); + break; + default: + Error(ecINVALID_NAME, -1, a_sName); + break; + } + } +} -//--------------------------------------------------------------------------- -/** \brief Check if a name contains invalid characters. - - \throw ParserException if the name contains invalid charakters. -*/ +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a name contains invalid characters. + * + * @throw ParserException if the name contains invalid charakters. + */ void QmuParserBase::CheckName(const QString &a_sName, const QString &a_szCharSet) const { - #if defined(_UNICODE) - std::wstring a_sNameStd = a_sName.toStdWString(); - std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); - #else - std::string a_sNameStd = a_sName.toStdString(); - std::string a_szCharSetStd = a_szCharSet.toStdString(); - #endif - if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || - (a_sNameStd[0]>='0' && a_sNameStd[0]<='9')) - { - Error(ecINVALID_NAME); - } +#if defined(_UNICODE) + std::wstring a_sNameStd = a_sName.toStdWString(); + std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); +#else + std::string a_sNameStd = a_sName.toStdString(); + std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd[0]>='0' && a_sNameStd[0]<='9')) + { + Error(ecINVALID_NAME); + } } -//--------------------------------------------------------------------------- -/** \brief Set the formula. - \param a_strFormula Formula as string_type - \throw ParserException in case of syntax errors. - - Triggers first time calculation thus the creation of the bytecode and - scanning of used variables. -*/ +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set the formula. + * @param a_strFormula Formula as string_type + * @throw ParserException in case of syntax errors. + * + * Triggers first time calculation thus the creation of the bytecode and scanning of used variables. + */ void QmuParserBase::SetExpr(const QString &a_sExpr) { - // Check locale compatibility - std::locale loc; - if (m_pTokenReader->GetArgSep()==std::use_facet >(loc).decimal_point()) - { - Error(ecLOCALE); - } + // Check locale compatibility + std::locale loc; + if (m_pTokenReader->GetArgSep()==std::use_facet >(loc).decimal_point()) + { + Error(ecLOCALE); + } - // 20060222: Bugfix for Borland-Kylix: - // adding a space to the expression will keep Borlands KYLIX from going wild - // when calling tellg on a stringstream created from the expression after - // reading a value at the end of an expression. (qmu::QmuParser::IsVal function) - // (tellg returns -1 otherwise causing the parser to ignore the value) - QString sBuf(a_sExpr + " " ); - m_pTokenReader->SetFormula(sBuf); - ReInit(); + // 20060222: Bugfix for Borland-Kylix: + // adding a space to the expression will keep Borlands KYLIX from going wild + // when calling tellg on a stringstream created from the expression after + // reading a value at the end of an expression. (qmu::QmuParser::IsVal function) + // (tellg returns -1 otherwise causing the parser to ignore the value) + QString sBuf(a_sExpr + " " ); + m_pTokenReader->SetFormula(sBuf); + ReInit(); } - //--------------------------------------------------------------------------- - /** \brief Get the default symbols used for the built in operators. - \sa c_DefaultOprt - */ - const QStringList &QmuParserBase::GetOprtDef() const - { - return c_DefaultOprt; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Get the default symbols used for the built in operators. + * @sa c_DefaultOprt + */ +const QStringList &QmuParserBase::GetOprtDef() const +{ + return c_DefaultOprt; +} - //--------------------------------------------------------------------------- - /** \brief Define the set of valid characters to be used in names of - functions, variables, constants. - */ - void QmuParserBase::DefineNameChars(const QString &a_szCharset) - { - m_sNameChars = a_szCharset; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the set of valid characters to be used in names of functions, variables, constants. + */ +void QmuParserBase::DefineNameChars(const QString &a_szCharset) +{ + m_sNameChars = a_szCharset; +} - //--------------------------------------------------------------------------- - /** \brief Define the set of valid characters to be used in names of - binary operators and postfix operators. - */ - void QmuParserBase::DefineOprtChars(const QString &a_szCharset) - { - m_sOprtChars = a_szCharset; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the set of valid characters to be used in names of binary operators and postfix operators. + */ +void QmuParserBase::DefineOprtChars(const QString &a_szCharset) +{ + m_sOprtChars = a_szCharset; +} - //--------------------------------------------------------------------------- - /** \brief Define the set of valid characters to be used in names of - infix operators. - */ - void QmuParserBase::DefineInfixOprtChars(const QString &a_szCharset) - { - m_sInfixOprtChars = a_szCharset; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the set of valid characters to be used in names of infix operators. + */ +void QmuParserBase::DefineInfixOprtChars(const QString &a_szCharset) +{ + m_sInfixOprtChars = a_szCharset; +} -//--------------------------------------------------------------------------- -/** \brief Virtual function that defines the characters allowed in name identifiers. - \sa #ValidOprtChars, #ValidPrefixOprtChars -*/ +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Virtual function that defines the characters allowed in name identifiers. + * @sa #ValidOprtChars, #ValidPrefixOprtChars + */ const QString& QmuParserBase::ValidNameChars() const { - assert(m_sNameChars.size()); - return m_sNameChars; + assert(m_sNameChars.size()); + return m_sNameChars; } - //--------------------------------------------------------------------------- - /** \brief Virtual function that defines the characters allowed in operator definitions. - \sa #ValidNameChars, #ValidPrefixOprtChars - */ - const QString &QmuParserBase::ValidOprtChars() const - { - assert(m_sOprtChars.size()); - return m_sOprtChars; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Virtual function that defines the characters allowed in operator definitions. + * @sa #ValidNameChars, #ValidPrefixOprtChars + */ +const QString &QmuParserBase::ValidOprtChars() const +{ + assert(m_sOprtChars.size()); + return m_sOprtChars; +} - //--------------------------------------------------------------------------- - /** \brief Virtual function that defines the characters allowed in infix operator definitions. - \sa #ValidNameChars, #ValidOprtChars - */ - const QString &QmuParserBase::ValidInfixOprtChars() const - { - assert(m_sInfixOprtChars.size()); - return m_sInfixOprtChars; - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Virtual function that defines the characters allowed in infix operator definitions. + * @sa #ValidNameChars, #ValidOprtChars + */ +const QString &QmuParserBase::ValidInfixOprtChars() const +{ + assert(m_sInfixOprtChars.size()); + return m_sInfixOprtChars; +} - //--------------------------------------------------------------------------- - /** \brief Add a user defined operator. - \post Will reset the Parser to string parsing mode. - */ - void QmuParserBase::DefinePostfixOprt(const QString &a_sName, - fun_type1 a_pFun, - bool a_bAllowOpt) - { - AddCallback(a_sName, - QmuParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX), - m_PostOprtDef, - ValidOprtChars() ); - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a user defined operator. + * @post Will reset the Parser to string parsing mode. + */ +void QmuParserBase::DefinePostfixOprt(const QString &a_sName, fun_type1 a_pFun, bool a_bAllowOpt) +{ + AddCallback(a_sName, QmuParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX), m_PostOprtDef, + ValidOprtChars() ); +} - //--------------------------------------------------------------------------- - /** \brief Initialize user defined functions. - - Calls the virtual functions InitFun(), InitConst() and InitOprt(). - */ - void QmuParserBase::Init() - { - InitCharSets(); - InitFun(); - InitConst(); - InitOprt(); - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize user defined functions. + * + * Calls the virtual functions InitFun(), InitConst() and InitOprt(). + */ +void QmuParserBase::Init() +{ + InitCharSets(); + InitFun(); + InitConst(); + InitOprt(); +} - //--------------------------------------------------------------------------- - /** \brief Add a user defined operator. - \post Will reset the Parser to string parsing mode. - \param [in] a_sName operator Identifier - \param [in] a_pFun Operator callback function - \param [in] a_iPrec Operator Precedence (default=prSIGN) - \param [in] a_bAllowOpt True if operator is volatile (default=false) - \sa EPrec - */ - void QmuParserBase::DefineInfixOprt(const QString &a_sName, - fun_type1 a_pFun, - int a_iPrec, - bool a_bAllowOpt) - { - AddCallback(a_sName, - QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), - m_InfixOprtDef, - ValidInfixOprtChars() ); - } +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a user defined operator. + * @post Will reset the Parser to string parsing mode. + * @param [in] a_sName operator Identifier + * @param [in] a_pFun Operator callback function + * @param [in] a_iPrec Operator Precedence (default=prSIGN) + * @param [in] a_bAllowOpt True if operator is volatile (default=false) + * @sa EPrec + */ +void QmuParserBase::DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec, bool a_bAllowOpt) +{ + AddCallback(a_sName, QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), m_InfixOprtDef, + ValidInfixOprtChars() ); +} +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define a binary operator. + * @param [in] a_sName The identifier of the operator. + * @param [in] a_pFun Pointer to the callback function. + * @param [in] a_iPrec Precedence of the operator. + * @param [in] a_eAssociativity The associativity of the operator. + * @param [in] a_bAllowOpt If this is true the operator may be optimized away. + * + * Adds a new Binary operator the the parser instance. + */ +void QmuParserBase::DefineOprt( const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec, + EOprtAssociativity a_eAssociativity, bool a_bAllowOpt ) +{ + // Check for conflicts with built in operator names + for (int i=0; m_bBuiltInOp && iIgnoreUndefVar(true); + CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it + // may contain references to nonexisting variables. + m_pParseFormula = &QmuParserBase::ParseString; + m_pTokenReader->IgnoreUndefVar(false); + } + catch(exception_type &e) + { + // Make sure to stay in string parse mode, dont call ReInit() + // because it deletes the array with the used variables + m_pParseFormula = &QmuParserBase::ParseString; + m_pTokenReader->IgnoreUndefVar(false); + throw e; + } + return m_pTokenReader->GetUsedVar(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return a map containing the used variables only. + */ +const varmap_type& QmuParserBase::GetVar() const +{ + return m_VarDef; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return a map containing all parser constants. + */ +const valmap_type& QmuParserBase::GetConst() const +{ + return m_ConstDef; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return prototypes of all parser functions. + * @return #m_FunDef + * @sa FunProt + * @throw nothrow + * + * The return type is a map of the public type #funmap_type containing the prototype definitions for all numerical + * parser functions. String functions are not part of this map. The Prototype definition is encapsulated in objects + * of the class FunProt one per parser function each associated with function names via a map construct. + */ +const funmap_type& QmuParserBase::GetFunDef() const +{ + return m_FunDef; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Retrieve the formula. + */ +const QString& QmuParserBase::GetExpr() const +{ + return m_pTokenReader->GetExpr(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Execute a function that takes a single string argument. + * @param a_FunTok Function token. + * @throw exception_type If the function token is not a string function + */ +QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, + const QVector &a_vArg) const +{ + if (a_vArg.back().GetCode()!=cmSTRING) + { + Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); + } + + token_type valTok; + generic_fun_type pFunc = a_FunTok.GetFuncAddr(); + assert(pFunc); + + try + { + // Check function arguments; write dummy value into valtok to represent the result + switch(a_FunTok.GetArgCount()) + { + case 0: + valTok.SetVal(1); + a_vArg[0].GetAsString(); + break; + case 1: + valTok.SetVal(1); + a_vArg[1].GetAsString(); + a_vArg[0].GetVal(); + break; + case 2: + valTok.SetVal(1); + a_vArg[2].GetAsString(); + a_vArg[1].GetVal(); + a_vArg[0].GetVal(); + break; + default: + Error(ecINTERNAL_ERROR); + break; + } + } + catch(QmuParserError& ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); + } + + // string functions won't be optimized + m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx()); + + // Push dummy value representing the function result to the stack + return valTok; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Apply a function token. + * @param iArgCount Number of Arguments actually gathered used only for multiarg functions. + * @post The result is pushed to the value stack + * @post The function token is removed from the stack + * @throw exception_type if Argument count does not mach function requirements. + */ +void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const +{ + assert(m_pTokenReader.get()); + + // Operator stack empty or does not contain tokens with callback functions + if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 ) + { + return; + } + + token_type funTok = a_stOpt.pop(); + assert(funTok.GetFuncAddr()); + + // Binary operators must rely on their internal operator number + // since counting of operators relies on commas for function arguments + // binary operators do not have commas in their expression + int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount; + + // determine how many parameters the function needs. To remember iArgCount includes the + // string parameter whilst GetArgCount() counts only numeric parameters. + int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0); + + // Thats the number of numerical parameters + int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0); + + if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1) + { + Error(ecINTERNAL_ERROR); + } + + if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) + { + Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); + } + + if (funTok.GetCode()!=cmOPRT_BIN && iArgCountGetPos()-1, funTok.GetAsString()); + } + + if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired ) + { + Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); + } + + // Collect the numeric function arguments from the value stack and store them + // in a vector + QVector stArg; + for (int i=0; iGetPos(), funTok.GetAsString()); + } + } + + switch(funTok.GetCode()) + { + case cmFUNC_STR: + stArg.push_back(a_stVal.pop()); + + if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); + } + + ApplyStrFunc(funTok, stArg); + break; + case cmFUNC_BULK: + m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); + break; + case cmOPRT_BIN: + case cmOPRT_POSTFIX: + case cmOPRT_INFIX: + case cmFUNC: + if (funTok.GetArgCount()==-1 && iArgCount==0) + { + Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); + } + + m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); + break; + } + // Push dummy value representing the function result to the stack + token_type token; + token.SetVal(1); + a_stVal.push(token); +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const +{ + // Check if there is an if Else clause to be calculated + while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) + { + token_type opElse = a_stOpt.pop(); + Q_ASSERT(a_stOpt.size()>0); + + // Take the value associated with the else branch from the value stack + token_type vVal2 = a_stVal.pop(); + + Q_ASSERT(a_stOpt.size()>0); + Q_ASSERT(a_stVal.size()>=2); + + // it then else is a ternary operator Pop all three values from the value s + // tack and just return the right value + token_type vVal1 = a_stVal.pop(); + token_type vExpr = a_stVal.pop(); + + a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2); + + token_type opIf = a_stOpt.pop(); + Q_ASSERT(opElse.GetCode()==cmELSE); + Q_ASSERT(opIf.GetCode()==cmIF); + + m_vRPN.AddIfElse(cmENDIF); + } // while pending if-else-clause found +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Performs the necessary steps to write code for the execution of binary operators into the bytecode. + */ +void QmuParserBase::ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const +{ + // is it a user defined binary operator? + if (a_stOpt.top().GetCode()==cmOPRT_BIN) + { + ApplyFunc(a_stOpt, a_stVal, 2); + } + else + { + Q_ASSERT(a_stVal.size()>=2); + token_type valTok1 = a_stVal.pop(), + valTok2 = a_stVal.pop(), + optTok = a_stOpt.pop(), + resTok; + + if ( valTok1.GetType()!=valTok2.GetType() || (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) ) + { + Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString()); + } + + if (optTok.GetCode()==cmASSIGN) + { + if (valTok2.GetCode()!=cmVAR) + { + Error(ecUNEXPECTED_OPERATOR, -1, "="); + } + m_vRPN.AddAssignOp(valTok2.GetVar()); + } + else + { + m_vRPN.AddOp(optTok.GetCode()); + } + resTok.SetVal(1); + a_stVal.push(resTok); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Apply a binary operator. + * @param a_stOpt The operator stack + * @param a_stVal The value stack + */ +void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStack &stVal) const +{ + while (stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmIF) + { + token_type tok = stOpt.top(); + switch (tok.GetCode()) + { + case cmOPRT_INFIX: + case cmOPRT_BIN: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmLT: + case cmGT: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmLAND: + case cmLOR: + case cmASSIGN: + if (stOpt.top().GetCode()==cmOPRT_INFIX) + { + ApplyFunc(stOpt, stVal, 1); + } + else + { + ApplyBinOprt(stOpt, stVal); + } + break; + case cmELSE: + ApplyIfElse(stOpt, stVal); + break; + default: + Error(ecINTERNAL_ERROR); + break; + } + } +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Parse the command code. + * @sa ParseString(...) + * + * Command code contains precalculated stack positions of the values and the associated operators. The Stack is + * filled beginning from index one the value at index zero is not used at all. + */ +qreal QmuParserBase::ParseCmdCode() const +{ + return ParseCmdCodeBulk(0, 0); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Evaluate the RPN. + * @param nOffset The offset added to variable addresses (for bulk mode) + * @param nThreadID OpenMP Thread id of the calling thread + */ +qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const +{ + assert(nThreadID<=s_MaxNumOpenMPThreads); + + // Note: The check for nOffset==0 and nThreadID here is not necessary but + // brings a minor performance gain when not in bulk mode. + qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * + (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; + qreal buf; + int sidx(0); + for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) + { + switch (pTok->Cmd) + { + // built in binary operators + case cmLE: + --sidx; + Stack[sidx] = Stack[sidx] <= Stack[sidx+1]; + continue; + case cmGE: + --sidx; + Stack[sidx] = Stack[sidx] >= Stack[sidx+1]; + continue; + case cmNEQ: + --sidx; + Stack[sidx] = Stack[sidx] != Stack[sidx+1]; + continue; + case cmEQ: + --sidx; + Stack[sidx] = Stack[sidx] == Stack[sidx+1]; + continue; + case cmLT: + --sidx; + Stack[sidx] = Stack[sidx] < Stack[sidx+1]; + continue; + case cmGT: + --sidx; + Stack[sidx] = Stack[sidx] > Stack[sidx+1]; + continue; + case cmADD: + --sidx; + Stack[sidx] += Stack[1+sidx]; + continue; + case cmSUB: + --sidx; + Stack[sidx] -= Stack[1+sidx]; + continue; + case cmMUL: + --sidx; + Stack[sidx] *= Stack[1+sidx]; + continue; + case cmDIV: + --sidx; + #if defined(MUP_MATH_EXCEPTIONS) + if (Stack[1+sidx]==0) + { + Error(ecDIV_BY_ZERO); + } + #endif + Stack[sidx] /= Stack[1+sidx]; + continue; + case cmPOW: + --sidx; + Stack[sidx] = qPow(Stack[sidx], Stack[1+sidx]); + continue; + case cmLAND: + --sidx; + Stack[sidx] = Stack[sidx] && Stack[sidx+1]; + continue; + case cmLOR: + --sidx; + Stack[sidx] = Stack[sidx] || Stack[sidx+1]; + continue; + case cmASSIGN: + --sidx; + Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; + continue; + //case cmBO: // unused, listed for compiler optimization purposes + //case cmBC: + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + case cmIF: + if (Stack[sidx--]==0) + { + pTok += pTok->Oprt.offset; + } + continue; + case cmELSE: + pTok += pTok->Oprt.offset; + continue; + case cmENDIF: + continue; + //case cmARG_SEP: + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + + // value and variable tokens + case cmVAR: + Stack[++sidx] = *(pTok->Val.ptr + nOffset); + continue; + case cmVAL: + Stack[++sidx] = pTok->Val.data2; + continue; + case cmVARPOW2: + buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf; + continue; + case cmVARPOW3: + buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf*buf; + continue; + case cmVARPOW4: + buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf*buf*buf; + continue; + case cmVARMUL: + Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2; + continue; + // Next is treatment of numeric functions + case cmFUNC: + { + int iArgCount = pTok->Fun.argc; + + // switch according to argument count + switch(iArgCount) + { + case 0: + sidx += 1; + Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); + continue; + case 1: + Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); + continue; + case 2: + sidx -= 1; + Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); + continue; + case 3: + sidx -= 2; + Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); + continue; + case 4: + sidx -= 3; + Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3]); + continue; + case 5: + sidx -= 4; + Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4]); + continue; + case 6: + sidx -= 5; + Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); + continue; + case 7: + sidx -= 6; + Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); + continue; + case 8: + sidx -= 7; + Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); + continue; + case 9: + sidx -= 8; + Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], + Stack[sidx+8]); + continue; + case 10: + sidx -= 9; + Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], + Stack[sidx+8], Stack[sidx+9]); + continue; + default: + if (iArgCount>0) // function with variable arguments store the number as a negative value + { + Error(ecINTERNAL_ERROR, 1); + } + + sidx -= -iArgCount - 1; + Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount); + continue; + } + } + // Next is treatment of string functions + case cmFUNC_STR: + { + sidx -= pTok->Fun.argc -1; + + // The index of the string argument in the string table + int iIdxStack = pTok->Fun.idx; + Q_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); + + switch(pTok->Fun.argc) // switch according to argument count + { + case 0: + Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); + continue; + case 1: + Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); + continue; + case 2: + Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx], + Stack[sidx+1]); + continue; + } + + continue; + } + + case cmFUNC_BULK: + { + int iArgCount = pTok->Fun.argc; + + // switch according to argument count + switch(iArgCount) + { + case 0: + sidx += 1; + Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); + continue; + case 1: + Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); + continue; + case 2: + sidx -= 1; + Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1]); + continue; + case 3: + sidx -= 2; + Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2]); + continue; + case 4: + sidx -= 3; + Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); + continue; + case 5: + sidx -= 4; + Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4]); + continue; + case 6: + sidx -= 5; + Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); + continue; + case 7: + sidx -= 6; + Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); + continue; + case 8: + sidx -= 7; + Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); + continue; + case 9: + sidx -= 8; + Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); + continue; + case 10: + sidx -= 9; + Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], + Stack[sidx+9]); + continue; + default: + Error(ecINTERNAL_ERROR, 2); + continue; + } + } + //case cmSTRING: + //case cmOPRT_BIN: + //case cmOPRT_POSTFIX: + //case cmOPRT_INFIX: + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + + //case cmEND: + // return Stack[m_nFinalResultIdx]; + + default: + Error(ecINTERNAL_ERROR, 3); + return 0; + } // switch CmdCode + } // for all bytecode tokens + + return Stack[m_nFinalResultIdx]; +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::CreateRPN() const +{ + if (!m_pTokenReader->GetExpr().length()) + { + Error(ecUNEXPECTED_EOF, 0); + } + + QStack stOpt, stVal; + QStack stArgCount; + token_type opta, opt; // for storing operators + token_type val, tval; // for storing value + string_type strBuf; // buffer for string function arguments + + ReInit(); + + // The outermost counter counts the number of seperated items + // such as in "a=10,b=20,c=c+a" + stArgCount.push(1); + + for(;;) + { + opt = m_pTokenReader->ReadNextToken(); + + switch (opt.GetCode()) + { + // + // Next three are different kind of value entries + // + case cmSTRING: + opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token + stVal.push(opt); + m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer + break; + case cmVAR: + stVal.push(opt); + m_vRPN.AddVar( static_cast(opt.GetVar()) ); + break; + case cmVAL: + stVal.push(opt); + m_vRPN.AddVal( opt.GetVal() ); + break; + case cmELSE: + m_nIfElseCounter--; + if (m_nIfElseCounter<0) + { + Error(ecMISPLACED_COLON, m_pTokenReader->GetPos()); + } + ApplyRemainingOprt(stOpt, stVal); + m_vRPN.AddIfElse(cmELSE); + stOpt.push(opt); + break; + case cmARG_SEP: + if (stArgCount.empty()) + { + Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); + } + ++stArgCount.top(); + // fallthrough intentional (no break!) + case cmEND: + ApplyRemainingOprt(stOpt, stVal); + break; + case cmBC: + { + // The argument count for parameterless functions is zero + // by default an opening bracket sets parameter count to 1 + // in preparation of arguments to come. If the last token + // was an opening bracket we know better... + if (opta.GetCode()==cmBO) + { + --stArgCount.top(); + } + + ApplyRemainingOprt(stOpt, stVal); + + // Check if the bracket content has been evaluated completely + if (stOpt.size() && stOpt.top().GetCode()==cmBO) + { + // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check + // if there is either a function or a sign pending + // neither the opening nor the closing bracket will be pushed back to + // the operator stack + // Check if a function is standing in front of the opening bracket, + // if yes evaluate it afterwards check for infix operators + assert(stArgCount.size()); + int iArgCount = stArgCount.pop(); + + stOpt.pop(); // Take opening bracket from stack + + if (iArgCount>1 && ( stOpt.size()==0 || (stOpt.top().GetCode()!=cmFUNC && + stOpt.top().GetCode()!=cmFUNC_BULK && + stOpt.top().GetCode()!=cmFUNC_STR) ) ) + { + Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos()); + } + + // The opening bracket was popped from the stack now check if there + // was a function before this bracket + if (stOpt.size() && stOpt.top().GetCode()!=cmOPRT_INFIX && stOpt.top().GetCode()!=cmOPRT_BIN && + stOpt.top().GetFuncAddr()!=0) + { + ApplyFunc(stOpt, stVal, iArgCount); + } + } + } // if bracket content is evaluated + break; + // + // Next are the binary operator entries + // + //case cmAND: // built in binary operators + //case cmOR: + //case cmXOR: + case cmIF: + m_nIfElseCounter++; + // fallthrough intentional (no break!) + case cmLAND: + case cmLOR: + case cmLT: + case cmGT: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmASSIGN: + case cmOPRT_BIN: + // A binary operator (user defined or built in) has been found. + while ( stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmELSE && + stOpt.top().GetCode() != cmIF) + { + int nPrec1 = GetOprtPrecedence(stOpt.top()), + nPrec2 = GetOprtPrecedence(opt); + + if (stOpt.top().GetCode()==opt.GetCode()) + { + // Deal with operator associativity + EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt); + if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || + (eOprtAsct==oaLEFT && (nPrec1 < nPrec2)) ) + { + break; + } + } + else if (nPrec1 < nPrec2) + { + // In case the operators are not equal the precedence decides alone... + break; + } + if (stOpt.top().GetCode()==cmOPRT_INFIX) + { + ApplyFunc(stOpt, stVal, 1); + } + else + { + ApplyBinOprt(stOpt, stVal); + } + } // while ( ... ) + + if (opt.GetCode()==cmIF) + { + m_vRPN.AddIfElse(opt.GetCode()); + } + + // The operator can't be evaluated right now, push back to the operator stack + stOpt.push(opt); + break; + // + // Last section contains functions and operators implicitely mapped to functions + // + case cmBO: + stArgCount.push(1); + stOpt.push(opt); + break; + case cmOPRT_INFIX: + case cmFUNC: + case cmFUNC_BULK: + case cmFUNC_STR: + stOpt.push(opt); + break; + case cmOPRT_POSTFIX: + stOpt.push(opt); + ApplyFunc(stOpt, stVal, 1); // this is the postfix operator + break; + default: + Error(ecINTERNAL_ERROR, 3); + } // end of switch operator-token + + opta = opt; + + if ( opt.GetCode() == cmEND ) + { + m_vRPN.Finalize(); + break; + } + + if (QmuParserBase::g_DbgDumpStack) + { + StackDump(stVal, stOpt); + m_vRPN.AsciiDump(); + } + } // while (true) + + if (QmuParserBase::g_DbgDumpCmdCode) + { + m_vRPN.AsciiDump(); + } + + if (m_nIfElseCounter>0) + { + Error(ecMISSING_ELSE_CLAUSE); + } + + // get the last value (= final result) from the stack + Q_ASSERT(stArgCount.size()==1); + m_nFinalResultIdx = stArgCount.top(); + if (m_nFinalResultIdx==0) + { + Error(ecINTERNAL_ERROR, 9); + } + + if (stVal.size()==0) + { + Error(ecEMPTY_EXPRESSION); + } + + if (stVal.top().GetType()!=tpDBL) + { + Error(ecSTR_RESULT); + } + + m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief One of the two main parse functions. + * @sa ParseCmdCode(...) + * + * Parse expression from input string. Perform syntax checking and create bytecode. After parsing the string and + * creating the bytecode the function pointer #m_pParseFormula will be changed to the second parse routine the + * uses bytecode instead of string parsing. + */ +qreal QmuParserBase::ParseString() const +{ + try + { + CreateRPN(); + m_pParseFormula = &QmuParserBase::ParseCmdCode; + return (this->*m_pParseFormula)(); + } + catch(QmuParserError &exc) + { + exc.SetFormula(m_pTokenReader->GetExpr()); + throw; + } +} + +//---------------------------------------------------------------------------------------------------------------------- +/** +* @brief Create an error containing the parse error position. +* +* This function will create an Parser Exception object containing the error text and its position. +* +* @param a_iErrc [in] The error code of type #EErrorCodes. +* @param a_iPos [in] The position where the error was detected. +* @param a_strTok [in] The token string representation associated with the error. +* @throw ParserException always throws thats the only purpose of this function. +*/ +void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const +{ + throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined variables. + * @throw nothrow + * + * Resets the parser to string parsing mode by calling #ReInit. + */ +void QmuParserBase::ClearVar() +{ + m_VarDef.clear(); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Remove a variable from internal storage. + * @throw nothrow + * + * Removes a variable if it exists. If the Variable does not exist nothing will be done. + */ +void QmuParserBase::RemoveVar(const QString &a_strVarName) +{ + varmap_type::iterator item = m_VarDef.find(a_strVarName); + if (item!=m_VarDef.end()) + { + m_VarDef.erase(item); + ReInit(); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all functions. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearFun() +{ + m_FunDef.clear(); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined constants. + * + * Both numeric and string constants will be removed from the internal storage. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearConst() +{ + m_ConstDef.clear(); + m_StrVarDef.clear(); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined postfix operators. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearPostfixOprt() +{ + m_PostOprtDef.clear(); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined binary operators. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearOprt() +{ + m_OprtDef.clear(); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear the user defined Prefix operators. + * @post Resets the parser to string parser mode. + * @throw nothrow + */ +void QmuParserBase::ClearInfixOprt() +{ + m_InfixOprtDef.clear(); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Enable or disable the formula optimization feature. + * @post Resets the parser to string parser mode. + * @throw nothrow + */ +void QmuParserBase::EnableOptimizer(bool a_bIsOn) +{ + m_vRPN.EnableOptimizer(a_bIsOn); + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Enable the dumping of bytecode amd stack content on the console. + * @param bDumpCmd Flag to enable dumping of the current bytecode to the console. + * @param bDumpStack Flag to enable dumping of the stack content is written to the console. + * + * This function is for debug purposes only! + */ +void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) +{ + QmuParserBase::g_DbgDumpCmdCode = bDumpCmd; + QmuParserBase::g_DbgDumpStack = bDumpStack; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Enable or disable the built in binary operators. + * @throw nothrow + * @sa m_bBuiltInOp, ReInit() + * + * If you disable the built in binary operators there will be no binary operators defined. Thus you must add them + * manually one by one. It is not possible to disable built in operators selectively. This function will Reinitialize + * the parser by calling ReInit(). + */ +void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) +{ + m_bBuiltInOp = a_bIsOn; + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Query status of built in variables. + * @return #m_bBuiltInOp; true if built in operators are enabled. + * @throw nothrow + */ +bool QmuParserBase::HasBuiltInOprt() const +{ + return m_bBuiltInOp; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Get the argument separator character. + */ +QChar QmuParserBase::GetArgSep() const +{ + return m_pTokenReader->GetArgSep(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set argument separator. + * @param cArgSep the argument separator character. + */ +void QmuParserBase::SetArgSep(char_type cArgSep) +{ + m_pTokenReader->SetArgSep(cArgSep); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Dump stack content. + * + * This function is used for debugging only. + */ +void QmuParserBase::StackDump(const QStack &a_stVal, const QStack &a_stOprt) const +{ + QStack stOprt(a_stOprt), + stVal(a_stVal); + + qDebug() << "\nValue stack:\n"; + while ( !stVal.empty() ) + { + token_type val = stVal.pop(); + if (val.GetType()==tpSTR) + { + qDebug() << " \"" << val.GetAsString() << "\" "; + } + else + { + qDebug() << " " << val.GetVal() << " "; + } + } + qDebug() << "\nOperator stack:\n"; + + while ( !stOprt.empty() ) + { + if (stOprt.top().GetCode()<=cmASSIGN) + { + qDebug() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << "\" \n"; + } + else + { + switch(stOprt.top().GetCode()) + { + case cmVAR: + qDebug() << "VAR\n"; + break; + case cmVAL: + qDebug() << "VAL\n"; + break; + case cmFUNC: + qDebug() << "FUNC \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmFUNC_BULK: + qDebug() << "FUNC_BULK \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmOPRT_INFIX: + qDebug() << "OPRT_INFIX \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmOPRT_BIN: + qDebug() << "OPRT_BIN \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmFUNC_STR: + qDebug() << "FUNC_STR\n"; + break; + case cmEND: + qDebug() << "END\n"; + break; + case cmUNKNOWN: + qDebug() << "UNKNOWN\n"; + break; + case cmBO: + qDebug() << "BRACKET \"(\"\n"; + break; + case cmBC: + qDebug() << "BRACKET \")\"\n"; + break; + case cmIF: + qDebug() << "IF\n"; + break; + case cmELSE: + qDebug() << "ELSE\n"; + break; + case cmENDIF: + qDebug() << "ENDIF\n"; + break; + default: + qDebug() << stOprt.top().GetCode() << " "; + break; + } + } + stOprt.pop(); + } + qDebug() << dec; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** @brief Evaluate an expression containing comma seperated subexpressions + * @param [out] nStackSize The total number of results available + * @return Pointer to the array containing all expression results + * + * This member function can be used to retriev all results of an expression made up of multiple comma seperated + * subexpressions (i.e. "x+y,sin(x),cos(y)") */ - void QmuParserBase::DefineVar(const QString &a_sName, qreal *a_pVar) - { - if (a_pVar==0) - { - Error(ecINVALID_VAR_PTR); - } - - // Test if a constant with that names already exists - if (m_ConstDef.find(a_sName)!=m_ConstDef.end()) - { - Error(ecNAME_CONFLICT); - } - - CheckName(a_sName, ValidNameChars()); - m_VarDef[a_sName] = a_pVar; - ReInit(); - } - - //--------------------------------------------------------------------------- - /** \brief Add a user defined constant. - \param [in] a_sName The name of the constant. - \param [in] a_fVal the value of the constant. - \post Will reset the Parser to string parsing mode. - \throw ParserException in case the name contains invalid signs. - */ - void QmuParserBase::DefineConst(const QString &a_sName, qreal a_fVal) - { - CheckName(a_sName, ValidNameChars()); - m_ConstDef[a_sName] = a_fVal; - ReInit(); - } - - //--------------------------------------------------------------------------- - /** \brief Get operator priority. - \throw ParserException if a_Oprt is no operator code - */ - int QmuParserBase::GetOprtPrecedence(const token_type &a_Tok) const - { - switch (a_Tok.GetCode()) - { - // built in operators - case cmEND: return -5; - case cmARG_SEP: return -4; - case cmASSIGN: return -1; - case cmELSE: - case cmIF: return 0; - case cmLAND: return prLAND; - case cmLOR: return prLOR; - case cmLT: - case cmGT: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: return prCMP; - case cmADD: - case cmSUB: return prADD_SUB; - case cmMUL: - case cmDIV: return prMUL_DIV; - case cmPOW: return prPOW; - - // user defined binary operators - case cmOPRT_INFIX: - case cmOPRT_BIN: return a_Tok.GetPri(); - default: Error(ecINTERNAL_ERROR, 5); - return 999; - } - } - - //--------------------------------------------------------------------------- - /** \brief Get operator priority. - \throw ParserException if a_Oprt is no operator code - */ - EOprtAssociativity QmuParserBase::GetOprtAssociativity(const token_type &a_Tok) const - { - switch (a_Tok.GetCode()) - { - case cmASSIGN: - case cmLAND: - case cmLOR: - case cmLT: - case cmGT: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: return oaLEFT; - case cmPOW: return oaRIGHT; - case cmOPRT_BIN: return a_Tok.GetAssociativity(); - default: return oaNONE; - } - } - - //--------------------------------------------------------------------------- - /** \brief Return a map containing the used variables only. */ - const varmap_type& QmuParserBase::GetUsedVar() const - { - try - { - m_pTokenReader->IgnoreUndefVar(true); - CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it - // may contain references to nonexisting variables. - m_pParseFormula = &QmuParserBase::ParseString; - m_pTokenReader->IgnoreUndefVar(false); - } - catch(exception_type &e) - { - // Make sure to stay in string parse mode, dont call ReInit() - // because it deletes the array with the used variables - m_pParseFormula = &QmuParserBase::ParseString; - m_pTokenReader->IgnoreUndefVar(false); - throw e; - } - - return m_pTokenReader->GetUsedVar(); - } - - //--------------------------------------------------------------------------- - /** \brief Return a map containing the used variables only. */ - const varmap_type& QmuParserBase::GetVar() const - { - return m_VarDef; - } - - //--------------------------------------------------------------------------- - /** \brief Return a map containing all parser constants. */ - const valmap_type& QmuParserBase::GetConst() const - { - return m_ConstDef; - } - - //--------------------------------------------------------------------------- - /** \brief Return prototypes of all parser functions. - \return #m_FunDef - \sa FunProt - \throw nothrow - - The return type is a map of the public type #funmap_type containing the prototype - definitions for all numerical parser functions. String functions are not part of - this map. The Prototype definition is encapsulated in objects of the class FunProt - one per parser function each associated with function names via a map construct. - */ - const funmap_type& QmuParserBase::GetFunDef() const - { - return m_FunDef; - } - - //--------------------------------------------------------------------------- - /** \brief Retrieve the formula. */ - const QString& QmuParserBase::GetExpr() const - { - return m_pTokenReader->GetExpr(); - } - - //--------------------------------------------------------------------------- - /** \brief Execute a function that takes a single string argument. - \param a_FunTok Function token. - \throw exception_type If the function token is not a string function - */ - QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, - const QVector &a_vArg) const - { - if (a_vArg.back().GetCode()!=cmSTRING) - Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); - - token_type valTok; - generic_fun_type pFunc = a_FunTok.GetFuncAddr(); - assert(pFunc); - - try - { - // Check function arguments; write dummy value into valtok to represent the result - switch(a_FunTok.GetArgCount()) - { - case 0: valTok.SetVal(1); a_vArg[0].GetAsString(); break; - case 1: valTok.SetVal(1); a_vArg[1].GetAsString(); a_vArg[0].GetVal(); break; - case 2: valTok.SetVal(1); a_vArg[2].GetAsString(); a_vArg[1].GetVal(); a_vArg[0].GetVal(); break; - default: Error(ecINTERNAL_ERROR); - } - } - catch(QmuParserError& ) - { - Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); - } - - // string functions won't be optimized - m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx()); - - // Push dummy value representing the function result to the stack - return valTok; - } - - //--------------------------------------------------------------------------- - /** \brief Apply a function token. - \param iArgCount Number of Arguments actually gathered used only for multiarg functions. - \post The result is pushed to the value stack - \post The function token is removed from the stack - \throw exception_type if Argument count does not mach function requirements. - */ - void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const - { - assert(m_pTokenReader.get()); - - // Operator stack empty or does not contain tokens with callback functions - if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 ) - return; - - token_type funTok = a_stOpt.pop(); - assert(funTok.GetFuncAddr()); - - // Binary operators must rely on their internal operator number - // since counting of operators relies on commas for function arguments - // binary operators do not have commas in their expression - int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount; - - // determine how many parameters the function needs. To remember iArgCount includes the - // string parameter whilst GetArgCount() counts only numeric parameters. - int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0); - - // Thats the number of numerical parameters - int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0); - - if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1) - Error(ecINTERNAL_ERROR); - - if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) - Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); - - if (funTok.GetCode()!=cmOPRT_BIN && iArgCountGetPos()-1, funTok.GetAsString()); - - if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired ) - Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); - - // Collect the numeric function arguments from the value stack and store them - // in a vector - QVector stArg; - for (int i=0; iGetPos(), funTok.GetAsString()); - } - - switch(funTok.GetCode()) - { - case cmFUNC_STR: - stArg.push_back(a_stVal.pop()); - - if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) - Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); - - ApplyStrFunc(funTok, stArg); - break; - - case cmFUNC_BULK: - m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); - break; - - case cmOPRT_BIN: - case cmOPRT_POSTFIX: - case cmOPRT_INFIX: - case cmFUNC: - if (funTok.GetArgCount()==-1 && iArgCount==0) - Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); - - m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); - break; - } - - // Push dummy value representing the function result to the stack - token_type token; - token.SetVal(1); - a_stVal.push(token); - } - - //--------------------------------------------------------------------------- - void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const - { - // Check if there is an if Else clause to be calculated - while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) - { - token_type opElse = a_stOpt.pop(); - Q_ASSERT(a_stOpt.size()>0); - - // Take the value associated with the else branch from the value stack - token_type vVal2 = a_stVal.pop(); - - Q_ASSERT(a_stOpt.size()>0); - Q_ASSERT(a_stVal.size()>=2); - - // it then else is a ternary operator Pop all three values from the value s - // tack and just return the right value - token_type vVal1 = a_stVal.pop(); - token_type vExpr = a_stVal.pop(); - - a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2); - - token_type opIf = a_stOpt.pop(); - Q_ASSERT(opElse.GetCode()==cmELSE); - Q_ASSERT(opIf.GetCode()==cmIF); - - m_vRPN.AddIfElse(cmENDIF); - } // while pending if-else-clause found - } - - //--------------------------------------------------------------------------- - /** \brief Performs the necessary steps to write code for - the execution of binary operators into the bytecode. - */ - void QmuParserBase::ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const - { - // is it a user defined binary operator? - if (a_stOpt.top().GetCode()==cmOPRT_BIN) - { - ApplyFunc(a_stOpt, a_stVal, 2); - } - else - { - Q_ASSERT(a_stVal.size()>=2); - token_type valTok1 = a_stVal.pop(), - valTok2 = a_stVal.pop(), - optTok = a_stOpt.pop(), - resTok; - - if ( valTok1.GetType()!=valTok2.GetType() || - (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) ) - Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString()); - - if (optTok.GetCode()==cmASSIGN) - { - if (valTok2.GetCode()!=cmVAR) - Error(ecUNEXPECTED_OPERATOR, -1, "="); - - m_vRPN.AddAssignOp(valTok2.GetVar()); - } - else - m_vRPN.AddOp(optTok.GetCode()); - - resTok.SetVal(1); - a_stVal.push(resTok); - } - } - - //--------------------------------------------------------------------------- - /** \brief Apply a binary operator. - \param a_stOpt The operator stack - \param a_stVal The value stack - */ - void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStack &stVal) const - { - while (stOpt.size() && - stOpt.top().GetCode() != cmBO && - stOpt.top().GetCode() != cmIF) - { - token_type tok = stOpt.top(); - switch (tok.GetCode()) - { - case cmOPRT_INFIX: - case cmOPRT_BIN: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmLT: - case cmGT: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: - case cmPOW: - case cmLAND: - case cmLOR: - case cmASSIGN: - if (stOpt.top().GetCode()==cmOPRT_INFIX) - ApplyFunc(stOpt, stVal, 1); - else - ApplyBinOprt(stOpt, stVal); - break; - - case cmELSE: - ApplyIfElse(stOpt, stVal); - break; - - default: - Error(ecINTERNAL_ERROR); - } - } - } - - //--------------------------------------------------------------------------- - /** \brief Parse the command code. - \sa ParseString(...) - - Command code contains precalculated stack positions of the values and the - associated operators. The Stack is filled beginning from index one the - value at index zero is not used at all. - */ - qreal QmuParserBase::ParseCmdCode() const - { - return ParseCmdCodeBulk(0, 0); - } - - //--------------------------------------------------------------------------- - /** \brief Evaluate the RPN. - \param nOffset The offset added to variable addresses (for bulk mode) - \param nThreadID OpenMP Thread id of the calling thread - */ - qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const - { - assert(nThreadID<=s_MaxNumOpenMPThreads); - - // Note: The check for nOffset==0 and nThreadID here is not necessary but - // brings a minor performance gain when not in bulk mode. - qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; - qreal buf; - int sidx(0); - for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) - { - switch (pTok->Cmd) - { - // built in binary operators - case cmLE: --sidx; Stack[sidx] = Stack[sidx] <= Stack[sidx+1]; continue; - case cmGE: --sidx; Stack[sidx] = Stack[sidx] >= Stack[sidx+1]; continue; - case cmNEQ: --sidx; Stack[sidx] = Stack[sidx] != Stack[sidx+1]; continue; - case cmEQ: --sidx; Stack[sidx] = Stack[sidx] == Stack[sidx+1]; continue; - case cmLT: --sidx; Stack[sidx] = Stack[sidx] < Stack[sidx+1]; continue; - case cmGT: --sidx; Stack[sidx] = Stack[sidx] > Stack[sidx+1]; continue; - case cmADD: --sidx; Stack[sidx] += Stack[1+sidx]; continue; - case cmSUB: --sidx; Stack[sidx] -= Stack[1+sidx]; continue; - case cmMUL: --sidx; Stack[sidx] *= Stack[1+sidx]; continue; - case cmDIV: --sidx; - - #if defined(MUP_MATH_EXCEPTIONS) - if (Stack[1+sidx]==0) - Error(ecDIV_BY_ZERO); - #endif - Stack[sidx] /= Stack[1+sidx]; - continue; - - case cmPOW: - --sidx; Stack[sidx] = std::pow(Stack[sidx], Stack[1+sidx]); - continue; - - case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue; - case cmLOR: --sidx; Stack[sidx] = Stack[sidx] || Stack[sidx+1]; continue; - - case cmASSIGN: - --sidx; Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; continue; - - //case cmBO: // unused, listed for compiler optimization purposes - //case cmBC: - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; - - case cmIF: - if (Stack[sidx--]==0) - pTok += pTok->Oprt.offset; - continue; - - case cmELSE: - pTok += pTok->Oprt.offset; - continue; - - case cmENDIF: - continue; - - //case cmARG_SEP: - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; - - // value and variable tokens - case cmVAR: Stack[++sidx] = *(pTok->Val.ptr + nOffset); continue; - case cmVAL: Stack[++sidx] = pTok->Val.data2; continue; - - case cmVARPOW2: buf = *(pTok->Val.ptr + nOffset); - Stack[++sidx] = buf*buf; - continue; - - case cmVARPOW3: buf = *(pTok->Val.ptr + nOffset); - Stack[++sidx] = buf*buf*buf; - continue; - - case cmVARPOW4: buf = *(pTok->Val.ptr + nOffset); - Stack[++sidx] = buf*buf*buf*buf; - continue; - - case cmVARMUL: Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2; - continue; - - // Next is treatment of numeric functions - case cmFUNC: - { - int iArgCount = pTok->Fun.argc; - - // switch according to argument count - switch(iArgCount) - { - case 0: sidx += 1; Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); continue; - case 1: Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); continue; - case 2: sidx -= 1; Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); continue; - case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue; - case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue; - case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; - case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; - case 7: sidx -= 6; Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; - case 8: sidx -= 7; Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue; - case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue; - case 10:sidx -= 9; Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue; - default: - if (iArgCount>0) // function with variable arguments store the number as a negative value - Error(ecINTERNAL_ERROR, 1); - - sidx -= -iArgCount - 1; - Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount); - continue; - } - } - - // Next is treatment of string functions - case cmFUNC_STR: - { - sidx -= pTok->Fun.argc -1; - - // The index of the string argument in the string table - int iIdxStack = pTok->Fun.idx; - Q_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); - - switch(pTok->Fun.argc) // switch according to argument count - { - case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); continue; - case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); continue; - case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx], Stack[sidx+1]); continue; - } - - continue; - } - - case cmFUNC_BULK: - { - int iArgCount = pTok->Fun.argc; - - // switch according to argument count - switch(iArgCount) - { - case 0: sidx += 1; Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); continue; - case 1: Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); continue; - case 2: sidx -= 1; Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue; - case 3: sidx -= 2; Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue; - case 4: sidx -= 3; Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue; - case 5: sidx -= 4; Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; - case 6: sidx -= 5; Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; - case 7: sidx -= 6; Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; - case 8: sidx -= 7; Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue; - case 9: sidx -= 8; Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue; - case 10:sidx -= 9; Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue; - default: - Error(ecINTERNAL_ERROR, 2); - continue; - } - } - - //case cmSTRING: - //case cmOPRT_BIN: - //case cmOPRT_POSTFIX: - //case cmOPRT_INFIX: - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; - - //case cmEND: - // return Stack[m_nFinalResultIdx]; - - default: - Error(ecINTERNAL_ERROR, 3); - return 0; - } // switch CmdCode - } // for all bytecode tokens - - return Stack[m_nFinalResultIdx]; - } - - //--------------------------------------------------------------------------- - void QmuParserBase::CreateRPN() const - { - if (!m_pTokenReader->GetExpr().length()) - Error(ecUNEXPECTED_EOF, 0); - - QStack stOpt, stVal; - QStack stArgCount; - token_type opta, opt; // for storing operators - token_type val, tval; // for storing value - string_type strBuf; // buffer for string function arguments - - ReInit(); - - // The outermost counter counts the number of seperated items - // such as in "a=10,b=20,c=c+a" - stArgCount.push(1); - - for(;;) - { - opt = m_pTokenReader->ReadNextToken(); - - switch (opt.GetCode()) - { - // - // Next three are different kind of value entries - // - case cmSTRING: - opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token - stVal.push(opt); - m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer - break; - - case cmVAR: - stVal.push(opt); - m_vRPN.AddVar( static_cast(opt.GetVar()) ); - break; - - case cmVAL: - stVal.push(opt); - m_vRPN.AddVal( opt.GetVal() ); - break; - - case cmELSE: - m_nIfElseCounter--; - if (m_nIfElseCounter<0) - Error(ecMISPLACED_COLON, m_pTokenReader->GetPos()); - - ApplyRemainingOprt(stOpt, stVal); - m_vRPN.AddIfElse(cmELSE); - stOpt.push(opt); - break; - - - case cmARG_SEP: - if (stArgCount.empty()) - Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); - - ++stArgCount.top(); - // fallthrough intentional (no break!) - - case cmEND: - ApplyRemainingOprt(stOpt, stVal); - break; - - case cmBC: - { - // The argument count for parameterless functions is zero - // by default an opening bracket sets parameter count to 1 - // in preparation of arguments to come. If the last token - // was an opening bracket we know better... - if (opta.GetCode()==cmBO) - --stArgCount.top(); - - ApplyRemainingOprt(stOpt, stVal); - - // Check if the bracket content has been evaluated completely - if (stOpt.size() && stOpt.top().GetCode()==cmBO) - { - // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check - // if there is either a function or a sign pending - // neither the opening nor the closing bracket will be pushed back to - // the operator stack - // Check if a function is standing in front of the opening bracket, - // if yes evaluate it afterwards check for infix operators - assert(stArgCount.size()); - int iArgCount = stArgCount.pop(); - - stOpt.pop(); // Take opening bracket from stack - - if (iArgCount>1 && ( stOpt.size()==0 || - (stOpt.top().GetCode()!=cmFUNC && - stOpt.top().GetCode()!=cmFUNC_BULK && - stOpt.top().GetCode()!=cmFUNC_STR) ) ) - Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos()); - - // The opening bracket was popped from the stack now check if there - // was a function before this bracket - if (stOpt.size() && - stOpt.top().GetCode()!=cmOPRT_INFIX && - stOpt.top().GetCode()!=cmOPRT_BIN && - stOpt.top().GetFuncAddr()!=0) - { - ApplyFunc(stOpt, stVal, iArgCount); - } - } - } // if bracket content is evaluated - break; - - // - // Next are the binary operator entries - // - //case cmAND: // built in binary operators - //case cmOR: - //case cmXOR: - case cmIF: - m_nIfElseCounter++; - // fallthrough intentional (no break!) - - case cmLAND: - case cmLOR: - case cmLT: - case cmGT: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: - case cmPOW: - case cmASSIGN: - case cmOPRT_BIN: - - // A binary operator (user defined or built in) has been found. - while ( stOpt.size() && - stOpt.top().GetCode() != cmBO && - stOpt.top().GetCode() != cmELSE && - stOpt.top().GetCode() != cmIF) - { - int nPrec1 = GetOprtPrecedence(stOpt.top()), - nPrec2 = GetOprtPrecedence(opt); - - if (stOpt.top().GetCode()==opt.GetCode()) - { - - // Deal with operator associativity - EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt); - if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || - (eOprtAsct==oaLEFT && (nPrec1 < nPrec2)) ) - { - break; - } - } - else if (nPrec1 < nPrec2) - { - // In case the operators are not equal the precedence decides alone... - break; - } - - if (stOpt.top().GetCode()==cmOPRT_INFIX) - ApplyFunc(stOpt, stVal, 1); - else - ApplyBinOprt(stOpt, stVal); - } // while ( ... ) - - if (opt.GetCode()==cmIF) - m_vRPN.AddIfElse(opt.GetCode()); - - // The operator can't be evaluated right now, push back to the operator stack - stOpt.push(opt); - break; - - // - // Last section contains functions and operators implicitely mapped to functions - // - case cmBO: - stArgCount.push(1); - stOpt.push(opt); - break; - - case cmOPRT_INFIX: - case cmFUNC: - case cmFUNC_BULK: - case cmFUNC_STR: - stOpt.push(opt); - break; - - case cmOPRT_POSTFIX: - stOpt.push(opt); - ApplyFunc(stOpt, stVal, 1); // this is the postfix operator - break; - - default: Error(ecINTERNAL_ERROR, 3); - } // end of switch operator-token - - opta = opt; - - if ( opt.GetCode() == cmEND ) - { - m_vRPN.Finalize(); - break; - } - - if (QmuParserBase::g_DbgDumpStack) - { - StackDump(stVal, stOpt); - m_vRPN.AsciiDump(); - } - } // while (true) - - if (QmuParserBase::g_DbgDumpCmdCode) - m_vRPN.AsciiDump(); - - if (m_nIfElseCounter>0) - Error(ecMISSING_ELSE_CLAUSE); - - // get the last value (= final result) from the stack - Q_ASSERT(stArgCount.size()==1); - m_nFinalResultIdx = stArgCount.top(); - if (m_nFinalResultIdx==0) - Error(ecINTERNAL_ERROR, 9); - - if (stVal.size()==0) - Error(ecEMPTY_EXPRESSION); - - if (stVal.top().GetType()!=tpDBL) - Error(ecSTR_RESULT); - - m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads); - } - - //--------------------------------------------------------------------------- - /** \brief One of the two main parse functions. - \sa ParseCmdCode(...) - - Parse expression from input string. Perform syntax checking and create - bytecode. After parsing the string and creating the bytecode the function - pointer #m_pParseFormula will be changed to the second parse routine the - uses bytecode instead of string parsing. - */ - qreal QmuParserBase::ParseString() const - { - try - { - CreateRPN(); - m_pParseFormula = &QmuParserBase::ParseCmdCode; - return (this->*m_pParseFormula)(); - } - catch(QmuParserError &exc) - { - exc.SetFormula(m_pTokenReader->GetExpr()); - throw; - } - } - - //--------------------------------------------------------------------------- - /** \brief Create an error containing the parse error position. - - This function will create an Parser Exception object containing the error text and - its position. - - \param a_iErrc [in] The error code of type #EErrorCodes. - \param a_iPos [in] The position where the error was detected. - \param a_strTok [in] The token string representation associated with the error. - \throw ParserException always throws thats the only purpose of this function. - */ - void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const - { - throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); - } - - //------------------------------------------------------------------------------ - /** \brief Clear all user defined variables. - \throw nothrow - - Resets the parser to string parsing mode by calling #ReInit. - */ - void QmuParserBase::ClearVar() - { - m_VarDef.clear(); - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Remove a variable from internal storage. - \throw nothrow - - Removes a variable if it exists. If the Variable does not exist nothing will be done. - */ - void QmuParserBase::RemoveVar(const QString &a_strVarName) - { - varmap_type::iterator item = m_VarDef.find(a_strVarName); - if (item!=m_VarDef.end()) - { - m_VarDef.erase(item); - ReInit(); - } - } - - //------------------------------------------------------------------------------ - /** \brief Clear all functions. - \post Resets the parser to string parsing mode. - \throw nothrow - */ - void QmuParserBase::ClearFun() - { - m_FunDef.clear(); - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Clear all user defined constants. - - Both numeric and string constants will be removed from the internal storage. - \post Resets the parser to string parsing mode. - \throw nothrow - */ - void QmuParserBase::ClearConst() - { - m_ConstDef.clear(); - m_StrVarDef.clear(); - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Clear all user defined postfix operators. - \post Resets the parser to string parsing mode. - \throw nothrow - */ - void QmuParserBase::ClearPostfixOprt() - { - m_PostOprtDef.clear(); - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Clear all user defined binary operators. - \post Resets the parser to string parsing mode. - \throw nothrow - */ - void QmuParserBase::ClearOprt() - { - m_OprtDef.clear(); - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Clear the user defined Prefix operators. - \post Resets the parser to string parser mode. - \throw nothrow - */ - void QmuParserBase::ClearInfixOprt() - { - m_InfixOprtDef.clear(); - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Enable or disable the formula optimization feature. - \post Resets the parser to string parser mode. - \throw nothrow - */ - void QmuParserBase::EnableOptimizer(bool a_bIsOn) - { - m_vRPN.EnableOptimizer(a_bIsOn); - ReInit(); - } - - //--------------------------------------------------------------------------- - /** \brief Enable the dumping of bytecode amd stack content on the console. - \param bDumpCmd Flag to enable dumping of the current bytecode to the console. - \param bDumpStack Flag to enable dumping of the stack content is written to the console. - - This function is for debug purposes only! - */ - void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) - { - QmuParserBase::g_DbgDumpCmdCode = bDumpCmd; - QmuParserBase::g_DbgDumpStack = bDumpStack; - } - - //------------------------------------------------------------------------------ - /** \brief Enable or disable the built in binary operators. - \throw nothrow - \sa m_bBuiltInOp, ReInit() - - If you disable the built in binary operators there will be no binary operators - defined. Thus you must add them manually one by one. It is not possible to - disable built in operators selectively. This function will Reinitialize the - parser by calling ReInit(). - */ - void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) - { - m_bBuiltInOp = a_bIsOn; - ReInit(); - } - - //------------------------------------------------------------------------------ - /** \brief Query status of built in variables. - \return #m_bBuiltInOp; true if built in operators are enabled. - \throw nothrow - */ - bool QmuParserBase::HasBuiltInOprt() const - { - return m_bBuiltInOp; - } - - //------------------------------------------------------------------------------ - /** \brief Get the argument separator character. - */ - QChar QmuParserBase::GetArgSep() const - { - return m_pTokenReader->GetArgSep(); - } - - //------------------------------------------------------------------------------ - /** \brief Set argument separator. - \param cArgSep the argument separator character. - */ - void QmuParserBase::SetArgSep(char_type cArgSep) - { - m_pTokenReader->SetArgSep(cArgSep); - } - - //------------------------------------------------------------------------------ - /** \brief Dump stack content. - - This function is used for debugging only. - */ - void QmuParserBase::StackDump(const QStack &a_stVal, - const QStack &a_stOprt) const - { - QStack stOprt(a_stOprt), - stVal(a_stVal); - - qDebug() << "\nValue stack:\n"; - while ( !stVal.empty() ) - { - token_type val = stVal.pop(); - if (val.GetType()==tpSTR) - qDebug() << " \"" << val.GetAsString() << "\" "; - else - qDebug() << " " << val.GetVal() << " "; - } - qDebug() << "\nOperator stack:\n"; - - while ( !stOprt.empty() ) - { - if (stOprt.top().GetCode()<=cmASSIGN) - { - qDebug() << "OPRT_INTRNL \"" - << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] - << "\" \n"; - } - else - { - switch(stOprt.top().GetCode()) - { - case cmVAR: qDebug() << "VAR\n"; break; - case cmVAL: qDebug() << "VAL\n"; break; - case cmFUNC: qDebug() << "FUNC \"" - << stOprt.top().GetAsString() - << "\"\n"; break; - case cmFUNC_BULK: qDebug() << "FUNC_BULK \"" - << stOprt.top().GetAsString() - << "\"\n"; break; - case cmOPRT_INFIX: qDebug() << "OPRT_INFIX \"" - << stOprt.top().GetAsString() - << "\"\n"; break; - case cmOPRT_BIN: qDebug() << "OPRT_BIN \"" - << stOprt.top().GetAsString() - << "\"\n"; break; - case cmFUNC_STR: qDebug() << "FUNC_STR\n"; break; - case cmEND: qDebug() << "END\n"; break; - case cmUNKNOWN: qDebug() << "UNKNOWN\n"; break; - case cmBO: qDebug() << "BRACKET \"(\"\n"; break; - case cmBC: qDebug() << "BRACKET \")\"\n"; break; - case cmIF: qDebug() << "IF\n"; break; - case cmELSE: qDebug() << "ELSE\n"; break; - case cmENDIF: qDebug() << "ENDIF\n"; break; - default: qDebug() << stOprt.top().GetCode() << " "; break; - } - } - stOprt.pop(); - } - - qDebug() << dec; - } - - //------------------------------------------------------------------------------ - /** \brief Evaluate an expression containing comma seperated subexpressions - \param [out] nStackSize The total number of results available - \return Pointer to the array containing all expression results - - This member function can be used to retriev all results of an expression - made up of multiple comma seperated subexpressions (i.e. "x+y,sin(x),cos(y)") - */ - qreal* QmuParserBase::Eval(int &nStackSize) const - { - (this->*m_pParseFormula)(); - nStackSize = m_nFinalResultIdx; - - // (for historic reasons the stack starts at position 1) - return &m_vStackBuffer[1]; - } - - //--------------------------------------------------------------------------- - /** \brief Return the number of results on the calculation stack. - - If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). - There mey be more than one return value. This function returns the number of - available results. - */ - int QmuParserBase::GetNumResults() const - { - return m_nFinalResultIdx; - } - - //--------------------------------------------------------------------------- - /** \brief Calculate the result. - - A note on const correctness: - I consider it important that Calc is a const function. - Due to caching operations Calc changes only the state of internal variables with one exception - m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making - Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. - - \pre A formula must be set. - \pre Variables must have been set (if needed) - - \sa #m_pParseFormula - \return The evaluation result - \throw ParseException if no Formula is set or in case of any other error related to the formula. - */ - qreal QmuParserBase::Eval() const - { - return (this->*m_pParseFormula)(); - } - - //--------------------------------------------------------------------------- - void QmuParserBase::Eval(qreal *results, int nBulkSize) - { - CreateRPN(); - - int i = 0; - -#ifdef MUP_USE_OPENMP -//#define DEBUG_OMP_STUFF - #ifdef DEBUG_OMP_STUFF - int *pThread = new int[nBulkSize]; - int *pIdx = new int[nBulkSize]; - #endif - - int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads); - int nThreadID, ct=0; - omp_set_num_threads(nMaxThreads); - - #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) - for (i=0; i*m_pParseFormula)(); + nStackSize = m_nFinalResultIdx; + + // (for historic reasons the stack starts at position 1) + return &m_vStackBuffer[1]; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the number of results on the calculation stack. + * + * If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). There mey be more than one return + * value. This function returns the number of available results. + */ +int QmuParserBase::GetNumResults() const +{ + return m_nFinalResultIdx; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Calculate the result. + * + * A note on const correctness: + * I consider it important that Calc is a const function. + * Due to caching operations Calc changes only the state of internal variables with one exception + * m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making + * Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. + * + * @pre A formula must be set. + * @pre Variables must have been set (if needed) + * + * @sa #m_pParseFormula + * @return The evaluation result + * @throw ParseException if no Formula is set or in case of any other error related to the formula. + */ +qreal QmuParserBase::Eval() const +{ + return (this->*m_pParseFormula)(); +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::Eval(qreal *results, int nBulkSize) +{ + CreateRPN(); + + int i = 0; + + #ifdef MUP_USE_OPENMP + //#define DEBUG_OMP_STUFF + #ifdef DEBUG_OMP_STUFF + int *pThread = new int[nBulkSize]; + int *pIdx = new int[nBulkSize]; + #endif + + int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads); + int nThreadID, ct=0; + omp_set_num_threads(nMaxThreads); + + #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) + for (i=0; i -#include -#include -#include -#include -#include #include #include #include -//--- Parser includes -------------------------------------------------------------------------- #include "qmuparserdef.h" #include "qmuparsertokenreader.h" #include "qmuparserbytecode.h" @@ -43,261 +35,227 @@ namespace qmu { -/** \file - \brief This file contains the class definition of the qmuparser engine. -*/ + /** + * @file + * @brief This file contains the class definition of the qmuparser engine. + */ -//-------------------------------------------------------------------------------------------------- -/** \brief Mathematical expressions parser (base parser engine). - \author (C) 2013 Ingo Berg - - This is the implementation of a bytecode based mathematical expressions parser. - The formula will be parsed from string and converted into a bytecode. - Future calculations will be done with the bytecode instead the formula string - resulting in a significant performance increase. - Complementary to a set of internally implemented functions the parser is able to handle - user defined functions and variables. -*/ -class QmuParserBase -{ -friend class QmuParserTokenReader; - -private: - - /** \brief Typedef for the parse functions. - - The parse function do the actual work. The parser exchanges - the function pointer to the parser function depending on - which state it is in. (i.e. bytecode parser vs. string parser) - */ - typedef qreal (QmuParserBase::*ParseFunction)() const; - - /** \brief Type used for storing an array of values. */ - typedef QVector valbuf_type; - - /** \brief Type for a vector of strings. */ - typedef QVector stringbuf_type; - - /** \brief Typedef for the token reader. */ - typedef QmuParserTokenReader token_reader_type; - - /** \brief Type used for parser tokens. */ - typedef QmuParserToken token_type; - - /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */ - static const int s_MaxNumOpenMPThreads = 4; - - public: - - /** \brief Type of the error class. - - Included for backwards compatibility. - */ - typedef QmuParserError exception_type; - - static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); - - QmuParserBase(); - QmuParserBase(const QmuParserBase &a_Parser); - QmuParserBase& operator=(const QmuParserBase &a_Parser); - - virtual ~QmuParserBase(); - - qreal Eval() const; - qreal* Eval(int &nStackSize) const; - void Eval(qreal *results, int nBulkSize); - - int GetNumResults() const; - - void SetExpr(const QString &a_sExpr); - void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); - - void SetDecSep(char_type cDecSep); - void SetThousandsSep(char_type cThousandsSep = 0); - void ResetLocale(); - - void EnableOptimizer(bool a_bIsOn=true); - void EnableBuiltInOprt(bool a_bIsOn=true); - - bool HasBuiltInOprt() const; - void AddValIdent(identfun_type a_pCallback); - - /** \fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) - \brief Define a parser function without arguments. - \param a_strName Name of the function - \param a_pFun Pointer to the callback function - \param a_bAllowOpt A flag indicating this function may be optimized - */ - template - void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) - { - AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); - } - - void DefineOprt(const QString &a_strName, - fun_type2 a_pFun, - unsigned a_iPri=0, - EOprtAssociativity a_eAssociativity = oaLEFT, - bool a_bAllowOpt = false); - void DefineConst(const QString &a_sName, qreal a_fVal); - void DefineStrConst(const QString &a_sName, const QString &a_strVal); - void DefineVar(const QString &a_sName, qreal *a_fVar); - void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); - void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); - - // Clear user defined variables, constants or functions - void ClearVar(); - void ClearFun(); - void ClearConst(); - void ClearInfixOprt(); - void ClearPostfixOprt(); - void ClearOprt(); - - void RemoveVar(const QString &a_strVarName); - const varmap_type& GetUsedVar() const; - const varmap_type& GetVar() const; - const valmap_type& GetConst() const; - const QString &GetExpr() const; - const funmap_type& GetFunDef() const; - string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const; - - const QStringList &GetOprtDef() const; - void DefineNameChars(const QString &a_szCharset); - void DefineOprtChars(const QString &a_szCharset); - void DefineInfixOprtChars(const QString &a_szCharset); - - const QString& ValidNameChars() const; - const QString &ValidOprtChars() const; - const QString &ValidInfixOprtChars() const; - - void SetArgSep(char_type cArgSep); - QChar GetArgSep() const; - - void Error(EErrorCodes a_iErrc, - int a_iPos = -1, - const QString &a_strTok = QString() ) const; - - protected: - - void Init(); - - virtual void InitCharSets() = 0; - virtual void InitFun() = 0; - virtual void InitConst() = 0; - virtual void InitOprt() = 0; - - virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd); - - static const QStringList c_DefaultOprt; - static std::locale s_locale; ///< The locale used by the parser - static bool g_DbgDumpCmdCode; - static bool g_DbgDumpStack; - - /** \brief A facet class used to change decimal and thousands separator. */ - template - class change_dec_sep : public std::numpunct + /** + * @brief Mathematical expressions parser (base parser engine). + * @author (C) 2013 Ingo Berg + * + * This is the implementation of a bytecode based mathematical expressions parser. + * The formula will be parsed from string and converted into a bytecode. + * Future calculations will be done with the bytecode instead the formula string + * resulting in a significant performance increase. + * Complementary to a set of internally implemented functions the parser is able to handle + * user defined functions and variables. + */ + class QmuParserBase { + friend class QmuParserTokenReader; public: - - explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) - :std::numpunct() - ,m_nGroup(nGroup) - ,m_cDecPoint(cDecSep) - ,m_cThousandsSep(cThousandsSep) - {} - + /** + * @brief Type of the error class. + * + * Included for backwards compatibility. + */ + typedef QmuParserError exception_type; + + QmuParserBase(); + QmuParserBase(const QmuParserBase &a_Parser); + QmuParserBase& operator=(const QmuParserBase &a_Parser); + virtual ~QmuParserBase(); + + static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); + qreal Eval() const; + qreal* Eval(int &nStackSize) const; + void Eval(qreal *results, int nBulkSize); + int GetNumResults() const; + void SetExpr(const QString &a_sExpr); + void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); + void SetDecSep(char_type cDecSep); + void SetThousandsSep(char_type cThousandsSep = 0); + void ResetLocale(); + void EnableOptimizer(bool a_bIsOn=true); + void EnableBuiltInOprt(bool a_bIsOn=true); + bool HasBuiltInOprt() const; + void AddValIdent(identfun_type a_pCallback); + void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, + EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); + void DefineConst(const QString &a_sName, qreal a_fVal); + void DefineStrConst(const QString &a_sName, const QString &a_strVal); + void DefineVar(const QString &a_sName, qreal *a_fVar); + void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); + void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, + bool a_bAllowOpt=true); + // Clear user defined variables, constants or functions + void ClearVar(); + void ClearFun(); + void ClearConst(); + void ClearInfixOprt(); + void ClearPostfixOprt(); + void ClearOprt(); + void RemoveVar(const QString &a_strVarName); + const varmap_type& GetUsedVar() const; + const varmap_type& GetVar() const; + const valmap_type& GetConst() const; + const QString& GetExpr() const; + const funmap_type& GetFunDef() const; + QString GetVersion(EParserVersionInfo eInfo = pviFULL) const; + const QStringList& GetOprtDef() const; + void DefineNameChars(const QString &a_szCharset); + void DefineOprtChars(const QString &a_szCharset); + void DefineInfixOprtChars(const QString &a_szCharset); + const QString& ValidNameChars() const; + const QString& ValidOprtChars() const; + const QString& ValidInfixOprtChars() const; + void SetArgSep(char_type cArgSep); + QChar GetArgSep() const; + void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; + /** + * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, + * bool a_bAllowOpt = true) + * @brief Define a parser function without arguments. + * @param a_strName Name of the function + * @param a_pFun Pointer to the callback function + * @param a_bAllowOpt A flag indicating this function may be optimized + */ + template + void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) + { + AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); + } protected: - - virtual char_type do_decimal_point() const - { - return m_cDecPoint; - } + static const QStringList c_DefaultOprt; + static std::locale s_locale; ///< The locale used by the parser + static bool g_DbgDumpCmdCode; + static bool g_DbgDumpStack; + void Init(); + virtual void InitCharSets() = 0; + virtual void InitFun() = 0; + virtual void InitConst() = 0; + virtual void InitOprt() = 0; + virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd); + /** + * @brief A facet class used to change decimal and thousands separator. + */ + template + class change_dec_sep : public std::numpunct + { + public: + explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) + :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) + {} + protected: + virtual char_type do_decimal_point() const + { + return m_cDecPoint; + } - virtual char_type do_thousands_sep() const - { - return m_cThousandsSep; - } - - virtual std::string do_grouping() const - { - return std::string(1, m_nGroup); - } + virtual char_type do_thousands_sep() const + { + return m_cThousandsSep; + } + virtual std::string do_grouping() const + { + return std::string(1, m_nGroup); + } + private: + int m_nGroup; + char_type m_cDecPoint; + char_type m_cThousandsSep; + }; private: + /** + * @brief Typedef for the parse functions. + * + * The parse function do the actual work. The parser exchanges + * the function pointer to the parser function depending on + * which state it is in. (i.e. bytecode parser vs. string parser) + */ + typedef qreal (QmuParserBase::*ParseFunction)() const; - int m_nGroup; - char_type m_cDecPoint; - char_type m_cThousandsSep; + /** + * @brief Type used for storing an array of values. + */ + typedef QVector valbuf_type; + + /** + * @brief Type for a vector of strings. + */ + typedef QVector stringbuf_type; + + /** + * @brief Typedef for the token reader. + */ + typedef QmuParserTokenReader token_reader_type; + + /** + * @brief Type used for parser tokens. + */ + typedef QmuParserToken token_type; + + /** + * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. + */ + static const int s_MaxNumOpenMPThreads = 4; + + /** + * @brief Pointer to the parser function. + * + * Eval() calls the function whose address is stored there. + */ + mutable ParseFunction m_pParseFormula; + mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. + mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments + stringbuf_type m_vStringVarBuf; + + std::auto_ptr m_pTokenReader; ///< Managed pointer to the token reader object. + + funmap_type m_FunDef; ///< Map of function names and pointers. + funmap_type m_PostOprtDef; ///< Postfix operator callbacks + funmap_type m_InfixOprtDef; ///< unary infix operator. + funmap_type m_OprtDef; ///< Binary operator callbacks + valmap_type m_ConstDef; ///< user constants. + strmap_type m_StrVarDef; ///< user defined string constants + varmap_type m_VarDef; ///< user defind variables. + + bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off + + QString m_sNameChars; ///< Charset for names + QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens + QString m_sInfixOprtChars; ///< Charset for infix operator tokens + + mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses + + // items merely used for caching state information + mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine + mutable int m_nFinalResultIdx; + + void Assign(const QmuParserBase &a_Parser); + void InitTokenReader(); + void ReInit() const; + void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, + funmap_type &a_Storage, const QString &a_szCharSet ); + void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; + token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; + int GetOprtPrecedence(const token_type &a_Tok) const; + EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; + void CreateRPN() const; + qreal ParseString() const; + qreal ParseCmdCode() const; + qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; + void CheckName(const QString &a_strName, const QString &a_CharSet) const; + void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, + const QString &a_szCharSet) const; + void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; }; - private: - - void Assign(const QmuParserBase &a_Parser); - void InitTokenReader(); - void ReInit() const; - - void AddCallback(const QString &a_strName, - const QmuParserCallback &a_Callback, - funmap_type &a_Storage, - const QString &a_szCharSet ); - - void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; - - token_type ApplyStrFunc(const token_type &a_FunTok, - const QVector &a_vArg) const; - - int GetOprtPrecedence(const token_type &a_Tok) const; - EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; - - void CreateRPN() const; - - qreal ParseString() const; - qreal ParseCmdCode() const; - qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; - - void CheckName(const QString &a_strName, const QString &a_CharSet) const; - void CheckOprt(const QString &a_sName, - const QmuParserCallback &a_Callback, - const QString &a_szCharSet) const; - - void StackDump(const QStack &a_stVal, - const QStack &a_stOprt) const; - - /** \brief Pointer to the parser function. - - Eval() calls the function whose address is stored there. - */ - mutable ParseFunction m_pParseFormula; - mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. - mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments - stringbuf_type m_vStringVarBuf; - - std::auto_ptr m_pTokenReader; ///< Managed pointer to the token reader object. - - funmap_type m_FunDef; ///< Map of function names and pointers. - funmap_type m_PostOprtDef; ///< Postfix operator callbacks - funmap_type m_InfixOprtDef; ///< unary infix operator. - funmap_type m_OprtDef; ///< Binary operator callbacks - valmap_type m_ConstDef; ///< user constants. - strmap_type m_StrVarDef; ///< user defined string constants - varmap_type m_VarDef; ///< user defind variables. - - bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off - - QString m_sNameChars; ///< Charset for names - QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens - QString m_sInfixOprtChars; ///< Charset for infix operator tokens - - mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses - - // items merely used for caching state information - mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine - mutable int m_nFinalResultIdx; -}; - } // namespace qmu #endif diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 5665417f3..495f7f6a0 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -35,534 +35,617 @@ namespace qmu { - //--------------------------------------------------------------------------- - /** \brief Bytecode default constructor. */ - QmuParserByteCode::QmuParserByteCode() - :m_iStackPos(0) - ,m_iMaxStackSize(0) - ,m_vRPN() - ,m_bEnableOptimizer(true) - { - m_vRPN.reserve(50); - } - - //--------------------------------------------------------------------------- - /** \brief Copy constructor. - - Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) - */ - QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) - { - Assign(a_ByteCode); - } - - //--------------------------------------------------------------------------- - /** \brief Assignment operator. - - Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) - */ - QmuParserByteCode& QmuParserByteCode::operator=(const QmuParserByteCode &a_ByteCode) - { - Assign(a_ByteCode); - return *this; - } - - //--------------------------------------------------------------------------- - void QmuParserByteCode::EnableOptimizer(bool bStat) - { - m_bEnableOptimizer = bStat; - } - - //--------------------------------------------------------------------------- - /** \brief Copy state of another object to this. - - \throw nowthrow - */ - void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) - { - if (this==&a_ByteCode) - return; - - m_iStackPos = a_ByteCode.m_iStackPos; - m_vRPN = a_ByteCode.m_vRPN; - m_iMaxStackSize = a_ByteCode.m_iMaxStackSize; - } - - //--------------------------------------------------------------------------- - /** \brief Add a Variable pointer to bytecode. - \param a_pVar Pointer to be added. - \throw nothrow - */ - void QmuParserByteCode::AddVar(qreal *a_pVar) - { - ++m_iStackPos; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); - - // optimization does not apply - SToken tok; - tok.Cmd = cmVAR; - tok.Val.ptr = a_pVar; - tok.Val.data = 1; - tok.Val.data2 = 0; - m_vRPN.push_back(tok); - } - - //--------------------------------------------------------------------------- - /** \brief Add a Variable pointer to bytecode. - - Value entries in byte code consist of: -
    -
  • value array position of the value
  • -
  • the operator code according to ParserToken::cmVAL
  • -
  • the value stored in #mc_iSizeVal number of bytecode entries.
  • -
- - \param a_pVal Value to be added. - \throw nothrow - */ - void QmuParserByteCode::AddVal(qreal a_fVal) - { - ++m_iStackPos; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); - - // If optimization does not apply - SToken tok; - tok.Cmd = cmVAL; - tok.Val.ptr = NULL; - tok.Val.data = 0; - tok.Val.data2 = a_fVal; - m_vRPN.push_back(tok); - } - - //--------------------------------------------------------------------------- - void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) - { - std::size_t sz = m_vRPN.size(); - qreal &x = m_vRPN[sz-2].Val.data2, - &y = m_vRPN[sz-1].Val.data2; - switch (a_Oprt) - { - case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break; - case cmLOR: x = (int)x || (int)y; m_vRPN.pop_back(); break; - case cmLT: x = x < y; m_vRPN.pop_back(); break; - case cmGT: x = x > y; m_vRPN.pop_back(); break; - case cmLE: x = x <= y; m_vRPN.pop_back(); break; - case cmGE: x = x >= y; m_vRPN.pop_back(); break; - case cmNEQ: x = x != y; m_vRPN.pop_back(); break; - case cmEQ: x = x == y; m_vRPN.pop_back(); break; - case cmADD: x = x + y; m_vRPN.pop_back(); break; - case cmSUB: x = x - y; m_vRPN.pop_back(); break; - case cmMUL: x = x * y; m_vRPN.pop_back(); break; - case cmDIV: - -#if defined(MUP_MATH_EXCEPTIONS) - if (y==0) - throw ParserError(ecDIV_BY_ZERO, "0"); -#endif - - x = x / y; - m_vRPN.pop_back(); - break; - - case cmPOW: x = std::pow(x, y); - m_vRPN.pop_back(); - break; - - default: - break; - } // switch opcode - } - - //--------------------------------------------------------------------------- - /** \brief Add an operator identifier to bytecode. - - Operator entries in byte code consist of: -
    -
  • value array position of the result
  • -
  • the operator code according to ParserToken::ECmdCode
  • -
- - \sa ParserToken::ECmdCode - */ - void QmuParserByteCode::AddOp(ECmdCode a_Oprt) - { - bool bOptimized = false; - - if (m_bEnableOptimizer) - { - std::size_t sz = m_vRPN.size(); - - // Check for foldable constants like: - // cmVAL cmVAL cmADD - // where cmADD can stand fopr any binary operator applied to - // two constant values. - if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL) - { - ConstantFolding(a_Oprt); - bOptimized = true; - } - else - { - switch(a_Oprt) - { - case cmPOW: - // Optimization for ploynomials of low order - if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) - { - if (m_vRPN[sz-1].Val.data2==2) - m_vRPN[sz-2].Cmd = cmVARPOW2; - else if (m_vRPN[sz-1].Val.data2==3) - m_vRPN[sz-2].Cmd = cmVARPOW3; - else if (m_vRPN[sz-1].Val.data2==4) - m_vRPN[sz-2].Cmd = cmVARPOW4; - else - break; - - m_vRPN.pop_back(); - bOptimized = true; - } - break; - - case cmSUB: - case cmADD: - // Simple optimization based on pattern recognition for a shitload of different - // bytecode combinations of addition/subtraction - if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || - (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) || - (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) || - (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || - (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) - { - assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) || - (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || - (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); - - m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable - m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset - m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior - m_vRPN.pop_back(); - bOptimized = true; - } - break; - - case cmMUL: - if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || - (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) - { - m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); - m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 = 0; - m_vRPN.pop_back(); - bOptimized = true; - } - else if ( (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ) - { - // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 - m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); - if (m_vRPN[sz-1].Cmd == cmVAL) - { - m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2; - } - else - { - m_vRPN[sz-2].Val.data = m_vRPN[sz-1].Val.data * m_vRPN[sz-2].Val.data2; - m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2; - } - m_vRPN.pop_back(); - bOptimized = true; - } - else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && - m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr) - { - // Optimization: a*a -> a^2 - m_vRPN[sz-2].Cmd = cmVARPOW2; - m_vRPN.pop_back(); - bOptimized = true; - } - break; - - case cmDIV: - if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0) - { - // Optimization: 4*a/2 -> 2*a - m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; - m_vRPN.pop_back(); - bOptimized = true; - } - break; - - } // switch a_Oprt - } - } - - // If optimization can't be applied just write the value - if (!bOptimized) - { - --m_iStackPos; - SToken tok; - tok.Cmd = a_Oprt; - m_vRPN.push_back(tok); - } - } - - //--------------------------------------------------------------------------- - void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt) - { - SToken tok; - tok.Cmd = a_Oprt; - m_vRPN.push_back(tok); - } - - //--------------------------------------------------------------------------- - /** \brief Add an assignement operator - - Operator entries in byte code consist of: -
    -
  • cmASSIGN code
  • -
  • the pointer of the destination variable
  • -
- - \sa ParserToken::ECmdCode - */ - void QmuParserByteCode::AddAssignOp(qreal *a_pVar) - { - --m_iStackPos; - - SToken tok; - tok.Cmd = cmASSIGN; - tok.Val.ptr = a_pVar; - m_vRPN.push_back(tok); - } - - //--------------------------------------------------------------------------- - /** \brief Add function to bytecode. - - \param a_iArgc Number of arguments, negative numbers indicate multiarg functions. - \param a_pFun Pointer to function callback. - */ - void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) - { - if (a_iArgc>=0) - { - m_iStackPos = m_iStackPos - a_iArgc + 1; - } - else - { - // function with unlimited number of arguments - m_iStackPos = m_iStackPos + a_iArgc + 1; - } - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); - - SToken tok; - tok.Cmd = cmFUNC; - tok.Fun.argc = a_iArgc; - tok.Fun.ptr = a_pFun; - m_vRPN.push_back(tok); - } - - //--------------------------------------------------------------------------- - /** \brief Add a bulk function to bytecode. - - \param a_iArgc Number of arguments, negative numbers indicate multiarg functions. - \param a_pFun Pointer to function callback. - */ - void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) - { - m_iStackPos = m_iStackPos - a_iArgc + 1; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); - - SToken tok; - tok.Cmd = cmFUNC_BULK; - tok.Fun.argc = a_iArgc; - tok.Fun.ptr = a_pFun; - m_vRPN.push_back(tok); - } - - //--------------------------------------------------------------------------- - /** \brief Add Strung function entry to the parser bytecode. - \throw nothrow - - A string function entry consists of the stack position of the return value, - followed by a cmSTRFUNC code, the function pointer and an index into the - string buffer maintained by the parser. - */ - void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) - { - m_iStackPos = m_iStackPos - a_iArgc + 1; - - SToken tok; - tok.Cmd = cmFUNC_STR; - tok.Fun.argc = a_iArgc; - tok.Fun.idx = a_iIdx; - tok.Fun.ptr = a_pFun; - m_vRPN.push_back(tok); - - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); - } - - //--------------------------------------------------------------------------- - /** \brief Add end marker to bytecode. - - \throw nothrow - */ - void QmuParserByteCode::Finalize() - { - SToken tok; - tok.Cmd = cmEND; - m_vRPN.push_back(tok); - rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit - - // Determine the if-then-else jump offsets - QStack stIf, stElse; - int idx; - for (int i=0; i<(int)m_vRPN.size(); ++i) - { - switch(m_vRPN[i].Cmd) - { - case cmIF: - stIf.push(i); - break; - - case cmELSE: - stElse.push(i); - idx = stIf.pop(); - m_vRPN[idx].Oprt.offset = i - idx; - break; - - case cmENDIF: - idx = stElse.pop(); - m_vRPN[idx].Oprt.offset = i - idx; - break; - - default: - break; - } - } - } - - //--------------------------------------------------------------------------- - const SToken* QmuParserByteCode::GetBase() const - { - if (m_vRPN.size()==0) - throw QmuParserError(ecINTERNAL_ERROR); - else - return &m_vRPN[0]; - } - - //--------------------------------------------------------------------------- - std::size_t QmuParserByteCode::GetMaxStackSize() const - { - return m_iMaxStackSize+1; - } - - //--------------------------------------------------------------------------- - /** \brief Returns the number of entries in the bytecode. */ - std::size_t QmuParserByteCode::GetSize() const - { - return m_vRPN.size(); - } - - //--------------------------------------------------------------------------- - /** \brief Delete the bytecode. - - \throw nothrow - - The name of this function is a violation of my own coding guidelines - but this way it's more in line with the STL functions thus more - intuitive. - */ - void QmuParserByteCode::clear() - { - m_vRPN.clear(); - m_iStackPos = 0; - m_iMaxStackSize = 0; - } - - //--------------------------------------------------------------------------- - /** \brief Dump bytecode (for debugging only!). */ - void QmuParserByteCode::AsciiDump() - { - if (!m_vRPN.size()) - { - qDebug() << "No bytecode available\n"; - return; - } - - qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n"; - for (std::size_t i=0; i + *
  • value array position of the value
  • + *
  • the operator code according to ParserToken::cmVAL
  • + *
  • the value stored in #mc_iSizeVal number of bytecode entries.
  • + * + * + * @param a_pVal Value to be added. + * @throw nothrow + */ +void QmuParserByteCode::AddVal(qreal a_fVal) +{ + ++m_iStackPos; + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + // If optimization does not apply + SToken tok; + tok.Cmd = cmVAL; + tok.Val.ptr = NULL; + tok.Val.data = 0; + tok.Val.data2 = a_fVal; + m_vRPN.push_back(tok); +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) +{ + std::size_t sz = m_vRPN.size(); + qreal &x = m_vRPN[sz-2].Val.data2, + &y = m_vRPN[sz-1].Val.data2; + switch (a_Oprt) + { + case cmLAND: + x = (int)x && (int)y; + m_vRPN.pop_back(); + break; + case cmLOR: + x = (int)x || (int)y; + m_vRPN.pop_back(); + break; + case cmLT: + x = x < y; + m_vRPN.pop_back(); + break; + case cmGT: + x = x > y; + m_vRPN.pop_back(); + break; + case cmLE: + x = x <= y; + m_vRPN.pop_back(); + break; + case cmGE: + x = x >= y; + m_vRPN.pop_back(); + break; + case cmNEQ: + x = x != y; + m_vRPN.pop_back(); + break; + case cmEQ: + x = x == y; + m_vRPN.pop_back(); + break; + case cmADD: + x = x + y; + m_vRPN.pop_back(); + break; + case cmSUB: + x = x - y; + m_vRPN.pop_back(); + break; + case cmMUL: + x = x * y; + m_vRPN.pop_back(); + break; + case cmDIV: + #if defined(MUP_MATH_EXCEPTIONS) + if (y==0) + { + throw ParserError(ecDIV_BY_ZERO, "0"); + } + #endif + x = x / y; + m_vRPN.pop_back(); + break; + case cmPOW: + x = qPow(x, y); + m_vRPN.pop_back(); + break; + default: + break; + } // switch opcode +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add an operator identifier to bytecode. + * + * Operator entries in byte code consist of: + *
      + *
    • value array position of the result
    • + *
    • the operator code according to ParserToken::ECmdCode
    • + *
    + * + * @sa ParserToken::ECmdCode + */ +void QmuParserByteCode::AddOp(ECmdCode a_Oprt) +{ + bool bOptimized = false; + + if (m_bEnableOptimizer) + { + std::size_t sz = m_vRPN.size(); + + // Check for foldable constants like: + // cmVAL cmVAL cmADD + // where cmADD can stand fopr any binary operator applied to + // two constant values. + if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL) + { + ConstantFolding(a_Oprt); + bOptimized = true; + } + else + { + switch(a_Oprt) + { + case cmPOW: + // Optimization for ploynomials of low order + if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) + { + if (m_vRPN[sz-1].Val.data2==2) + { + m_vRPN[sz-2].Cmd = cmVARPOW2; + } + else if (m_vRPN[sz-1].Val.data2==3) + { + m_vRPN[sz-2].Cmd = cmVARPOW3; + } + else if (m_vRPN[sz-1].Val.data2==4) + { + m_vRPN[sz-2].Cmd = cmVARPOW4; + } + else + { + break; + } + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + case cmSUB: + case cmADD: + // Simple optimization based on pattern recognition for a shitload of different + // bytecode combinations of addition/subtraction + if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL + && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && + m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) + { + assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) || + (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || + (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); + + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | + (long long)(m_vRPN[sz-1].Val.ptr)); // variable + m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset + m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior + m_vRPN.pop_back(); + bOptimized = true; + } + break; + case cmMUL: + if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) + { + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | + (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 = 0; + m_vRPN.pop_back(); + bOptimized = true; + } + else if ( (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ) + { + // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | + (long long)(m_vRPN[sz-1].Val.ptr)); + if (m_vRPN[sz-1].Cmd == cmVAL) + { + m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2; + } + else + { + m_vRPN[sz-2].Val.data = m_vRPN[sz-1].Val.data * m_vRPN[sz-2].Val.data2; + m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2; + } + m_vRPN.pop_back(); + bOptimized = true; + } + else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr) + { + // Optimization: a*a -> a^2 + m_vRPN[sz-2].Cmd = cmVARPOW2; + m_vRPN.pop_back(); + bOptimized = true; + } + break; + case cmDIV: + if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0) + { + // Optimization: 4*a/2 -> 2*a + m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + } // switch a_Oprt + } + } + + // If optimization can't be applied just write the value + if (!bOptimized) + { + --m_iStackPos; + SToken tok; + tok.Cmd = a_Oprt; + m_vRPN.push_back(tok); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt) +{ + SToken tok; + tok.Cmd = a_Oprt; + m_vRPN.push_back(tok); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add an assignement operator + * + * Operator entries in byte code consist of: + *
      + *
    • cmASSIGN code
    • + *
    • the pointer of the destination variable
    • + *
    + * + * @sa ParserToken::ECmdCode + */ +void QmuParserByteCode::AddAssignOp(qreal *a_pVar) +{ + --m_iStackPos; + + SToken tok; + tok.Cmd = cmASSIGN; + tok.Val.ptr = a_pVar; + m_vRPN.push_back(tok); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add function to bytecode. + * + * @param a_iArgc Number of arguments, negative numbers indicate multiarg functions. + * @param a_pFun Pointer to function callback. + */ +void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) +{ + if (a_iArgc>=0) + { + m_iStackPos = m_iStackPos - a_iArgc + 1; + } + else + { + // function with unlimited number of arguments + m_iStackPos = m_iStackPos + a_iArgc + 1; + } + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + SToken tok; + tok.Cmd = cmFUNC; + tok.Fun.argc = a_iArgc; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a bulk function to bytecode. + * + * @param a_iArgc Number of arguments, negative numbers indicate multiarg functions. + * @param a_pFun Pointer to function callback. + */ +void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) +{ + m_iStackPos = m_iStackPos - a_iArgc + 1; + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + + SToken tok; + tok.Cmd = cmFUNC_BULK; + tok.Fun.argc = a_iArgc; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add Strung function entry to the parser bytecode. + * @throw nothrow + * + * A string function entry consists of the stack position of the return value, followed by a cmSTRFUNC code, the + * function pointer and an index into the string buffer maintained by the parser. + */ +void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) +{ + m_iStackPos = m_iStackPos - a_iArgc + 1; + + SToken tok; + tok.Cmd = cmFUNC_STR; + tok.Fun.argc = a_iArgc; + tok.Fun.idx = a_iIdx; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); + + m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add end marker to bytecode. + * + * @throw nothrow + */ +void QmuParserByteCode::Finalize() +{ + SToken tok; + tok.Cmd = cmEND; + m_vRPN.push_back(tok); + rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit + + // Determine the if-then-else jump offsets + QStack stIf, stElse; + int idx; + for (int i=0; i<(int)m_vRPN.size(); ++i) + { + switch(m_vRPN[i].Cmd) + { + case cmIF: + stIf.push(i); + break; + case cmELSE: + stElse.push(i); + idx = stIf.pop(); + m_vRPN[idx].Oprt.offset = i - idx; + break; + case cmENDIF: + idx = stElse.pop(); + m_vRPN[idx].Oprt.offset = i - idx; + break; + default: + break; + } + } +} + +//---------------------------------------------------------------------------------------------------------------------- +const SToken* QmuParserByteCode::GetBase() const +{ + if (m_vRPN.size()==0) + { + throw QmuParserError(ecINTERNAL_ERROR); + } + else + { + return &m_vRPN[0]; + } +} + +//---------------------------------------------------------------------------------------------------------------------- +std::size_t QmuParserByteCode::GetMaxStackSize() const +{ + return m_iMaxStackSize+1; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the number of entries in the bytecode. + */ +std::size_t QmuParserByteCode::GetSize() const +{ + return m_vRPN.size(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Delete the bytecode. + * + * @throw nothrow + * + * The name of this function is a violation of my own coding guidelines but this way it's more in line with the STL + * functions thus more intuitive. + */ +void QmuParserByteCode::clear() +{ + m_vRPN.clear(); + m_iStackPos = 0; + m_iMaxStackSize = 0; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Dump bytecode (for debugging only!). + */ +void QmuParserByteCode::AsciiDump() +{ + if (!m_vRPN.size()) + { + qDebug() << "No bytecode available\n"; + return; + } + + qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n"; + for (std::size_t i=0; i -#include -#include - #include "qmuparserdef.h" #include "qmuparsererror.h" #include "qmuparsertoken.h" -/** \file - \brief Definition of the parser bytecode class. -*/ - +/** + * @file + * @brief Definition of the parser bytecode class. + */ namespace qmu { - struct SToken - { - ECmdCode Cmd; - int StackPos; +struct SToken +{ + ECmdCode Cmd; + int StackPos; - union - { - struct //SValData - { - qreal *ptr; - qreal data; - qreal data2; - } Val; + union + { + struct //SValData + { + qreal *ptr; + qreal data; + qreal data2; + } Val; - struct //SFunData - { - // Note: generic_fun_type is merely a placeholder. The real type could be - // anything between gun_type1 and fun_type9. I can't use a void - // pointer due to constraints in the ANSI standard which allows - // data pointers and function pointers to differ in size. - generic_fun_type ptr; - int argc; - int idx; - } Fun; + struct //SFunData + { + // Note: generic_fun_type is merely a placeholder. The real type could be + // anything between gun_type1 and fun_type9. I can't use a void + // pointer due to constraints in the ANSI standard which allows + // data pointers and function pointers to differ in size. + generic_fun_type ptr; + int argc; + int idx; + } Fun; - struct //SOprtData - { - qreal *ptr; - int offset; - } Oprt; - }; - }; + struct //SOprtData + { + qreal *ptr; + int offset; + } Oprt; + }; +}; - /** \brief Bytecode implementation of the Math Parser. - - The bytecode contains the formula converted to revers polish notation stored in a continious - memory area. Associated with this data are operator codes, variable pointers, constant - values and function pointers. Those are necessary in order to calculate the result. - All those data items will be casted to the underlying datatype of the bytecode. - - \author (C) 2004-2013 Ingo Berg -*/ +/** + * @brief Bytecode implementation of the Math Parser. + * + * The bytecode contains the formula converted to revers polish notation stored in a continious + * memory area. Associated with this data are operator codes, variable pointers, constant + * values and function pointers. Those are necessary in order to calculate the result. + * All those data items will be casted to the underlying datatype of the bytecode. + * + * @author (C) 2004-2013 Ingo Berg + */ class QmuParserByteCode { private: - - /** \brief Token type for internal use only. */ + /** @brief Token type for internal use only. */ typedef QmuParserToken token_type; - /** \brief Token vector for storing the RPN. */ + /** @brief Token vector for storing the RPN. */ typedef QVector rpn_type; - /** \brief Position in the Calculation array. */ + /** @brief Position in the Calculation array. */ unsigned m_iStackPos; - /** \brief Maximum size needed for the stack. */ + /** @brief Maximum size needed for the stack. */ std::size_t m_iMaxStackSize; - /** \brief The actual rpn storage. */ + /** @brief The actual rpn storage. */ rpn_type m_vRPN; bool m_bEnableOptimizer; void ConstantFolding(ECmdCode a_Oprt); - public: - QmuParserByteCode(); QmuParserByteCode(const QmuParserByteCode &a_ByteCode); QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); - void Assign(const QmuParserByteCode &a_ByteCode); - - void AddVar(qreal *a_pVar); - void AddVal(qreal a_fVal); - void AddOp(ECmdCode a_Oprt); - void AddIfElse(ECmdCode a_Oprt); - void AddAssignOp(qreal *a_pVar); - void AddFun(generic_fun_type a_pFun, int a_iArgc); - void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); - void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); - - void EnableOptimizer(bool bStat); - - void Finalize(); - void clear(); - std::size_t GetMaxStackSize() const; - std::size_t GetSize() const; - + void Assign(const QmuParserByteCode &a_ByteCode); + void AddVar(qreal *a_pVar); + void AddVal(qreal a_fVal); + void AddOp(ECmdCode a_Oprt); + void AddIfElse(ECmdCode a_Oprt); + void AddAssignOp(qreal *a_pVar); + void AddFun(generic_fun_type a_pFun, int a_iArgc); + void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); + void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); + void EnableOptimizer(bool bStat); + void Finalize(); + void clear(); + std::size_t GetMaxStackSize() const; + std::size_t GetSize() const; const SToken* GetBase() const; - void AsciiDump(); + void AsciiDump(); }; - } // namespace qmu - #endif diff --git a/src/libs/qmuparser/qmuparsercallback.cpp b/src/libs/qmuparser/qmuparsercallback.cpp index 08bc21f2d..0a1db5ac9 100644 --- a/src/libs/qmuparser/qmuparsercallback.cpp +++ b/src/libs/qmuparser/qmuparsercallback.cpp @@ -1,460 +1,322 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include "qmuparsercallback.h" - -/** \file - \brief Implementation of the parser callback class. -*/ - - -namespace qmu -{ - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(0) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode) - :m_pFun((void*)a_pFun) - ,m_iArgc(1) - ,m_iPri(a_iPrec) - ,m_eOprtAsct(oaNONE) - ,m_iCode(a_iCode) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - /** \brief Constructor for constructing funcstion callbacks taking two arguments. - \throw nothrow - */ - QmuParserCallback::QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(2) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - /** \brief Constructor for constructing binary operator callbacks. - \param a_pFun Pointer to a static function taking two arguments - \param a_bAllowOpti A flag indicating this funcation can be optimized - \param a_iPrec The operator precedence - \param a_eOprtAsct The operators associativity - \throw nothrow - */ - QmuParserCallback::QmuParserCallback(fun_type2 a_pFun, - bool a_bAllowOpti, - int a_iPrec, - EOprtAssociativity a_eOprtAsct) - :m_pFun((void*)a_pFun) - ,m_iArgc(2) - ,m_iPri(a_iPrec) - ,m_eOprtAsct(a_eOprtAsct) - ,m_iCode(cmOPRT_BIN) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(3) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(4) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(5) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(6) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(7) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(8) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(9) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(10) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(0) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(1) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - /** \brief Constructor for constructing funcstion callbacks taking two arguments. - \throw nothrow - */ - QmuParserCallback::QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(2) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(3) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(4) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(5) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(6) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(7) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(8) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(9) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(10) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_BULK) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(-1) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC) - ,m_iType(tpDBL) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(0) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_STR) - ,m_iType(tpSTR) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(1) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_STR) - ,m_iType(tpSTR) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - QmuParserCallback::QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti) - :m_pFun((void*)a_pFun) - ,m_iArgc(2) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmFUNC_STR) - ,m_iType(tpSTR) - ,m_bAllowOpti(a_bAllowOpti) - {} - - - //--------------------------------------------------------------------------- - /** \brief Default constructor. - \throw nothrow - */ - QmuParserCallback::QmuParserCallback() - :m_pFun(0) - ,m_iArgc(0) - ,m_iPri(-1) - ,m_eOprtAsct(oaNONE) - ,m_iCode(cmUNKNOWN) - ,m_iType(tpVOID) - ,m_bAllowOpti(0) - {} - - - //--------------------------------------------------------------------------- - /** \brief Copy constructor. - \throw nothrow - */ - QmuParserCallback::QmuParserCallback(const QmuParserCallback &ref) - { - m_pFun = ref.m_pFun; - m_iArgc = ref.m_iArgc; - m_bAllowOpti = ref.m_bAllowOpti; - m_iCode = ref.m_iCode; - m_iType = ref.m_iType; - m_iPri = ref.m_iPri; - m_eOprtAsct = ref.m_eOprtAsct; - } - - //--------------------------------------------------------------------------- - /** \brief Clone this instance and return a pointer to the new instance. */ - QmuParserCallback* QmuParserCallback::Clone() const - { - return new QmuParserCallback(*this); - } - - //--------------------------------------------------------------------------- - /** \brief Return tru if the function is conservative. - - Conservative functions return always the same result for the same argument. - \throw nothrow - */ - bool QmuParserCallback::IsOptimizable() const - { - return m_bAllowOpti; - } - - //--------------------------------------------------------------------------- - /** \brief Get the callback address for the parser function. - - The type of the address is void. It needs to be recasted according to the - argument number to the right type. - - \throw nothrow - \return #pFun - */ - void* QmuParserCallback::GetAddr() const - { - return m_pFun; - } - - //--------------------------------------------------------------------------- - /** \brief Return the callback code. */ - ECmdCode QmuParserCallback::GetCode() const - { - return m_iCode; - } - - //--------------------------------------------------------------------------- - ETypeCode QmuParserCallback::GetType() const - { - return m_iType; - } - - - //--------------------------------------------------------------------------- - /** \brief Return the operator precedence. - \throw nothrown - - Only valid if the callback token is an operator token (binary or infix). - */ - int QmuParserCallback::GetPri() const - { - return m_iPri; - } - - //--------------------------------------------------------------------------- - /** \brief Return the operators associativity. - \throw nothrown - - Only valid if the callback token is a binary operator token. - */ - EOprtAssociativity QmuParserCallback::GetAssociativity() const - { - return m_eOprtAsct; - } - - //--------------------------------------------------------------------------- - /** \brief Returns the number of function Arguments. */ - int QmuParserCallback::GetArgc() const - { - return m_iArgc; - } -} // namespace qmu +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsercallback.h" + +/** + * @file + * @brief Implementation of the parser callback class. + */ + +namespace qmu +{ +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type0 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), m_iCode ( a_iCode ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor for constructing funcstion callbacks taking two arguments. + * @throw nothrow + */ +QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor for constructing binary operator callbacks. + * @param a_pFun Pointer to a static function taking two arguments + * @param a_bAllowOpti A flag indicating this funcation can be optimized + * @param a_iPrec The operator precedence + * @param a_eOprtAsct The operators associativity + * @throw nothrow + */ +QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, + EOprtAssociativity a_eOprtAsct ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), + m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor for constructing funcstion callbacks taking two arguments. + * @throw nothrow + */ +QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), + m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), + m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti ) + : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), + m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Default constructor. + * @throw nothrow + */ +QmuParserCallback::QmuParserCallback() + : m_pFun ( 0 ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), + m_bAllowOpti ( 0 ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy constructor. + * @throw nothrow + */ +QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref ) +{ + m_pFun = ref.m_pFun; + m_iArgc = ref.m_iArgc; + m_bAllowOpti = ref.m_bAllowOpti; + m_iCode = ref.m_iCode; + m_iType = ref.m_iType; + m_iPri = ref.m_iPri; + m_eOprtAsct = ref.m_eOprtAsct; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clone this instance and return a pointer to the new instance. + */ +QmuParserCallback* QmuParserCallback::Clone() const +{ + return new QmuParserCallback ( *this ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return tru if the function is conservative. + * + * Conservative functions return always the same result for the same argument. + * @throw nothrow + */ +bool QmuParserCallback::IsOptimizable() const +{ + return m_bAllowOpti; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Get the callback address for the parser function. + * + * The type of the address is void. It needs to be recasted according to the argument number to the right type. + * + * @throw nothrow + * @return #pFun + */ +void* QmuParserCallback::GetAddr() const +{ + return m_pFun; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the callback code. +*/ +ECmdCode QmuParserCallback::GetCode() const +{ + return m_iCode; +} + +//---------------------------------------------------------------------------------------------------------------------- +ETypeCode QmuParserCallback::GetType() const +{ + return m_iType; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the operator precedence. + * @throw nothrown + * + * Only valid if the callback token is an operator token (binary or infix). + */ +int QmuParserCallback::GetPri() const +{ + return m_iPri; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the operators associativity. + * @throw nothrown + * + * Only valid if the callback token is a binary operator token. + */ +EOprtAssociativity QmuParserCallback::GetAssociativity() const +{ + return m_eOprtAsct; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the number of function Arguments. + */ +int QmuParserCallback::GetArgc() const +{ + return m_iArgc; +} +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparsercallback.h b/src/libs/qmuparser/qmuparsercallback.h index de968d686..3fce55943 100644 --- a/src/libs/qmuparser/qmuparsercallback.h +++ b/src/libs/qmuparser/qmuparsercallback.h @@ -25,25 +25,24 @@ #include "qmuparserdef.h" -/** \file - \brief Definition of the parser callback class. -*/ +/** + * @file + * @brief Definition of the parser callback class. + */ namespace qmu { -/** \brief Encapsulation of prototypes for a numerical parser function. - - Encapsulates the prototyp for numerical parser functions. The class - stores the number of arguments for parser functions as well - as additional flags indication the function is non optimizeable. - The pointer to the callback function pointer is stored as void* - and needs to be casted according to the argument count. - Negative argument counts indicate a parser function with a variable number - of arguments. - - \author (C) 2004-2011 Ingo Berg -*/ +/** + * @brief Encapsulation of prototypes for a numerical parser function. + * + * Encapsulates the prototyp for numerical parser functions. The class stores the number of arguments for parser + * functions as well as additional flags indication the function is non optimizeable. The pointer to the callback + * function pointer is stored as void* and needs to be casted according to the argument count. Negative argument counts + * indicate a parser function with a variable number of arguments. + * + * @author (C) 2004-2011 Ingo Berg + */ class QmuParserCallback { public: @@ -80,23 +79,22 @@ public: QmuParserCallback(const QmuParserCallback &a_Fun); QmuParserCallback* Clone() const; - - bool IsOptimizable() const; - void* GetAddr() const; - ECmdCode GetCode() const; - ETypeCode GetType() const; - int GetPri() const; + bool IsOptimizable() const; + void* GetAddr() const; + ECmdCode GetCode() const; + ETypeCode GetType() const; + int GetPri() const; EOprtAssociativity GetAssociativity() const; - int GetArgc() const; - + int GetArgc() const; private: void *m_pFun; ///< Pointer to the callback function, casted to void - /** \brief Number of numeric function arguments - - This number is negative for functions with variable number of arguments. in this cases - they represent the actual number of arguments found. - */ + /** + * @brief Number of numeric function arguments + * + * This number is negative for functions with variable number of arguments. in this cases + * they represent the actual number of arguments found. + */ int m_iArgc; int m_iPri; ///< Valid only for binary and infix operators; Operator precedence. EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators @@ -105,8 +103,10 @@ private: bool m_bAllowOpti; ///< Flag indication optimizeability }; -//------------------------------------------------------------------------------ -/** \brief Container for Callback objects. */ +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Container for Callback objects. + */ typedef std::map funmap_type; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 0ecb3ac4a..4a1abd67e 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -1,281 +1,275 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPDEF_H -#define QMUPDEF_H - -#include -#include -#include -#include -#include -#include - -#include "qmuparserfixes.h" - -/** \file - \brief This file contains standard definitions used by the parser. -*/ - -#define QMUP_VERSION "2.2.3" -#define QMUP_VERSION_DATE "20121222; SF" - -#define QMUP_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - -/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */ -//#define QMUP_MATH_EXCEPTIONS - -/** \brief Activate this option in order to compile with OpenMP support. - - OpenMP is used only in the bulk mode it may increase the performance a bit. -*/ -//#define MUP_USE_OPENMP - -#if defined(_UNICODE) - /** \brief Definition of the basic parser string type. */ - #define QMUP_STRING_TYPE std::wstring -#else - /** \brief Definition of the basic parser string type. */ - #define QMUP_STRING_TYPE std::string -#endif - -namespace qmu -{ - //------------------------------------------------------------------------------ - /** \brief Bytecode values. - - \attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt! - */ - enum ECmdCode - { - // The following are codes for built in binary operators - // apart from built in operators the user has the opportunity to - // add user defined operators. - cmLE = 0, ///< Operator item: less or equal - cmGE = 1, ///< Operator item: greater or equal - cmNEQ = 2, ///< Operator item: not equal - cmEQ = 3, ///< Operator item: equals - cmLT = 4, ///< Operator item: less than - cmGT = 5, ///< Operator item: greater than - cmADD = 6, ///< Operator item: add - cmSUB = 7, ///< Operator item: subtract - cmMUL = 8, ///< Operator item: multiply - cmDIV = 9, ///< Operator item: division - cmPOW = 10, ///< Operator item: y to the power of ... - cmLAND = 11, - cmLOR = 12, - cmASSIGN = 13, ///< Operator item: Assignment operator - cmBO = 14, ///< Operator item: opening bracket - cmBC = 15, ///< Operator item: closing bracket - cmIF = 16, ///< For use in the ternary if-then-else operator - cmELSE = 17, ///< For use in the ternary if-then-else operator - cmENDIF = 18, ///< For use in the ternary if-then-else operator - cmARG_SEP = 19, ///< function argument separator - cmVAR = 20, ///< variable item - cmVAL = 21, ///< value item - - // For optimization purposes - cmVARPOW2, - cmVARPOW3, - cmVARPOW4, - cmVARMUL, - cmPOW2, - - // operators and functions - cmFUNC, ///< Code for a generic function item - cmFUNC_STR, ///< Code for a function with a string parameter - cmFUNC_BULK, ///< Special callbacks for Bulk mode with an additional parameter for the bulk index - cmSTRING, ///< Code for a string token - cmOPRT_BIN, ///< user defined binary operator - cmOPRT_POSTFIX, ///< code for postfix operators - cmOPRT_INFIX, ///< code for infix operators - cmEND, ///< end of formula - cmUNKNOWN ///< uninitialized item - }; - - //------------------------------------------------------------------------------ - /** \brief Types internally used by the parser. - */ - enum ETypeCode - { - tpSTR = 0, ///< String type (Function arguments and constants only, no string variables) - tpDBL = 1, ///< Floating point variables - tpVOID = 2 ///< Undefined type. - }; - - //------------------------------------------------------------------------------ - enum EParserVersionInfo - { - pviBRIEF, - pviFULL - }; - - //------------------------------------------------------------------------------ - /** \brief Parser operator precedence values. */ - enum EOprtAssociativity - { - oaLEFT = 0, - oaRIGHT = 1, - oaNONE = 2 - }; - - //------------------------------------------------------------------------------ - /** \brief Parser operator precedence values. */ - enum EOprtPrecedence - { - // binary operators - prLOR = 1, - prLAND = 2, - prLOGIC = 3, ///< logic operators - prCMP = 4, ///< comparsion operators - prADD_SUB = 5, ///< addition - prMUL_DIV = 6, ///< multiplication/division - prPOW = 7, ///< power operator priority (highest) - - // infix operators - prINFIX = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator - prPOSTFIX = 6 ///< Postfix operator priority (currently unused) - }; - - //------------------------------------------------------------------------------ - // basic types - - /** \brief The stringtype used by the parser. - - Depends on wether UNICODE is used or not. - */ - typedef QMUP_STRING_TYPE string_type; - - /** \brief The character type used by the parser. - - Depends on wether UNICODE is used or not. - */ - typedef string_type::value_type char_type; - - /** \brief Typedef for easily using stringstream that respect the parser stringtype. */ - typedef std::basic_stringstream, - std::allocator > stringstream_type; - - // Data container types - - /** \brief Type used for storing variables. */ - typedef std::map varmap_type; - - /** \brief Type used for storing constants. */ - typedef std::map valmap_type; - - /** \brief Type for assigning a string name to an index in the internal string table. */ - typedef std::map strmap_type; - - // Parser callbacks - - /** \brief Callback type used for functions without arguments. */ - typedef qreal (*generic_fun_type)(); - - /** \brief Callback type used for functions without arguments. */ - typedef qreal (*fun_type0)(); - - /** \brief Callback type used for functions with a single arguments. */ - typedef qreal (*fun_type1)(qreal); - - /** \brief Callback type used for functions with two arguments. */ - typedef qreal (*fun_type2)(qreal, qreal); - - /** \brief Callback type used for functions with three arguments. */ - typedef qreal (*fun_type3)(qreal, qreal, qreal); - - /** \brief Callback type used for functions with four arguments. */ - typedef qreal (*fun_type4)(qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*fun_type5)(qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*fun_type6)(qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*fun_type7)(qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*fun_type8)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*fun_type9)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*fun_type10)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions without arguments. */ - typedef qreal (*bulkfun_type0)(int, int); - - /** \brief Callback type used for functions with a single arguments. */ - typedef qreal (*bulkfun_type1)(int, int, qreal); - - /** \brief Callback type used for functions with two arguments. */ - typedef qreal (*bulkfun_type2)(int, int, qreal, qreal); - - /** \brief Callback type used for functions with three arguments. */ - typedef qreal (*bulkfun_type3)(int, int, qreal, qreal, qreal); - - /** \brief Callback type used for functions with four arguments. */ - typedef qreal (*bulkfun_type4)(int, int, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*bulkfun_type5)(int, int, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*bulkfun_type6)(int, int, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*bulkfun_type7)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*bulkfun_type8)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*bulkfun_type9)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with five arguments. */ - typedef qreal (*bulkfun_type10)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal); - - /** \brief Callback type used for functions with a variable argument list. */ - typedef qreal (*multfun_type)(const qreal*, int); - - /** \brief Callback type used for functions taking a string as an argument. */ - typedef qreal (*strfun_type1)(const QString &); - - /** \brief Callback type used for functions taking a string and a value as arguments. */ - typedef qreal (*strfun_type2)(const QString &, qreal); - - /** \brief Callback type used for functions taking a string and two values as arguments. */ - typedef qreal (*strfun_type3)(const QString &, qreal, qreal); - - /** \brief Callback used for functions that identify values in a string. */ - typedef int (*identfun_type)(const QString &sExpr, int *nPos, qreal *fVal); - - /** \brief Callback used for variable creation factory functions. */ - typedef qreal* (*facfun_type)(const QString &, void*); -} // end of namespace - -#endif - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPDEF_H +#define QMUPDEF_H + +#include +#include + +#include "qmuparserfixes.h" + +/** @file + @brief This file contains standard definitions used by the parser. +*/ + +#define QMUP_VERSION "2.2.3" +#define QMUP_VERSION_DATE "20121222; SF" + +#define QMUP_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +/** @brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */ +//#define QMUP_MATH_EXCEPTIONS + +/** @brief Activate this option in order to compile with OpenMP support. + + OpenMP is used only in the bulk mode it may increase the performance a bit. +*/ +//#define MUP_USE_OPENMP + +#if defined(_UNICODE) + /** @brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::wstring +#else + /** @brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::string +#endif + +namespace qmu +{ +//------------------------------------------------------------------------------ +/** @brief Bytecode values. + + \attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt! +*/ +enum ECmdCode +{ + // The following are codes for built in binary operators + // apart from built in operators the user has the opportunity to + // add user defined operators. + cmLE = 0, ///< Operator item: less or equal + cmGE = 1, ///< Operator item: greater or equal + cmNEQ = 2, ///< Operator item: not equal + cmEQ = 3, ///< Operator item: equals + cmLT = 4, ///< Operator item: less than + cmGT = 5, ///< Operator item: greater than + cmADD = 6, ///< Operator item: add + cmSUB = 7, ///< Operator item: subtract + cmMUL = 8, ///< Operator item: multiply + cmDIV = 9, ///< Operator item: division + cmPOW = 10, ///< Operator item: y to the power of ... + cmLAND = 11, + cmLOR = 12, + cmASSIGN = 13, ///< Operator item: Assignment operator + cmBO = 14, ///< Operator item: opening bracket + cmBC = 15, ///< Operator item: closing bracket + cmIF = 16, ///< For use in the ternary if-then-else operator + cmELSE = 17, ///< For use in the ternary if-then-else operator + cmENDIF = 18, ///< For use in the ternary if-then-else operator + cmARG_SEP = 19, ///< function argument separator + cmVAR = 20, ///< variable item + cmVAL = 21, ///< value item + + // For optimization purposes + cmVARPOW2, + cmVARPOW3, + cmVARPOW4, + cmVARMUL, + cmPOW2, + + // operators and functions + cmFUNC, ///< Code for a generic function item + cmFUNC_STR, ///< Code for a function with a string parameter + cmFUNC_BULK, ///< Special callbacks for Bulk mode with an additional parameter for the bulk index + cmSTRING, ///< Code for a string token + cmOPRT_BIN, ///< user defined binary operator + cmOPRT_POSTFIX, ///< code for postfix operators + cmOPRT_INFIX, ///< code for infix operators + cmEND, ///< end of formula + cmUNKNOWN ///< uninitialized item +}; + +//------------------------------------------------------------------------------ +/** @brief Types internally used by the parser. +*/ +enum ETypeCode +{ + tpSTR = 0, ///< String type (Function arguments and constants only, no string variables) + tpDBL = 1, ///< Floating point variables + tpVOID = 2 ///< Undefined type. +}; + +//------------------------------------------------------------------------------ +enum EParserVersionInfo +{ + pviBRIEF, + pviFULL +}; + +//------------------------------------------------------------------------------ +/** @brief Parser operator precedence values. */ +enum EOprtAssociativity +{ + oaLEFT = 0, + oaRIGHT = 1, + oaNONE = 2 +}; + +//------------------------------------------------------------------------------ +/** @brief Parser operator precedence values. */ +enum EOprtPrecedence +{ + // binary operators + prLOR = 1, + prLAND = 2, + prLOGIC = 3, ///< logic operators + prCMP = 4, ///< comparsion operators + prADD_SUB = 5, ///< addition + prMUL_DIV = 6, ///< multiplication/division + prPOW = 7, ///< power operator priority (highest) + + // infix operators + prINFIX = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator + prPOSTFIX = 6 ///< Postfix operator priority (currently unused) +}; + +//------------------------------------------------------------------------------ +// basic types + +/** @brief The stringtype used by the parser. + + Depends on wether UNICODE is used or not. +*/ +typedef QMUP_STRING_TYPE string_type; + +/** @brief The character type used by the parser. + + Depends on wether UNICODE is used or not. +*/ +typedef string_type::value_type char_type; + +/** @brief Typedef for easily using stringstream that respect the parser stringtype. */ +typedef std::basic_stringstream < char_type, std::char_traits, std::allocator > stringstream_type; + +// Data container types + +/** @brief Type used for storing variables. */ +typedef std::map varmap_type; + +/** @brief Type used for storing constants. */ +typedef std::map valmap_type; + +/** @brief Type for assigning a string name to an index in the internal string table. */ +typedef std::map strmap_type; + +// Parser callbacks + +/** @brief Callback type used for functions without arguments. */ +typedef qreal ( *generic_fun_type ) (); + +/** @brief Callback type used for functions without arguments. */ +typedef qreal ( *fun_type0 ) (); + +/** @brief Callback type used for functions with a single arguments. */ +typedef qreal ( *fun_type1 ) ( qreal ); + +/** @brief Callback type used for functions with two arguments. */ +typedef qreal ( *fun_type2 ) ( qreal, qreal ); + +/** @brief Callback type used for functions with three arguments. */ +typedef qreal ( *fun_type3 ) ( qreal, qreal, qreal ); + +/** @brief Callback type used for functions with four arguments. */ +typedef qreal ( *fun_type4 ) ( qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *fun_type5 ) ( qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *fun_type6 ) ( qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *fun_type7 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *fun_type8 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *fun_type9 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *fun_type10 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions without arguments. */ +typedef qreal ( *bulkfun_type0 ) ( int, int ); + +/** @brief Callback type used for functions with a single arguments. */ +typedef qreal ( *bulkfun_type1 ) ( int, int, qreal ); + +/** @brief Callback type used for functions with two arguments. */ +typedef qreal ( *bulkfun_type2 ) ( int, int, qreal, qreal ); + +/** @brief Callback type used for functions with three arguments. */ +typedef qreal ( *bulkfun_type3 ) ( int, int, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with four arguments. */ +typedef qreal ( *bulkfun_type4 ) ( int, int, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *bulkfun_type5 ) ( int, int, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *bulkfun_type6 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *bulkfun_type7 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *bulkfun_type8 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *bulkfun_type9 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with five arguments. */ +typedef qreal ( *bulkfun_type10 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal ); + +/** @brief Callback type used for functions with a variable argument list. */ +typedef qreal ( *multfun_type ) ( const qreal*, int ); + +/** @brief Callback type used for functions taking a string as an argument. */ +typedef qreal ( *strfun_type1 ) ( const QString & ); + +/** @brief Callback type used for functions taking a string and a value as arguments. */ +typedef qreal ( *strfun_type2 ) ( const QString &, qreal ); + +/** @brief Callback type used for functions taking a string and two values as arguments. */ +typedef qreal ( *strfun_type3 ) ( const QString &, qreal, qreal ); + +/** @brief Callback used for functions that identify values in a string. */ +typedef int ( *identfun_type ) ( const QString &sExpr, int *nPos, qreal *fVal ); + +/** @brief Callback used for variable creation factory functions. */ +typedef qreal* ( *facfun_type ) ( const QString &, void* ); +} // end of namespace + +#endif + diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index c073b68ea..f0c2f4c11 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -1,326 +1,329 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include "qmuparsererror.h" - -#include - - -namespace qmu -{ - const QmuParserErrorMsg QmuParserErrorMsg::m_Instance; - - //------------------------------------------------------------------------------ - const QmuParserErrorMsg& QmuParserErrorMsg::Instance() - { - return m_Instance; - } - - //------------------------------------------------------------------------------ - QString QmuParserErrorMsg::operator[](unsigned a_iIdx) const - { - return (a_iIdx + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsererror.h" + +#include + +namespace qmu +{ +const QmuParserErrorMsg QmuParserErrorMsg::m_Instance; + +//---------------------------------------------------------------------------------------------------------------------- +const QmuParserErrorMsg& QmuParserErrorMsg::Instance() +{ + return m_Instance; +} + +//---------------------------------------------------------------------------------------------------------------------- +QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const +{ + return ( a_iIdx < m_vErrMsg.size() ) ? m_vErrMsg[a_iIdx] : QString(); +} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserErrorMsg::~QmuParserErrorMsg() +{} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Assignement operator is deactivated. + */ +QmuParserErrorMsg& QmuParserErrorMsg::operator= ( const QmuParserErrorMsg& ) +{ + assert ( false ); + return *this; +} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserErrorMsg::QmuParserErrorMsg ( const QmuParserErrorMsg& ) +{} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserErrorMsg::QmuParserErrorMsg() + : m_vErrMsg ( 0 ) +{ + m_vErrMsg.resize ( ecCOUNT ); + + m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$."; + m_vErrMsg[ecINTERNAL_ERROR] = "Internal error"; + m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\"."; + m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function."; + m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty."; + m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable."; + m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$"; + m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$"; + m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$"; + m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$"; + m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)"; + m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis"; + m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$"; + m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$"; + m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero"; + m_vErrMsg[ecDOMAIN_ERROR] = "Domain error"; + m_vErrMsg[ecNAME_CONFLICT] = "Name conflict"; + m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero)."; + m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator."; + m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$."; + m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$."; + m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument."; + m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected."; + m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$."; + m_vErrMsg[ecSTR_RESULT] = "Function result is a string."; + m_vErrMsg[ecGENERIC] = "Parser error."; + m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator."; + m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket."; + m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause"; + m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$"; + +#if defined(_DEBUG) + for ( int i = 0; i < ecCOUNT; ++i ) + { + if ( !m_vErrMsg[i].length() ) + { + assert ( false ); + } + } +#endif +} + +//---------------------------------------------------------------------------------------------------------------------- +// +// QParserError class +// +//---------------------------------------------------------------------------------------------------------------------- + +/** + * @brief Default constructor. + */ +QmuParserError::QmuParserError() + : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief This Constructor is used for internal exceptions only. + * + * It does not contain any information but the error code. + */ +QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) + : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ + m_strMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Construct an error from a message text. + */ +QmuParserError::QmuParserError ( const QString &sMsg ) + : m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ + Reset(); + m_strMsg = sMsg; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Construct an error object. + * @param [in] a_iErrc the error code. + * @param [in] sTok The token string related to this error. + * @param [in] sExpr The expression related to the error. + * @param [in] a_iPos the position in the expression where the error occured. + */ +QmuParserError::QmuParserError ( EErrorCodes iErrc, + const QString &sTok, + const QString &sExpr, + int iPos ) + : m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ + m_strMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Construct an error object. + * @param [in] iErrc the error code. + * @param [in] iPos the position in the expression where the error occured. + * @param [in] sTok The token string related to this error. + */ +QmuParserError::QmuParserError ( EErrorCodes iErrc, int iPos, const QString &sTok ) + : m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ + m_strMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** @brief Construct an error object. + * @param [in] szMsg The error message text. + * @param [in] iPos the position related to the error. + * @param [in] sTok The token string related to this error. + */ +QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok ) + : m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** @brief Copy constructor. */ +QmuParserError::QmuParserError ( const QmuParserError &a_Obj ) + : m_strMsg ( a_Obj.m_strMsg ), m_strFormula ( a_Obj.m_strFormula ), m_strTok ( a_Obj.m_strTok ), + m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{ +} + +//---------------------------------------------------------------------------------------------------------------------- +/** @brief Assignment operator. */ +QmuParserError& QmuParserError::operator= ( const QmuParserError &a_Obj ) +{ + if ( this == &a_Obj ) + { + return *this; + } + + m_strMsg = a_Obj.m_strMsg; + m_strFormula = a_Obj.m_strFormula; + m_strTok = a_Obj.m_strTok; + m_iPos = a_Obj.m_iPos; + m_iErrc = a_Obj.m_iErrc; + return *this; +} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserError::~QmuParserError() +{} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Replace all ocuurences of a substring with another string. + * @param strFind The string that shall be replaced. + * @param strReplaceWith The string that should be inserted instead of strFind + */ +void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ) +{ + QString strResult; + int iPos ( 0 ), iNext ( 0 ); + + for ( ;; ) + { + iNext = strSource.indexOf ( strFind, iPos ); + strResult.append ( strSource.mid ( iPos, iNext - iPos ) ); + + if ( iNext == -1 ) + break; + + strResult.append ( strReplaceWith ); + iPos = iNext + strFind.length(); + } + + strSource.swap ( strResult ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Reset the erro object. + */ +void QmuParserError::Reset() +{ + m_strMsg = ""; + m_strFormula = ""; + m_strTok = ""; + m_iPos = -1; + m_iErrc = ecUNDEFINED; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set the expression related to this error. + */ +void QmuParserError::SetFormula ( const QString &a_strFormula ) +{ + m_strFormula = a_strFormula; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief gets the expression related tp this error. + */ +const QString& QmuParserError::GetExpr() const +{ + return m_strFormula; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the message string for this error. + */ +const QString& QmuParserError::GetMsg() const +{ + return m_strMsg; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the formula position related to the error. + * + * If the error is not related to a distinct position this will return -1 + */ +std::size_t QmuParserError::GetPos() const +{ + return m_iPos; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return string related with this token (if available). + */ +const QString& QmuParserError::GetToken() const +{ + return m_strTok; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the error code. + */ +EErrorCodes QmuParserError::GetCode() const +{ + return m_iErrc; +} +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index 97623a9fa..0bf9328d3 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -1,163 +1,159 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERERROR_H -#define QMUPARSERERROR_H - -#include -#include -#include -#include -#include - -#include "qmuparserdef.h" - -/** \file - \brief This file defines the error class used by the parser. -*/ - -namespace qmu -{ - -/** \brief Error codes. */ -enum EErrorCodes -{ - // Formula syntax errors - ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found - ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified. - ecUNEXPECTED_EOF = 2, ///< Unexpected end of formula. (Example: "2+sin(") - ecUNEXPECTED_ARG_SEP = 3, ///< An unexpected comma has been found. (Example: "1,23") - ecUNEXPECTED_ARG = 4, ///< An unexpected argument has been found - ecUNEXPECTED_VAL = 5, ///< An unexpected value token has been found - ecUNEXPECTED_VAR = 6, ///< An unexpected variable token has been found - ecUNEXPECTED_PARENS = 7, ///< Unexpected Parenthesis, opening or closing - ecUNEXPECTED_STR = 8, ///< A string has been found at an inapropriate position - ecSTRING_EXPECTED = 9, ///< A string function has been called with a different type of argument - ecVAL_EXPECTED = 10, ///< A numerical function has been called with a non value type of argument - ecMISSING_PARENS = 11, ///< Missing parens. (Example: "3*sin(3") - ecUNEXPECTED_FUN = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)") - ecUNTERMINATED_STRING = 13, ///< unterminated string constant. (Example: "3*valueof("hello)") - ecTOO_MANY_PARAMS = 14, ///< Too many function parameters - ecTOO_FEW_PARAMS = 15, ///< Too few function parameters. (Example: "ite(1<2,2)") - ecOPRT_TYPE_CONFLICT = 16, ///< binary operators may only be applied to value items of the same type - ecSTR_RESULT = 17, ///< result is a string - - // Invalid Parser input Parameters - ecINVALID_NAME = 18, ///< Invalid function, variable or constant name. - ecINVALID_BINOP_IDENT = 19, ///< Invalid binary operator identifier - ecINVALID_INFIX_IDENT = 20, ///< Invalid function, variable or constant name. - ecINVALID_POSTFIX_IDENT = 21, ///< Invalid function, variable or constant name. - - ecBUILTIN_OVERLOAD = 22, ///< Trying to overload builtin operator - ecINVALID_FUN_PTR = 23, ///< Invalid callback function pointer - ecINVALID_VAR_PTR = 24, ///< Invalid variable pointer - ecEMPTY_EXPRESSION = 25, ///< The Expression is empty - ecNAME_CONFLICT = 26, ///< Name conflict - ecOPT_PRI = 27, ///< Invalid operator priority - // - ecDOMAIN_ERROR = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused) - ecDIV_BY_ZERO = 29, ///< Division by zero (currently unused) - ecGENERIC = 30, ///< Generic error - ecLOCALE = 31, ///< Conflict with current locale - - ecUNEXPECTED_CONDITIONAL = 32, - ecMISSING_ELSE_CLAUSE = 33, - ecMISPLACED_COLON = 34, - - // internal errors - ecINTERNAL_ERROR = 35, ///< Internal error of any kind. - - // The last two are special entries - ecCOUNT, ///< This is no error code, It just stores just the total number of error codes - ecUNDEFINED = -1 ///< Undefined message, placeholder to detect unassigned error messages -}; - -//--------------------------------------------------------------------------- -/** \brief A class that handles the error messages. -*/ -class QmuParserErrorMsg -{ -public: - typedef QmuParserErrorMsg self_type; - - QmuParserErrorMsg& operator=(const QmuParserErrorMsg &); - QmuParserErrorMsg(const QmuParserErrorMsg&); - QmuParserErrorMsg(); - - ~QmuParserErrorMsg(); - - static const QmuParserErrorMsg& Instance(); - QString operator[](unsigned a_iIdx) const; - -private: - QVector m_vErrMsg; ///< A vector with the predefined error messages - static const self_type m_Instance; ///< The instance pointer -}; - -//--------------------------------------------------------------------------- -/** \brief Error class of the parser. - \author Ingo Berg - - Part of the math parser package. -*/ -class QmuParserError -{ -private: - - /** \brief Replace all ocuurences of a substring with another string. */ - void ReplaceSubString(QString &strSource, - const QString &strFind, - const QString &strReplaceWith); - void Reset(); - -public: - - QmuParserError(); - explicit QmuParserError(EErrorCodes a_iErrc); - explicit QmuParserError(const QString &sMsg); - QmuParserError( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1); - QmuParserError(EErrorCodes a_iErrc, int a_iPos, const QString &sTok); - QmuParserError(const QString &a_szMsg, int a_iPos, const QString &sTok = QString()); - QmuParserError(const QmuParserError &a_Obj); - QmuParserError& operator=(const QmuParserError &a_Obj); - ~QmuParserError(); - - void SetFormula(const QString &a_strFormula); - const QString &GetExpr() const; - const QString &GetMsg() const; - std::size_t GetPos() const; - const QString &GetToken() const; - EErrorCodes GetCode() const; - -private: - QString m_strMsg; ///< The message string - QString m_strFormula; ///< Formula string - QString m_strTok; ///< Token related with the error - int m_iPos; ///< Formula position related to the error - EErrorCodes m_iErrc; ///< Error code - const QmuParserErrorMsg &m_ErrMsg; -}; - -} // namespace qmu - -#endif - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERERROR_H +#define QMUPARSERERROR_H + +#include +#include +#include +#include +#include + +#include "qmuparserdef.h" + +/** @file + @brief This file defines the error class used by the parser. +*/ + +namespace qmu +{ + +/** @brief Error codes. */ +enum EErrorCodes +{ + // Formula syntax errors + ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found + ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified. + ecUNEXPECTED_EOF = 2, ///< Unexpected end of formula. (Example: "2+sin(") + ecUNEXPECTED_ARG_SEP = 3, ///< An unexpected comma has been found. (Example: "1,23") + ecUNEXPECTED_ARG = 4, ///< An unexpected argument has been found + ecUNEXPECTED_VAL = 5, ///< An unexpected value token has been found + ecUNEXPECTED_VAR = 6, ///< An unexpected variable token has been found + ecUNEXPECTED_PARENS = 7, ///< Unexpected Parenthesis, opening or closing + ecUNEXPECTED_STR = 8, ///< A string has been found at an inapropriate position + ecSTRING_EXPECTED = 9, ///< A string function has been called with a different type of argument + ecVAL_EXPECTED = 10, ///< A numerical function has been called with a non value type of argument + ecMISSING_PARENS = 11, ///< Missing parens. (Example: "3*sin(3") + ecUNEXPECTED_FUN = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)") + ecUNTERMINATED_STRING = 13, ///< unterminated string constant. (Example: "3*valueof("hello)") + ecTOO_MANY_PARAMS = 14, ///< Too many function parameters + ecTOO_FEW_PARAMS = 15, ///< Too few function parameters. (Example: "ite(1<2,2)") + ecOPRT_TYPE_CONFLICT = 16, ///< binary operators may only be applied to value items of the same type + ecSTR_RESULT = 17, ///< result is a string + + // Invalid Parser input Parameters + ecINVALID_NAME = 18, ///< Invalid function, variable or constant name. + ecINVALID_BINOP_IDENT = 19, ///< Invalid binary operator identifier + ecINVALID_INFIX_IDENT = 20, ///< Invalid function, variable or constant name. + ecINVALID_POSTFIX_IDENT = 21, ///< Invalid function, variable or constant name. + + ecBUILTIN_OVERLOAD = 22, ///< Trying to overload builtin operator + ecINVALID_FUN_PTR = 23, ///< Invalid callback function pointer + ecINVALID_VAR_PTR = 24, ///< Invalid variable pointer + ecEMPTY_EXPRESSION = 25, ///< The Expression is empty + ecNAME_CONFLICT = 26, ///< Name conflict + ecOPT_PRI = 27, ///< Invalid operator priority + // + ecDOMAIN_ERROR = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused) + ecDIV_BY_ZERO = 29, ///< Division by zero (currently unused) + ecGENERIC = 30, ///< Generic error + ecLOCALE = 31, ///< Conflict with current locale + + ecUNEXPECTED_CONDITIONAL = 32, + ecMISSING_ELSE_CLAUSE = 33, + ecMISPLACED_COLON = 34, + + // internal errors + ecINTERNAL_ERROR = 35, ///< Internal error of any kind. + + // The last two are special entries + ecCOUNT, ///< This is no error code, It just stores just the total number of error codes + ecUNDEFINED = -1 ///< Undefined message, placeholder to detect unassigned error messages +}; + +//--------------------------------------------------------------------------- +/** @brief A class that handles the error messages. +*/ +class QmuParserErrorMsg +{ +public: + typedef QmuParserErrorMsg self_type; + + QmuParserErrorMsg& operator= ( const QmuParserErrorMsg & ); + QmuParserErrorMsg ( const QmuParserErrorMsg& ); + QmuParserErrorMsg(); + ~QmuParserErrorMsg(); + + static const QmuParserErrorMsg& Instance(); + QString operator[] ( unsigned a_iIdx ) const; + +private: + QVector m_vErrMsg; ///< A vector with the predefined error messages + static const self_type m_Instance; ///< The instance pointer +}; + +//--------------------------------------------------------------------------- +/** @brief Error class of the parser. + @author Ingo Berg + + Part of the math parser package. +*/ +class QmuParserError +{ +public: + + QmuParserError(); + explicit QmuParserError ( EErrorCodes a_iErrc ); + explicit QmuParserError ( const QString &sMsg ); + QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 ); + QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok ); + QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() ); + QmuParserError ( const QmuParserError &a_Obj ); + QmuParserError& operator= ( const QmuParserError &a_Obj ); + ~QmuParserError(); + + void SetFormula ( const QString &a_strFormula ); + const QString& GetExpr() const; + const QString& GetMsg() const; + std::size_t GetPos() const; + const QString& GetToken() const; + EErrorCodes GetCode() const; + +private: + QString m_strMsg; ///< The message string + QString m_strFormula; ///< Formula string + QString m_strTok; ///< Token related with the error + int m_iPos; ///< Formula position related to the error + EErrorCodes m_iErrc; ///< Error code + const QmuParserErrorMsg &m_ErrMsg; + /** + * @brief Replace all ocuurences of a substring with another string. + */ + void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ); + void Reset(); +}; + +} // namespace qmu + +#endif + diff --git a/src/libs/qmuparser/qmuparserfixes.h b/src/libs/qmuparser/qmuparserfixes.h index f0d529a63..1cabcda6d 100644 --- a/src/libs/qmuparser/qmuparserfixes.h +++ b/src/libs/qmuparser/qmuparserfixes.h @@ -23,8 +23,8 @@ #ifndef QMUPARSERFIXES_H #define QMUPARSERFIXES_H -/** \file - \brief This file contains compatibility fixes for some platforms. +/** @file + @brief This file contains compatibility fixes for some platforms. */ // diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index d4d22919a..16900978b 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -1,1326 +1,1415 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include "qmuparsertest.h" -#include -#include - -#include -#include -#include - -using namespace std; - -/** \file - \brief This file contains the implementation of parser test cases. -*/ - -namespace qmu -{ - namespace Test - { - int QmuParserTester::c_iCount = 0; - - //--------------------------------------------------------------------------------------------- - QmuParserTester::QmuParserTester() - :m_vTestFun() - { - AddTest(&QmuParserTester::TestNames); - AddTest(&QmuParserTester::TestSyntax); - AddTest(&QmuParserTester::TestPostFix); - AddTest(&QmuParserTester::TestInfixOprt); - AddTest(&QmuParserTester::TestVarConst); - AddTest(&QmuParserTester::TestMultiArg); - AddTest(&QmuParserTester::TestExpression); - AddTest(&QmuParserTester::TestIfThenElse); - AddTest(&QmuParserTester::TestInterface); - AddTest(&QmuParserTester::TestBinOprt); - AddTest(&QmuParserTester::TestException); - AddTest(&QmuParserTester::TestStrArg); - - QmuParserTester::c_iCount = 0; - } - - //--------------------------------------------------------------------------------------------- - int QmuParserTester::IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) - { - if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) - return 0; - - unsigned iVal(0); - bool ok = false; - iVal = a_szExpr.toUInt(&ok, 16); - - if(ok) - { - int nPos = a_szExpr.indexOf(QString().setNum(iVal, 16)); - if(nPos == 0) - return 1; - - *a_iPos += (int)(2 + nPos); - *a_fVal = (qreal)iVal; - return 1; - } - else - { - return 0; - } - - } - - //--------------------------------------------------------------------------------------------- - int QmuParserTester::TestInterface() - { - int iStat = 0; - qDebug() << "testing member functions..."; - - // Test RemoveVar - qreal afVal[3] = {1,2,3}; - QmuParser p; - - try - { - p.DefineVar( "a", &afVal[0]); - p.DefineVar( "b", &afVal[1]); - p.DefineVar( "c", &afVal[2]); - p.SetExpr( "a+b+c" ); - p.Eval(); - } - catch(...) - { - iStat += 1; // this is not supposed to happen - } - - try - { - p.RemoveVar( "c" ); - p.Eval(); - iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... - } - catch(...) - { - // failure is expected... - } - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------------------------- - int QmuParserTester::TestStrArg() - { - int iStat = 0; - qDebug() << "testing string arguments..."; - - iStat += EqnTest("valueof(\"\")", 123, true); // empty string arguments caused a crash - iStat += EqnTest("valueof(\"aaa\")+valueof(\"bbb\") ", 246, true); - iStat += EqnTest("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")", 323, true); - // use in expressions with variables - iStat += EqnTest("a*(atof(\"10\")-b)", 8, true); - iStat += EqnTest("a-(atof(\"10\")*b)", -19, true); - // string + numeric arguments - iStat += EqnTest("strfun1(\"100\")", 100, true); - iStat += EqnTest("strfun2(\"100\",1)", 101, true); - iStat += EqnTest("strfun3(\"99\",1,2)", 102, true); - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------------------------- - int QmuParserTester::TestBinOprt() - { - int iStat = 0; - qDebug() << "testing binary operators..."; - - // built in operators - // xor operator - //iStat += EqnTest("1 xor 2", 3, true); - //iStat += EqnTest("a xor b", 3, true); // with a=1 and b=2 - //iStat += EqnTest("1 xor 2 xor 3", 0, true); - //iStat += EqnTest("a xor b xor 3", 0, true); // with a=1 and b=2 - //iStat += EqnTest("a xor b xor c", 0, true); // with a=1 and b=2 - //iStat += EqnTest("(1 xor 2) xor 3", 0, true); - //iStat += EqnTest("(a xor b) xor c", 0, true); // with a=1 and b=2 - //iStat += EqnTest("(a) xor (b) xor c", 0, true); // with a=1 and b=2 - //iStat += EqnTest("1 or 2"), 3, true; - //iStat += EqnTest("a or b"), 3, true; // with a=1 and b=2 - iStat += EqnTest("a++b", 3, true); - iStat += EqnTest("a ++ b", 3, true); - iStat += EqnTest("1++2", 3, true); - iStat += EqnTest("1 ++ 2", 3, true); - iStat += EqnTest("a add b", 3, true); - iStat += EqnTest("1 add 2", 3, true); - iStat += EqnTest("aa", 1, true); - iStat += EqnTest("a>a", 0, true); - iStat += EqnTest("aa", 0, true); - iStat += EqnTest("a<=a", 1, true); - iStat += EqnTest("a<=b", 1, true); - iStat += EqnTest("b<=a", 0, true); - iStat += EqnTest("a>=a", 1, true); - iStat += EqnTest("b>=a", 1, true); - iStat += EqnTest("a>=b", 0, true); - - // Test logical operators, expecially if user defined "&" and the internal "&&" collide - iStat += EqnTest("1 && 1", 1, true); - iStat += EqnTest("1 && 0", 0, true); - iStat += EqnTest("(aa)", 1, true); - iStat += EqnTest("(ab)", 0, true); - //iStat += EqnTest("12 and 255", 12, true); - //iStat += EqnTest("12 and 0", 0, true); - iStat += EqnTest("12 & 255", 12, true); - iStat += EqnTest("12 & 0", 0, true); - iStat += EqnTest("12&255", 12, true); - iStat += EqnTest("12&0", 0, true); - - // Assignement operator - iStat += EqnTest("a = b", 2, true); - iStat += EqnTest("a = sin(b)", 0.909297, true); - iStat += EqnTest("a = 1+sin(b)", 1.909297, true); - iStat += EqnTest("(a=b)*2", 4, true); - iStat += EqnTest("2*(a=b)", 4, true); - iStat += EqnTest("2*(a=b+1)", 6, true); - iStat += EqnTest("(a=b+1)*2", 6, true); - - iStat += EqnTest("2^2^3", 256, true); - iStat += EqnTest("1/2/3", 1.0/6.0, true); - - // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 - iStat += EqnTest("3+4*2/(1-5)^2^3", 3.0001220703125, true); - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------------------------- - /** \brief Check muParser name restriction enforcement. */ - int QmuParserTester::TestNames() - { - int iStat= 0, - iErr = 0; - - qDebug() << "testing name restriction enforcement..."; - - QmuParser p; - - #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \ - iErr = 0; \ - QmuParserTester::c_iCount++; \ - try \ - { \ - p.Define##DOMAIN(EXPR, ARG); \ - } \ - catch(QmuParser::exception_type&) \ - { \ - iErr = (FAIL==false) ? 0 : 1; \ - } \ - iStat += iErr; - - // constant names - PARSER_THROWCHECK(Const, false, "0a", 1) - PARSER_THROWCHECK(Const, false, "9a", 1) - PARSER_THROWCHECK(Const, false, "+a", 1) - PARSER_THROWCHECK(Const, false, "-a", 1) - PARSER_THROWCHECK(Const, false, "a-", 1) - PARSER_THROWCHECK(Const, false, "a*", 1) - PARSER_THROWCHECK(Const, false, "a?", 1) - PARSER_THROWCHECK(Const, true, "a", 1) - PARSER_THROWCHECK(Const, true, "a_min", 1) - PARSER_THROWCHECK(Const, true, "a_min0", 1) - PARSER_THROWCHECK(Const, true, "a_min9", 1) - // variable names - qreal a; - p.ClearConst(); - PARSER_THROWCHECK(Var, false, "123abc", &a) - PARSER_THROWCHECK(Var, false, "9a", &a) - PARSER_THROWCHECK(Var, false, "0a", &a) - PARSER_THROWCHECK(Var, false, "+a", &a) - PARSER_THROWCHECK(Var, false, "-a", &a) - PARSER_THROWCHECK(Var, false, "?a", &a) - PARSER_THROWCHECK(Var, false, "!a", &a) - PARSER_THROWCHECK(Var, false, "a+", &a) - PARSER_THROWCHECK(Var, false, "a-", &a) - PARSER_THROWCHECK(Var, false, "a*", &a) - PARSER_THROWCHECK(Var, false, "a?", &a) - PARSER_THROWCHECK(Var, true, "a", &a) - PARSER_THROWCHECK(Var, true, "a_min", &a) - PARSER_THROWCHECK(Var, true, "a_min0", &a) - PARSER_THROWCHECK(Var, true, "a_min9", &a) - PARSER_THROWCHECK(Var, false, "a_min9", 0) - // Postfix operators - // fail - PARSER_THROWCHECK(PostfixOprt, false, "(k", f1of1) - PARSER_THROWCHECK(PostfixOprt, false, "9+", f1of1) - PARSER_THROWCHECK(PostfixOprt, false, "+", 0) - // pass - PARSER_THROWCHECK(PostfixOprt, true, "-a", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "?a", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "_", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "#", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "&&", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "||", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "&", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "|", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "++", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "--", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "?>", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "?<", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "**", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "xor", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "and", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "or", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "not", f1of1) - PARSER_THROWCHECK(PostfixOprt, true, "!", f1of1) - // Binary operator - // The following must fail with builtin operators activated - // p.EnableBuiltInOp(true); -> this is the default - p.ClearPostfixOprt(); - PARSER_THROWCHECK(Oprt, false, "+", f1of2) - PARSER_THROWCHECK(Oprt, false, "-", f1of2) - PARSER_THROWCHECK(Oprt, false, "*", f1of2) - PARSER_THROWCHECK(Oprt, false, "/", f1of2) - PARSER_THROWCHECK(Oprt, false, "^", f1of2) - PARSER_THROWCHECK(Oprt, false, "&&", f1of2) - PARSER_THROWCHECK(Oprt, false, "||", f1of2) - // without activated built in operators it should work - p.EnableBuiltInOprt(false); - PARSER_THROWCHECK(Oprt, true, "+", f1of2) - PARSER_THROWCHECK(Oprt, true, "-", f1of2) - PARSER_THROWCHECK(Oprt, true, "*", f1of2) - PARSER_THROWCHECK(Oprt, true, "/", f1of2) - PARSER_THROWCHECK(Oprt, true, "^", f1of2) - PARSER_THROWCHECK(Oprt, true, "&&", f1of2) - PARSER_THROWCHECK(Oprt, true, "||", f1of2) - #undef PARSER_THROWCHECK - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------- - int QmuParserTester::TestSyntax() - { - int iStat = 0; - qDebug() << "testing syntax engine..."; - - iStat += ThrowTest("1,", ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest("a,", ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest("sin(8),", ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest("(sin(8)),", ecUNEXPECTED_EOF); // incomplete hex definition - iStat += ThrowTest("a{m},", ecUNEXPECTED_EOF); // incomplete hex definition - - iStat += EqnTest("(1+ 2*a)", 3, true); // Spaces within formula - iStat += EqnTest("sqrt((4))", 2, true); // Multiple brackets - iStat += EqnTest("sqrt((2)+2)", 2, true);// Multiple brackets - iStat += EqnTest("sqrt(2+(2))", 2, true);// Multiple brackets - iStat += EqnTest("sqrt(a+(3))", 2, true);// Multiple brackets - iStat += EqnTest("sqrt((3)+a)", 2, true);// Multiple brackets - iStat += EqnTest("order(1,2)", 1, true); // May not cause name collision with operator "or" - iStat += EqnTest("(2+", 0, false); // missing closing bracket - iStat += EqnTest("2++4", 0, false); // unexpected operator - iStat += EqnTest("2+-4", 0, false); // unexpected operator - iStat += EqnTest("(2+)", 0, false); // unexpected closing bracket - iStat += EqnTest("--2", 0, false); // double sign - iStat += EqnTest("ksdfj", 0, false); // unknown token - iStat += EqnTest("()", 0, false); // empty bracket without a function - iStat += EqnTest("5+()", 0, false); // empty bracket without a function - iStat += EqnTest("sin(cos)", 0, false); // unexpected function - iStat += EqnTest("5t6", 0, false); // unknown token - iStat += EqnTest("5 t 6", 0, false); // unknown token - iStat += EqnTest("8*", 0, false); // unexpected end of formula - iStat += EqnTest(",3", 0, false); // unexpected comma - iStat += EqnTest("3,5", 0, false); // unexpected comma - iStat += EqnTest("sin(8,8)", 0, false); // too many function args - iStat += EqnTest("(7,8)", 0, false); // too many function args - iStat += EqnTest("sin)", 0, false); // unexpected closing bracket - iStat += EqnTest("a)", 0, false); // unexpected closing bracket - iStat += EqnTest("pi)", 0, false); // unexpected closing bracket - iStat += EqnTest("sin(())", 0, false); // unexpected closing bracket - iStat += EqnTest("sin()", 0, false); // unexpected closing bracket - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------- - int QmuParserTester::TestVarConst() - { - int iStat = 0; - qDebug() << "testing variable/constant detection..."; - - // Test if the result changes when a variable changes - iStat += EqnTestWithVarChange( "a", 1, 1, 2, 2 ); - iStat += EqnTestWithVarChange( "2*a", 2, 4, 3, 6 ); - - // distinguish constants with same basename - iStat += EqnTest( "const", 1, true); - iStat += EqnTest( "const1", 2, true); - iStat += EqnTest( "const2", 3, true); - iStat += EqnTest( "2*const", 2, true); - iStat += EqnTest( "2*const1", 4, true); - iStat += EqnTest( "2*const2", 6, true); - iStat += EqnTest( "2*const+1", 3, true); - iStat += EqnTest( "2*const1+1", 5, true); - iStat += EqnTest( "2*const2+1", 7, true); - iStat += EqnTest( "const", 0, false); - iStat += EqnTest( "const1", 0, false); - iStat += EqnTest( "const2", 0, false); - - // distinguish variables with same basename - iStat += EqnTest( "a", 1, true); - iStat += EqnTest( "aa", 2, true); - iStat += EqnTest( "2*a", 2, true); - iStat += EqnTest( "2*aa", 4, true); - iStat += EqnTest( "2*a-1", 1, true); - iStat += EqnTest( "2*aa-1", 3, true); - - // custom value recognition - iStat += EqnTest( "0xff", 255, true); - iStat += EqnTest( "0x97 + 0xff", 406, true); - - // Finally test querying of used variables - try - { - int idx; - qmu::QmuParser p; - qreal vVarVal[] = { 1, 2, 3, 4, 5}; - p.DefineVar( "a", &vVarVal[0]); - p.DefineVar( "b", &vVarVal[1]); - p.DefineVar( "c", &vVarVal[2]); - p.DefineVar( "d", &vVarVal[3]); - p.DefineVar( "e", &vVarVal[4]); - - // Test lookup of defined variables - // 4 used variables - p.SetExpr( "a+b+c+d" ); - qmu::varmap_type UsedVar = p.GetUsedVar(); - int iCount = (int)UsedVar.size(); - if (iCount!=4) - throw false; - - // the next check will fail if the parser - // erroneousely creates new variables internally - if (p.GetVar().size()!=5) - throw false; - - qmu::varmap_type::const_iterator item = UsedVar.begin(); - for (idx=0; item!=UsedVar.end(); ++item) - { - if (&vVarVal[idx++]!=item->second) - throw false; - } - - // Test lookup of undefined variables - p.SetExpr( "undef1+undef2+undef3" ); - UsedVar = p.GetUsedVar(); - iCount = (int)UsedVar.size(); - if (iCount!=3) - throw false; - - // the next check will fail if the parser - // erroneousely creates new variables internally - if (p.GetVar().size()!=5) - throw false; - - for (item = UsedVar.begin(); item!=UsedVar.end(); ++item) - { - if (item->second!=0) - throw false; // all pointers to undefined variables must be null - } - - // 1 used variables - p.SetExpr( "a+b" ); - UsedVar = p.GetUsedVar(); - iCount = (int)UsedVar.size(); - if (iCount!=2) throw false; - item = UsedVar.begin(); - for (idx=0; item!=UsedVar.end(); ++item) - if (&vVarVal[idx++]!=item->second) throw false; - - } - catch(...) - { - iStat += 1; - } - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------- - int QmuParserTester::TestMultiArg() - { - int iStat = 0; - qDebug() << "testing multiarg functions..."; - - // Compound expressions - iStat += EqnTest( "1,2,3", 3, true); - iStat += EqnTest( "a,b,c", 3, true); - iStat += EqnTest( "a=10,b=20,c=a*b", 200, true); - iStat += EqnTest( "1,\n2,\n3", 3, true); - iStat += EqnTest( "a,\nb,\nc", 3, true); - iStat += EqnTest( "a=10,\nb=20,\nc=a*b", 200, true); - iStat += EqnTest( "1,\r\n2,\r\n3", 3, true); - iStat += EqnTest( "a,\r\nb,\r\nc", 3, true); - iStat += EqnTest( "a=10,\r\nb=20,\r\nc=a*b", 200, true); - - // picking the right argument - iStat += EqnTest( "f1of1(1)", 1, true); - iStat += EqnTest( "f1of2(1, 2)", 1, true); - iStat += EqnTest( "f2of2(1, 2)", 2, true); - iStat += EqnTest( "f1of3(1, 2, 3)", 1, true); - iStat += EqnTest( "f2of3(1, 2, 3)", 2, true); - iStat += EqnTest( "f3of3(1, 2, 3)", 3, true); - iStat += EqnTest( "f1of4(1, 2, 3, 4)", 1, true); - iStat += EqnTest( "f2of4(1, 2, 3, 4)", 2, true); - iStat += EqnTest( "f3of4(1, 2, 3, 4)", 3, true); - iStat += EqnTest( "f4of4(1, 2, 3, 4)", 4, true); - iStat += EqnTest( "f1of5(1, 2, 3, 4, 5)", 1, true); - iStat += EqnTest( "f2of5(1, 2, 3, 4, 5)", 2, true); - iStat += EqnTest( "f3of5(1, 2, 3, 4, 5)", 3, true); - iStat += EqnTest( "f4of5(1, 2, 3, 4, 5)", 4, true); - iStat += EqnTest( "f5of5(1, 2, 3, 4, 5)", 5, true); - // Too few arguments / Too many arguments - iStat += EqnTest( "1+ping()", 11, true); - iStat += EqnTest( "ping()+1", 11, true); - iStat += EqnTest( "2*ping()", 20, true); - iStat += EqnTest( "ping()*2", 20, true); - iStat += EqnTest( "ping(1,2)", 0, false); - iStat += EqnTest( "1+ping(1,2)", 0, false); - iStat += EqnTest( "f1of1(1,2)", 0, false); - iStat += EqnTest( "f1of1()", 0, false); - iStat += EqnTest( "f1of2(1, 2, 3)", 0, false); - iStat += EqnTest( "f1of2(1)", 0, false); - iStat += EqnTest( "f1of3(1, 2, 3, 4)", 0, false); - iStat += EqnTest( "f1of3(1)", 0, false); - iStat += EqnTest( "f1of4(1, 2, 3, 4, 5)", 0, false); - iStat += EqnTest( "f1of4(1)", 0, false); - iStat += EqnTest( "(1,2,3)", 0, false); - iStat += EqnTest( "1,2,3", 0, false); - iStat += EqnTest( "(1*a,2,3)", 0, false); - iStat += EqnTest( "1,2*a,3", 0, false); - - // correct calculation of arguments - iStat += EqnTest( "min(a, 1)", 1, true); - iStat += EqnTest( "min(3*2, 1)", 1, true); - iStat += EqnTest( "min(3*2, 1)", 6, false); - iStat += EqnTest( "firstArg(2,3,4)", 2, true); - iStat += EqnTest( "lastArg(2,3,4)", 4, true); - iStat += EqnTest( "min(3*a+1, 1)", 1, true); - iStat += EqnTest( "max(3*a+1, 1)", 4, true); - iStat += EqnTest( "max(3*a+1, 1)*2", 8, true); - iStat += EqnTest( "2*max(3*a+1, 1)+2", 10, true); - - // functions with Variable argument count - iStat += EqnTest( "sum(a)", 1, true); - iStat += EqnTest( "sum(1,2,3)", 6, true); - iStat += EqnTest( "sum(a,b,c)", 6, true); - iStat += EqnTest( "sum(1,-max(1,2),3)*2", 4, true); - iStat += EqnTest( "2*sum(1,2,3)", 12, true); - iStat += EqnTest( "2*sum(1,2,3)+2", 14, true); - iStat += EqnTest( "2*sum(-1,2,3)+2", 10, true); - iStat += EqnTest( "2*sum(-1,2,-(-a))+2", 6, true); - iStat += EqnTest( "2*sum(-1,10,-a)+2", 18, true); - iStat += EqnTest( "2*sum(1,2,3)*2", 24, true); - iStat += EqnTest( "sum(1,-max(1,2),3)*2", 4, true); - iStat += EqnTest( "sum(1*3, 4, a+2)", 10, true); - iStat += EqnTest( "sum(1*3, 2*sum(1,2,2), a+2)", 16, true); - iStat += EqnTest( "sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)", 24, true); - - // some failures - iStat += EqnTest( "sum()", 0, false); - iStat += EqnTest( "sum(,)", 0, false); - iStat += EqnTest( "sum(1,2,)", 0, false); - iStat += EqnTest( "sum(,1,2)", 0, false); - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - - //--------------------------------------------------------------------------- - int QmuParserTester::TestInfixOprt() - { - int iStat(0); - qDebug() << "testing infix operators..."; - - iStat += EqnTest( "-1", -1, true); - iStat += EqnTest( "-(-1)", 1, true); - iStat += EqnTest( "-(-1)*2", 2, true); - iStat += EqnTest( "-(-2)*sqrt(4)", 4, true); - iStat += EqnTest( "-_pi", -M_PI, true); - iStat += EqnTest( "-a", -1, true); - iStat += EqnTest( "-(a)", -1, true); - iStat += EqnTest( "-(-a)", 1, true); - iStat += EqnTest( "-(-a)*2", 2, true); - iStat += EqnTest( "-(8)", -8, true); - iStat += EqnTest( "-8", -8, true); - iStat += EqnTest( "-(2+1)", -3, true); - iStat += EqnTest( "-(f1of1(1+2*3)+1*2)", -9, true); - iStat += EqnTest( "-(-f1of1(1+2*3)+1*2)", 5, true); - iStat += EqnTest( "-sin(8)", -0.989358, true); - iStat += EqnTest( "3-(-a)", 4, true); - iStat += EqnTest( "3--a", 4, true); - iStat += EqnTest( "-1*3", -3, true); - - // Postfix / infix priorities - iStat += EqnTest( "~2#", 8, true); - iStat += EqnTest( "~f1of1(2)#", 8, true); - iStat += EqnTest( "~(b)#", 8, true); - iStat += EqnTest( "(~b)#", 12, true); - iStat += EqnTest( "~(2#)", 8, true); - iStat += EqnTest( "~(f1of1(2)#)", 8, true); - // - iStat += EqnTest( "-2^2",-4, true); - iStat += EqnTest( "-(a+b)^2",-9, true); - iStat += EqnTest( "(-3)^2",9, true); - iStat += EqnTest( "-(-2^2)",4, true); - iStat += EqnTest( "3+-3^2",-6, true); - // The following assumes use of sqr as postfix operator ("") together - // with a sign operator of low priority: - iStat += EqnTest( "-2'", -4, true); - iStat += EqnTest( "-(1+1)'",-4, true); - iStat += EqnTest( "2+-(1+1)'",-2, true); - iStat += EqnTest( "2+-2'", -2, true); - // This is the classic behaviour of the infix sign operator (here: "$") which is - // now deprecated: - iStat += EqnTest( "$2^2",4, true); - iStat += EqnTest( "$(a+b)^2",9, true); - iStat += EqnTest( "($3)^2",9, true); - iStat += EqnTest( "$($2^2)",-4, true); - iStat += EqnTest( "3+$3^2",12, true); - - // infix operators sharing the first few characters - iStat += EqnTest( "~ 123", 123+2, true); - iStat += EqnTest( "~~ 123", 123+2, true); - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - - //--------------------------------------------------------------------------- - int QmuParserTester::TestPostFix() - { - int iStat = 0; - qDebug() << "testing postfix operators..."; - - // application - iStat += EqnTest( "3{m}+5", 5.003, true); - iStat += EqnTest( "1000{m}", 1, true); - iStat += EqnTest( "1000 {m}", 1, true); - iStat += EqnTest( "(a){m}", 1e-3, true); - iStat += EqnTest( "a{m}", 1e-3, true); - iStat += EqnTest( "a {m}", 1e-3, true); - iStat += EqnTest( "-(a){m}", -1e-3, true); - iStat += EqnTest( "-2{m}", -2e-3, true); - iStat += EqnTest( "-2 {m}", -2e-3, true); - iStat += EqnTest( "f1of1(1000){m}", 1, true); - iStat += EqnTest( "-f1of1(1000){m}", -1, true); - iStat += EqnTest( "-f1of1(-1000){m}", 1, true); - iStat += EqnTest( "f4of4(0,0,0,1000){m}", 1, true); - iStat += EqnTest( "2+(a*1000){m}", 3, true); - - // can postfix operators "m" und "meg" be told apart properly? - iStat += EqnTest( "2*3000meg+2", 2*3e9+2, true); - - // some incorrect results - iStat += EqnTest( "1000{m}", 0.1, false); - iStat += EqnTest( "(a){m}", 2, false); - // failure due to syntax checking - iStat += ThrowTest("0x", ecUNASSIGNABLE_TOKEN); // incomplete hex definition - iStat += ThrowTest("3+", ecUNEXPECTED_EOF); - iStat += ThrowTest( "4 + {m}", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "{m}4", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "sin({m})", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "{m} {m}", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "{m}(8)", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "4,{m}", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "-{m}", ecUNASSIGNABLE_TOKEN); - iStat += ThrowTest( "2(-{m})", ecUNEXPECTED_PARENS); - iStat += ThrowTest( "2({m})", ecUNEXPECTED_PARENS); - - iStat += ThrowTest( "multi*1.0", ecUNASSIGNABLE_TOKEN); - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - //--------------------------------------------------------------------------- - int QmuParserTester::TestExpression() - { - int iStat = 0; - qDebug() << "testing expression samples..."; - - qreal b = 2; - - // Optimization - iStat += EqnTest( "2*b*5", 20, true); - iStat += EqnTest( "2*b*5 + 4*b", 28, true); - iStat += EqnTest( "2*a/3", 2.0/3.0, true); - - // Addition auf cmVARMUL - iStat += EqnTest( "3+b", b+3, true); - iStat += EqnTest( "b+3", b+3, true); - iStat += EqnTest( "b*3+2", b*3+2, true); - iStat += EqnTest( "3*b+2", b*3+2, true); - iStat += EqnTest( "2+b*3", b*3+2, true); - iStat += EqnTest( "2+3*b", b*3+2, true); - iStat += EqnTest( "b+3*b", b+3*b, true); - iStat += EqnTest( "3*b+b", b+3*b, true); - - iStat += EqnTest( "2+b*3+b", 2+b*3+b, true); - iStat += EqnTest( "b+2+b*3", b+2+b*3, true); - - iStat += EqnTest( "(2*b+1)*4", (2*b+1)*4, true); - iStat += EqnTest( "4*(2*b+1)", (2*b+1)*4, true); - - // operator precedencs - iStat += EqnTest( "1+2-3*4/5^6", 2.99923, true); - iStat += EqnTest( "1^2/3*4-5+6", 2.33333333, true); - iStat += EqnTest( "1+2*3", 7, true); - iStat += EqnTest( "1+2*3", 7, true); - iStat += EqnTest( "(1+2)*3", 9, true); - iStat += EqnTest( "(1+2)*(-3)", -9, true); - iStat += EqnTest( "2/4", 0.5, true); - - iStat += EqnTest( "exp(ln(7))", 7, true); - iStat += EqnTest( "e^ln(7)", 7, true); - iStat += EqnTest( "e^(ln(7))", 7, true); - iStat += EqnTest( "(e^(ln(7)))", 7, true); - iStat += EqnTest( "1-(e^(ln(7)))", -6, true); - iStat += EqnTest( "2*(e^(ln(7)))", 14, true); - iStat += EqnTest( "10^log(5)", 5, true); - iStat += EqnTest( "10^log10(5)", 5, true); - iStat += EqnTest( "2^log2(4)", 4, true); - iStat += EqnTest( "-(sin(0)+1)", -1, true); - iStat += EqnTest( "-(2^1.1)", -2.14354692, true); - - iStat += EqnTest( "(cos(2.41)/b)", -0.372056, true); - iStat += EqnTest( "(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160, true); - iStat += EqnTest( "(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120, true); - iStat += EqnTest( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))", 0.00377999, true); - - // long formula (Reference: Matlab) - iStat += EqnTest( - "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))" - "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/" - "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-" - "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6" - "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e" - "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549, true); - - // long formula (Reference: Matlab) - iStat += EqnTest( - "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e" - ")+a)))*2.77)", -2.16995656, true); - - // long formula (Reference: Matlab) - iStat += EqnTest( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true); - - if (iStat==0) - qDebug() << "passed"; - else - qDebug() << "\n failed with " << iStat << " errors"; - - return iStat; - } - - - - //--------------------------------------------------------------------------- - int QmuParserTester::TestIfThenElse() - { - int iStat = 0; - qDebug() << "testing if-then-else operator..."; - - // Test error detection - iStat += ThrowTest(":3", ecUNEXPECTED_CONDITIONAL); - iStat += ThrowTest("? 1 : 2", ecUNEXPECTED_CONDITIONAL); - iStat += ThrowTest("(ab) ? 10 : 11", 11, true); - iStat += EqnTest("(ab) ? c : d", -2, true); - - iStat += EqnTest("(a>b) ? 1 : 0", 0, true); - iStat += EqnTest("((a>b) ? 1 : 0) ? 1 : 2", 2, true); - iStat += EqnTest("((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)", 2, true); - iStat += EqnTest("((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)", 1, true); - - iStat += EqnTest("sum((a>b) ? 1 : 2)", 2, true); - iStat += EqnTest("sum((1) ? 1 : 2)", 1, true); - iStat += EqnTest("sum((a>b) ? 1 : 2, 100)", 102, true); - iStat += EqnTest("sum((1) ? 1 : 2, 100)", 101, true); - iStat += EqnTest("sum(3, (a>b) ? 3 : 10)", 13, true); - iStat += EqnTest("sum(3, (ab) ? 3 : 10)", 130, true); - iStat += EqnTest("10*sum(3, (ab) ? 3 : 10)*10", 130, true); - iStat += EqnTest("sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab)&&(a2)&&(1<2) ? 128 : 255", 255, true); - iStat += EqnTest("((1<2)&&(1<2)) ? 128 : 255", 128, true); - iStat += EqnTest("((1>2)&&(1<2)) ? 128 : 255", 255, true); - iStat += EqnTest("((ab)&&(a0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 255, true); - iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)", 255, true); - iStat += EqnTest("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 128, true); - iStat += EqnTest("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)", 128, true); - iStat += EqnTest("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 32, true); - iStat += EqnTest("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 64, true); - iStat += EqnTest("1>0 ? 50 : 1>0 ? 128 : 255", 50, true); - iStat += EqnTest("1>0 ? 50 : (1>0 ? 128 : 255)", 50, true); - iStat += EqnTest("1>0 ? 1>0 ? 128 : 255 : 50", 128, true); - iStat += EqnTest("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16", 32, true); - iStat += EqnTest("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)", 32, true); - iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16", 255, true); - iStat += EqnTest("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)", 255, true); - iStat += EqnTest("1 ? 0 ? 128 : 255 : 1 ? 32 : 64", 255, true); - - // assignment operators - iStat += EqnTest("a= 0 ? 128 : 255, a", 255, true); - iStat += EqnTest("a=((a>b)&&(a - // this is now legal, for reference see: - // https://sourceforge.net/forum/message.php?msg_id=7411373 - // iStat += ThrowTest( "sin=9"), ecUNEXPECTED_OPERATOR); - //
    - - iStat += ThrowTest( "(8)=5", ecUNEXPECTED_OPERATOR); - iStat += ThrowTest( "(a)=5", ecUNEXPECTED_OPERATOR); - iStat += ThrowTest( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT); - - if (iStat==0) - qDebug() << "passed" ; - else - qDebug() << "\n failed with " << iStat << " errors" ; - - return iStat; - } - - - //--------------------------------------------------------------------------- - void QmuParserTester::AddTest(testfun_type a_pFun) - { - m_vTestFun.push_back(a_pFun); - } - - //--------------------------------------------------------------------------- - void QmuParserTester::Run() - { - int iStat = 0; - try - { - for (int i=0; i<(int)m_vTestFun.size(); ++i) - iStat += (this->*m_vTestFun[i])(); - } - catch(QmuParser::exception_type &e) - { - qDebug() << "\n" << e.GetMsg() ; - qDebug() << e.GetToken() ; - Abort(); - } - catch(std::exception &e) - { - qDebug() << e.what() ; - Abort(); - } - catch(...) - { - qDebug() << "Internal error"; - Abort(); - } - - if (iStat==0) - { - qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" ; - } - else - { - qDebug() << "Test failed with " << iStat - << " errors (" << QmuParserTester::c_iCount - << " expressions)" ; - } - QmuParserTester::c_iCount = 0; - } - - - //--------------------------------------------------------------------------- - int QmuParserTester::ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail) - { - QmuParserTester::c_iCount++; - - try - { - qreal fVal[] = {1,1,1}; - QmuParser p; - - p.DefineVar( "a", &fVal[0]); - p.DefineVar( "b", &fVal[1]); - p.DefineVar( "c", &fVal[2]); - p.DefinePostfixOprt( "{m}", Milli); - p.DefinePostfixOprt( "m", Milli); - p.DefineFun( "ping", Ping); - p.DefineFun( "valueof", ValueOf); - p.DefineFun( "strfun1", StrFun1); - p.DefineFun( "strfun2", StrFun2); - p.DefineFun( "strfun3", StrFun3); - p.SetExpr(a_str); - p.Eval(); - } - catch(QmuParserError &e) - { - // output the formula in case of an failed test - if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) ) - { - qDebug() << "\n " - << "Expression: " << a_str - << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" - << " Expected:" << a_iErrc; - } - - return (a_iErrc==e.GetCode()) ? 0 : 1; - } - - // if a_bFail==false no exception is expected - bool bRet((a_bFail==false) ? 0 : 1); - if (bRet==1) - { - qDebug() << "\n " - << "Expression: " << a_str - << " did evaluate; Expected error:" << a_iErrc; - } - - return bRet; - } - - //--------------------------------------------------------------------------- - /** \brief Evaluate a tet expression. - - \return 1 in case of a failure, 0 otherwise. - */ - int QmuParserTester::EqnTestWithVarChange(const QString &a_str, - double a_fVar1, - double a_fRes1, - double a_fVar2, - double a_fRes2) - { - QmuParserTester::c_iCount++; - qreal fVal[2] = {-999, -999 }; // should be equalinitially - - try - { - QmuParser p; - - // variable - qreal var = 0; - p.DefineVar( "a", &var); - p.SetExpr(a_str); - - var = a_fVar1; - fVal[0] = p.Eval(); - - var = a_fVar2; - fVal[1] = p.Eval(); - - if ( fabs(a_fRes1-fVal[0]) > 0.0000000001) - throw std::runtime_error("incorrect result (first pass)"); - - if ( fabs(a_fRes2-fVal[1]) > 0.0000000001) - throw std::runtime_error("incorrect result (second pass)"); - } - catch(QmuParser::exception_type &e) - { - qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; - return 1; - } - catch(std::exception &e) - { - qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; - return 1; // always return a failure since this exception is not expected - } - catch(...) - { - qDebug() << "\n fail: " << a_str << " (unexpected exception)"; - return 1; // exceptions other than ParserException are not allowed - } - - return 0; - } - - //--------------------------------------------------------------------------- - /** \brief Evaluate a tet expression. - - \return 1 in case of a failure, 0 otherwise. - */ - int QmuParserTester::EqnTest(const QString &a_str, double a_fRes, bool a_fPass) - { - QmuParserTester::c_iCount++; - int iRet(0); - qreal fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different - - try - { - std::auto_ptr p1; - QmuParser p2, p3; // three parser objects - // they will be used for testing copy and assihnment operators - // p1 is a pointer since i'm going to delete it in order to test if - // parsers after copy construction still refer to members of it. - // !! If this is the case this function will crash !! - - p1.reset(new qmu::QmuParser()); - // Add constants - p1->DefineConst( "pi", (qreal)M_PI); - p1->DefineConst( "e", (qreal)M_E); - p1->DefineConst( "const", 1); - p1->DefineConst( "const1", 2); - p1->DefineConst( "const2", 3); - // variables - qreal vVarVal[] = { 1, 2, 3, -2}; - p1->DefineVar( "a", &vVarVal[0]); - p1->DefineVar( "aa", &vVarVal[1]); - p1->DefineVar( "b", &vVarVal[1]); - p1->DefineVar( "c", &vVarVal[2]); - p1->DefineVar( "d", &vVarVal[3]); - - // custom value ident functions - p1->AddValIdent(&QmuParserTester::IsHexVal); - - // functions - p1->DefineFun( "ping", Ping); - p1->DefineFun( "f1of1", f1of1); // one parameter - p1->DefineFun( "f1of2", f1of2); // two parameter - p1->DefineFun( "f2of2", f2of2); - p1->DefineFun( "f1of3", f1of3); // three parameter - p1->DefineFun( "f2of3", f2of3); - p1->DefineFun( "f3of3", f3of3); - p1->DefineFun( "f1of4", f1of4); // four parameter - p1->DefineFun( "f2of4", f2of4); - p1->DefineFun( "f3of4", f3of4); - p1->DefineFun( "f4of4", f4of4); - p1->DefineFun( "f1of5", f1of5); // five parameter - p1->DefineFun( "f2of5", f2of5); - p1->DefineFun( "f3of5", f3of5); - p1->DefineFun( "f4of5", f4of5); - p1->DefineFun( "f5of5", f5of5); - - // binary operators - p1->DefineOprt( "add", add, 0); - p1->DefineOprt( "++", add, 0); - p1->DefineOprt( "&", land, prLAND); - - // sample functions - p1->DefineFun( "min", Min); - p1->DefineFun( "max", Max); - p1->DefineFun( "sum", Sum); - p1->DefineFun( "valueof", ValueOf); - p1->DefineFun( "atof", StrToFloat); - p1->DefineFun( "strfun1", StrFun1); - p1->DefineFun( "strfun2", StrFun2); - p1->DefineFun( "strfun3", StrFun3); - p1->DefineFun( "lastArg", LastArg); - p1->DefineFun( "firstArg", FirstArg); - p1->DefineFun( "order", FirstArg); - - // infix / postfix operator - // Note: Identifiers used here do not have any meaning - // they are mere placeholders to test certain features. - p1->DefineInfixOprt( "$", sign, prPOW+1); // sign with high priority - p1->DefineInfixOprt( "~", plus2); // high priority - p1->DefineInfixOprt( "~~", plus2); - p1->DefinePostfixOprt( "{m}", Milli); - p1->DefinePostfixOprt( "{M}", Mega); - p1->DefinePostfixOprt( "m", Milli); - p1->DefinePostfixOprt( "meg", Mega); - p1->DefinePostfixOprt( "#", times3); - p1->DefinePostfixOprt( "'", sqr); - p1->SetExpr(a_str); - - // Test bytecode integrity - // String parsing and bytecode parsing must yield the same result - fVal[0] = p1->Eval(); // result from stringparsing - fVal[1] = p1->Eval(); // result from bytecode - if (fVal[0]!=fVal[1]) - throw QmuParser::exception_type( "Bytecode / string parsing mismatch." ); - - // Test copy and assignement operators - try - { - // Test copy constructor - QVector vParser; - vParser.push_back(*(p1.get())); - qmu::QmuParser p2 = vParser[0]; // take parser from vector - - // destroy the originals from p2 - vParser.clear(); // delete the vector - p1.reset(0); - - fVal[2] = p2.Eval(); - - // Test assignement operator - // additionally disable Optimizer this time - qmu::QmuParser p3; - p3 = p2; - p3.EnableOptimizer(false); - fVal[3] = p3.Eval(); - - // Test Eval function for multiple return values - // use p2 since it has the optimizer enabled! - int nNum; - qreal *v = p2.Eval(nNum); - fVal[4] = v[nNum-1]; - } - catch(std::exception &e) - { - qDebug() << "\n " << e.what() << "\n"; - } - - // limited floating point accuracy requires the following test - bool bCloseEnough(true); - for (unsigned i=0; i::has_infinity) - bCloseEnough &= (fabs(fVal[i]) != numeric_limits::infinity()); - } - - iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1; - - - if (iRet==1) - { - qDebug() << "\n fail: " << a_str - << " (incorrect result; expected: " << a_fRes - << " ;calculated: " << fVal[0] << "," - << fVal[1] << "," - << fVal[2] << "," - << fVal[3] << "," - << fVal[4] << ")."; - } - } - catch(QmuParser::exception_type &e) - { - if (a_fPass) - { - if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998) - qDebug() << "\n fail: " << a_str << " (copy construction)"; - else - qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; - return 1; - } - } - catch(std::exception &e) - { - qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; - return 1; // always return a failure since this exception is not expected - } - catch(...) - { - qDebug() << "\n fail: " << a_str << " (unexpected exception)"; - return 1; // exceptions other than ParserException are not allowed - } - - return iRet; - } - - //--------------------------------------------------------------------------- - /** \brief Internal error in test class Test is going to be aborted. */ - void QmuParserTester::Abort() const - { - qDebug() << "Test failed (internal error in test class)" ; - while (!getchar()); - exit(-1); - } - } // namespace test -} // namespace qmu +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsertest.h" +#include +#include + +#include +#include +#include + +using namespace std; + +/** + * @file + * @brief This file contains the implementation of parser test cases. + */ + +namespace qmu +{ +namespace Test +{ +int QmuParserTester::c_iCount = 0; + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserTester::QmuParserTester() + : m_vTestFun() +{ + AddTest ( &QmuParserTester::TestNames ); + AddTest ( &QmuParserTester::TestSyntax ); + AddTest ( &QmuParserTester::TestPostFix ); + AddTest ( &QmuParserTester::TestInfixOprt ); + AddTest ( &QmuParserTester::TestVarConst ); + AddTest ( &QmuParserTester::TestMultiArg ); + AddTest ( &QmuParserTester::TestExpression ); + AddTest ( &QmuParserTester::TestIfThenElse ); + AddTest ( &QmuParserTester::TestInterface ); + AddTest ( &QmuParserTester::TestBinOprt ); + AddTest ( &QmuParserTester::TestException ); + AddTest ( &QmuParserTester::TestStrArg ); + + QmuParserTester::c_iCount = 0; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ) +{ + if ( a_szExpr[1] == 0 || ( a_szExpr[0] != '0' || a_szExpr[1] != 'x' ) ) + { + return 0; + } + + unsigned iVal ( 0 ); + bool ok = false; + iVal = a_szExpr.toUInt ( &ok, 16 ); + + if ( ok ) + { + int nPos = a_szExpr.indexOf ( QString().setNum ( iVal, 16 ) ); + if ( nPos == 0 ) + { + return 1; + } + + *a_iPos += ( int ) ( 2 + nPos ); + *a_fVal = ( qreal ) iVal; + return 1; + } + else + { + return 0; + } + +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestInterface() +{ + int iStat = 0; + qDebug() << "testing member functions..."; + + // Test RemoveVar + qreal afVal[3] = {1, 2, 3}; + QmuParser p; + + try + { + p.DefineVar ( "a", &afVal[0] ); + p.DefineVar ( "b", &afVal[1] ); + p.DefineVar ( "c", &afVal[2] ); + p.SetExpr ( "a+b+c" ); + p.Eval(); + } + catch ( ... ) + { + iStat += 1; // this is not supposed to happen + } + + try + { + p.RemoveVar ( "c" ); + p.Eval(); + iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... + } + catch ( ... ) + { + // failure is expected... + } + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestStrArg() +{ + int iStat = 0; + qDebug() << "testing string arguments..."; + + iStat += EqnTest ( "valueof(\"\")", 123, true ); // empty string arguments caused a crash + iStat += EqnTest ( "valueof(\"aaa\")+valueof(\"bbb\") ", 246, true ); + iStat += EqnTest ( "2*(valueof(\"aaa\")-23)+valueof(\"bbb\")", 323, true ); + // use in expressions with variables + iStat += EqnTest ( "a*(atof(\"10\")-b)", 8, true ); + iStat += EqnTest ( "a-(atof(\"10\")*b)", -19, true ); + // string + numeric arguments + iStat += EqnTest ( "strfun1(\"100\")", 100, true ); + iStat += EqnTest ( "strfun2(\"100\",1)", 101, true ); + iStat += EqnTest ( "strfun3(\"99\",1,2)", 102, true ); + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestBinOprt() +{ + int iStat = 0; + qDebug() << "testing binary operators..."; + + // built in operators + // xor operator + //iStat += EqnTest("1 xor 2", 3, true); + //iStat += EqnTest("a xor b", 3, true); // with a=1 and b=2 + //iStat += EqnTest("1 xor 2 xor 3", 0, true); + //iStat += EqnTest("a xor b xor 3", 0, true); // with a=1 and b=2 + //iStat += EqnTest("a xor b xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("(1 xor 2) xor 3", 0, true); + //iStat += EqnTest("(a xor b) xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("(a) xor (b) xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("1 or 2"), 3, true; + //iStat += EqnTest("a or b"), 3, true; // with a=1 and b=2 + iStat += EqnTest ( "a++b", 3, true ); + iStat += EqnTest ( "a ++ b", 3, true ); + iStat += EqnTest ( "1++2", 3, true ); + iStat += EqnTest ( "1 ++ 2", 3, true ); + iStat += EqnTest ( "a add b", 3, true ); + iStat += EqnTest ( "1 add 2", 3, true ); + iStat += EqnTest ( "aa", 1, true ); + iStat += EqnTest ( "a>a", 0, true ); + iStat += EqnTest ( "aa", 0, true ); + iStat += EqnTest ( "a<=a", 1, true ); + iStat += EqnTest ( "a<=b", 1, true ); + iStat += EqnTest ( "b<=a", 0, true ); + iStat += EqnTest ( "a>=a", 1, true ); + iStat += EqnTest ( "b>=a", 1, true ); + iStat += EqnTest ( "a>=b", 0, true ); + + // Test logical operators, expecially if user defined "&" and the internal "&&" collide + iStat += EqnTest ( "1 && 1", 1, true ); + iStat += EqnTest ( "1 && 0", 0, true ); + iStat += EqnTest ( "(aa)", 1, true ); + iStat += EqnTest ( "(ab)", 0, true ); + //iStat += EqnTest("12 and 255", 12, true); + //iStat += EqnTest("12 and 0", 0, true); + iStat += EqnTest ( "12 & 255", 12, true ); + iStat += EqnTest ( "12 & 0", 0, true ); + iStat += EqnTest ( "12&255", 12, true ); + iStat += EqnTest ( "12&0", 0, true ); + + // Assignement operator + iStat += EqnTest ( "a = b", 2, true ); + iStat += EqnTest ( "a = sin(b)", 0.909297, true ); + iStat += EqnTest ( "a = 1+sin(b)", 1.909297, true ); + iStat += EqnTest ( "(a=b)*2", 4, true ); + iStat += EqnTest ( "2*(a=b)", 4, true ); + iStat += EqnTest ( "2*(a=b+1)", 6, true ); + iStat += EqnTest ( "(a=b+1)*2", 6, true ); + + iStat += EqnTest ( "2^2^3", 256, true ); + iStat += EqnTest ( "1/2/3", 1.0 / 6.0, true ); + + // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 + iStat += EqnTest ( "3+4*2/(1-5)^2^3", 3.0001220703125, true ); + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** @brief Check muParser name restriction enforcement. */ +int QmuParserTester::TestNames() +{ + int iStat = 0, + iErr = 0; + + qDebug() << "testing name restriction enforcement..."; + + QmuParser p; + +#define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \ + iErr = 0; \ + QmuParserTester::c_iCount++; \ + try \ + { \ + p.Define##DOMAIN(EXPR, ARG); \ + } \ + catch(QmuParser::exception_type&) \ + { \ + iErr = (FAIL==false) ? 0 : 1; \ + } \ + iStat += iErr; + + // constant names + PARSER_THROWCHECK ( Const, false, "0a", 1 ) + PARSER_THROWCHECK ( Const, false, "9a", 1 ) + PARSER_THROWCHECK ( Const, false, "+a", 1 ) + PARSER_THROWCHECK ( Const, false, "-a", 1 ) + PARSER_THROWCHECK ( Const, false, "a-", 1 ) + PARSER_THROWCHECK ( Const, false, "a*", 1 ) + PARSER_THROWCHECK ( Const, false, "a?", 1 ) + PARSER_THROWCHECK ( Const, true, "a", 1 ) + PARSER_THROWCHECK ( Const, true, "a_min", 1 ) + PARSER_THROWCHECK ( Const, true, "a_min0", 1 ) + PARSER_THROWCHECK ( Const, true, "a_min9", 1 ) + // variable names + qreal a; + p.ClearConst(); + PARSER_THROWCHECK ( Var, false, "123abc", &a ) + PARSER_THROWCHECK ( Var, false, "9a", &a ) + PARSER_THROWCHECK ( Var, false, "0a", &a ) + PARSER_THROWCHECK ( Var, false, "+a", &a ) + PARSER_THROWCHECK ( Var, false, "-a", &a ) + PARSER_THROWCHECK ( Var, false, "?a", &a ) + PARSER_THROWCHECK ( Var, false, "!a", &a ) + PARSER_THROWCHECK ( Var, false, "a+", &a ) + PARSER_THROWCHECK ( Var, false, "a-", &a ) + PARSER_THROWCHECK ( Var, false, "a*", &a ) + PARSER_THROWCHECK ( Var, false, "a?", &a ) + PARSER_THROWCHECK ( Var, true, "a", &a ) + PARSER_THROWCHECK ( Var, true, "a_min", &a ) + PARSER_THROWCHECK ( Var, true, "a_min0", &a ) + PARSER_THROWCHECK ( Var, true, "a_min9", &a ) + PARSER_THROWCHECK ( Var, false, "a_min9", 0 ) + // Postfix operators + // fail + PARSER_THROWCHECK ( PostfixOprt, false, "(k", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, false, "9+", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, false, "+", 0 ) + // pass + PARSER_THROWCHECK ( PostfixOprt, true, "-a", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "?a", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "_", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "#", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "&&", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "||", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "&", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "|", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "++", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "--", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "?>", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "?<", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "**", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "xor", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "and", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "or", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "not", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "!", f1of1 ) + // Binary operator + // The following must fail with builtin operators activated + // p.EnableBuiltInOp(true); -> this is the default + p.ClearPostfixOprt(); + PARSER_THROWCHECK ( Oprt, false, "+", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "-", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "*", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "/", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "^", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "&&", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "||", f1of2 ) + // without activated built in operators it should work + p.EnableBuiltInOprt ( false ); + PARSER_THROWCHECK ( Oprt, true, "+", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "-", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "*", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "/", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "^", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "&&", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "||", f1of2 ) +#undef PARSER_THROWCHECK + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestSyntax() +{ + int iStat = 0; + qDebug() << "testing syntax engine..."; + + iStat += ThrowTest ( "1,", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "a,", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "sin(8),", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "(sin(8)),", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "a{m},", ecUNEXPECTED_EOF ); // incomplete hex definition + + iStat += EqnTest ( "(1+ 2*a)", 3, true ); // Spaces within formula + iStat += EqnTest ( "sqrt((4))", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt((2)+2)", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt(2+(2))", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt(a+(3))", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt((3)+a)", 2, true ); // Multiple brackets + iStat += EqnTest ( "order(1,2)", 1, true ); // May not cause name collision with operator "or" + iStat += EqnTest ( "(2+", 0, false ); // missing closing bracket + iStat += EqnTest ( "2++4", 0, false ); // unexpected operator + iStat += EqnTest ( "2+-4", 0, false ); // unexpected operator + iStat += EqnTest ( "(2+)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "--2", 0, false ); // double sign + iStat += EqnTest ( "ksdfj", 0, false ); // unknown token + iStat += EqnTest ( "()", 0, false ); // empty bracket without a function + iStat += EqnTest ( "5+()", 0, false ); // empty bracket without a function + iStat += EqnTest ( "sin(cos)", 0, false ); // unexpected function + iStat += EqnTest ( "5t6", 0, false ); // unknown token + iStat += EqnTest ( "5 t 6", 0, false ); // unknown token + iStat += EqnTest ( "8*", 0, false ); // unexpected end of formula + iStat += EqnTest ( ",3", 0, false ); // unexpected comma + iStat += EqnTest ( "3,5", 0, false ); // unexpected comma + iStat += EqnTest ( "sin(8,8)", 0, false ); // too many function args + iStat += EqnTest ( "(7,8)", 0, false ); // too many function args + iStat += EqnTest ( "sin)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "a)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "pi)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "sin(())", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "sin()", 0, false ); // unexpected closing bracket + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestVarConst() +{ + int iStat = 0; + qDebug() << "testing variable/constant detection..."; + + // Test if the result changes when a variable changes + iStat += EqnTestWithVarChange ( "a", 1, 1, 2, 2 ); + iStat += EqnTestWithVarChange ( "2*a", 2, 4, 3, 6 ); + + // distinguish constants with same basename + iStat += EqnTest ( "const", 1, true ); + iStat += EqnTest ( "const1", 2, true ); + iStat += EqnTest ( "const2", 3, true ); + iStat += EqnTest ( "2*const", 2, true ); + iStat += EqnTest ( "2*const1", 4, true ); + iStat += EqnTest ( "2*const2", 6, true ); + iStat += EqnTest ( "2*const+1", 3, true ); + iStat += EqnTest ( "2*const1+1", 5, true ); + iStat += EqnTest ( "2*const2+1", 7, true ); + iStat += EqnTest ( "const", 0, false ); + iStat += EqnTest ( "const1", 0, false ); + iStat += EqnTest ( "const2", 0, false ); + + // distinguish variables with same basename + iStat += EqnTest ( "a", 1, true ); + iStat += EqnTest ( "aa", 2, true ); + iStat += EqnTest ( "2*a", 2, true ); + iStat += EqnTest ( "2*aa", 4, true ); + iStat += EqnTest ( "2*a-1", 1, true ); + iStat += EqnTest ( "2*aa-1", 3, true ); + + // custom value recognition + iStat += EqnTest ( "0xff", 255, true ); + iStat += EqnTest ( "0x97 + 0xff", 406, true ); + + // Finally test querying of used variables + try + { + int idx; + qmu::QmuParser p; + qreal vVarVal[] = { 1, 2, 3, 4, 5}; + p.DefineVar ( "a", &vVarVal[0] ); + p.DefineVar ( "b", &vVarVal[1] ); + p.DefineVar ( "c", &vVarVal[2] ); + p.DefineVar ( "d", &vVarVal[3] ); + p.DefineVar ( "e", &vVarVal[4] ); + + // Test lookup of defined variables + // 4 used variables + p.SetExpr ( "a+b+c+d" ); + qmu::varmap_type UsedVar = p.GetUsedVar(); + int iCount = ( int ) UsedVar.size(); + if ( iCount != 4 ) + { + throw false; + } + + // the next check will fail if the parser + // erroneousely creates new variables internally + if ( p.GetVar().size() != 5 ) + { + throw false; + } + + qmu::varmap_type::const_iterator item = UsedVar.begin(); + for ( idx = 0; item != UsedVar.end(); ++item ) + { + if ( &vVarVal[idx++] != item->second ) + { + throw false; + } + } + + // Test lookup of undefined variables + p.SetExpr ( "undef1+undef2+undef3" ); + UsedVar = p.GetUsedVar(); + iCount = ( int ) UsedVar.size(); + if ( iCount != 3 ) + { + throw false; + } + + // the next check will fail if the parser + // erroneousely creates new variables internally + if ( p.GetVar().size() != 5 ) + { + throw false; + } + + for ( item = UsedVar.begin(); item != UsedVar.end(); ++item ) + { + if ( item->second != 0 ) + { + throw false; // all pointers to undefined variables must be null + } + } + + // 1 used variables + p.SetExpr ( "a+b" ); + UsedVar = p.GetUsedVar(); + iCount = ( int ) UsedVar.size(); + if ( iCount != 2 ) + { + throw false; + } + item = UsedVar.begin(); + for ( idx = 0; item != UsedVar.end(); ++item ) + { + if ( &vVarVal[idx++] != item->second ) + { + throw false; + } + } + + } + catch ( ... ) + { + iStat += 1; + } + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestMultiArg() +{ + int iStat = 0; + qDebug() << "testing multiarg functions..."; + + // Compound expressions + iStat += EqnTest ( "1,2,3", 3, true ); + iStat += EqnTest ( "a,b,c", 3, true ); + iStat += EqnTest ( "a=10,b=20,c=a*b", 200, true ); + iStat += EqnTest ( "1,\n2,\n3", 3, true ); + iStat += EqnTest ( "a,\nb,\nc", 3, true ); + iStat += EqnTest ( "a=10,\nb=20,\nc=a*b", 200, true ); + iStat += EqnTest ( "1,\r\n2,\r\n3", 3, true ); + iStat += EqnTest ( "a,\r\nb,\r\nc", 3, true ); + iStat += EqnTest ( "a=10,\r\nb=20,\r\nc=a*b", 200, true ); + + // picking the right argument + iStat += EqnTest ( "f1of1(1)", 1, true ); + iStat += EqnTest ( "f1of2(1, 2)", 1, true ); + iStat += EqnTest ( "f2of2(1, 2)", 2, true ); + iStat += EqnTest ( "f1of3(1, 2, 3)", 1, true ); + iStat += EqnTest ( "f2of3(1, 2, 3)", 2, true ); + iStat += EqnTest ( "f3of3(1, 2, 3)", 3, true ); + iStat += EqnTest ( "f1of4(1, 2, 3, 4)", 1, true ); + iStat += EqnTest ( "f2of4(1, 2, 3, 4)", 2, true ); + iStat += EqnTest ( "f3of4(1, 2, 3, 4)", 3, true ); + iStat += EqnTest ( "f4of4(1, 2, 3, 4)", 4, true ); + iStat += EqnTest ( "f1of5(1, 2, 3, 4, 5)", 1, true ); + iStat += EqnTest ( "f2of5(1, 2, 3, 4, 5)", 2, true ); + iStat += EqnTest ( "f3of5(1, 2, 3, 4, 5)", 3, true ); + iStat += EqnTest ( "f4of5(1, 2, 3, 4, 5)", 4, true ); + iStat += EqnTest ( "f5of5(1, 2, 3, 4, 5)", 5, true ); + // Too few arguments / Too many arguments + iStat += EqnTest ( "1+ping()", 11, true ); + iStat += EqnTest ( "ping()+1", 11, true ); + iStat += EqnTest ( "2*ping()", 20, true ); + iStat += EqnTest ( "ping()*2", 20, true ); + iStat += EqnTest ( "ping(1,2)", 0, false ); + iStat += EqnTest ( "1+ping(1,2)", 0, false ); + iStat += EqnTest ( "f1of1(1,2)", 0, false ); + iStat += EqnTest ( "f1of1()", 0, false ); + iStat += EqnTest ( "f1of2(1, 2, 3)", 0, false ); + iStat += EqnTest ( "f1of2(1)", 0, false ); + iStat += EqnTest ( "f1of3(1, 2, 3, 4)", 0, false ); + iStat += EqnTest ( "f1of3(1)", 0, false ); + iStat += EqnTest ( "f1of4(1, 2, 3, 4, 5)", 0, false ); + iStat += EqnTest ( "f1of4(1)", 0, false ); + iStat += EqnTest ( "(1,2,3)", 0, false ); + iStat += EqnTest ( "1,2,3", 0, false ); + iStat += EqnTest ( "(1*a,2,3)", 0, false ); + iStat += EqnTest ( "1,2*a,3", 0, false ); + + // correct calculation of arguments + iStat += EqnTest ( "min(a, 1)", 1, true ); + iStat += EqnTest ( "min(3*2, 1)", 1, true ); + iStat += EqnTest ( "min(3*2, 1)", 6, false ); + iStat += EqnTest ( "firstArg(2,3,4)", 2, true ); + iStat += EqnTest ( "lastArg(2,3,4)", 4, true ); + iStat += EqnTest ( "min(3*a+1, 1)", 1, true ); + iStat += EqnTest ( "max(3*a+1, 1)", 4, true ); + iStat += EqnTest ( "max(3*a+1, 1)*2", 8, true ); + iStat += EqnTest ( "2*max(3*a+1, 1)+2", 10, true ); + + // functions with Variable argument count + iStat += EqnTest ( "sum(a)", 1, true ); + iStat += EqnTest ( "sum(1,2,3)", 6, true ); + iStat += EqnTest ( "sum(a,b,c)", 6, true ); + iStat += EqnTest ( "sum(1,-max(1,2),3)*2", 4, true ); + iStat += EqnTest ( "2*sum(1,2,3)", 12, true ); + iStat += EqnTest ( "2*sum(1,2,3)+2", 14, true ); + iStat += EqnTest ( "2*sum(-1,2,3)+2", 10, true ); + iStat += EqnTest ( "2*sum(-1,2,-(-a))+2", 6, true ); + iStat += EqnTest ( "2*sum(-1,10,-a)+2", 18, true ); + iStat += EqnTest ( "2*sum(1,2,3)*2", 24, true ); + iStat += EqnTest ( "sum(1,-max(1,2),3)*2", 4, true ); + iStat += EqnTest ( "sum(1*3, 4, a+2)", 10, true ); + iStat += EqnTest ( "sum(1*3, 2*sum(1,2,2), a+2)", 16, true ); + iStat += EqnTest ( "sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)", 24, true ); + + // some failures + iStat += EqnTest ( "sum()", 0, false ); + iStat += EqnTest ( "sum(,)", 0, false ); + iStat += EqnTest ( "sum(1,2,)", 0, false ); + iStat += EqnTest ( "sum(,1,2)", 0, false ); + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestInfixOprt() +{ + int iStat ( 0 ); + qDebug() << "testing infix operators..."; + + iStat += EqnTest ( "-1", -1, true ); + iStat += EqnTest ( "-(-1)", 1, true ); + iStat += EqnTest ( "-(-1)*2", 2, true ); + iStat += EqnTest ( "-(-2)*sqrt(4)", 4, true ); + iStat += EqnTest ( "-_pi", -M_PI, true ); + iStat += EqnTest ( "-a", -1, true ); + iStat += EqnTest ( "-(a)", -1, true ); + iStat += EqnTest ( "-(-a)", 1, true ); + iStat += EqnTest ( "-(-a)*2", 2, true ); + iStat += EqnTest ( "-(8)", -8, true ); + iStat += EqnTest ( "-8", -8, true ); + iStat += EqnTest ( "-(2+1)", -3, true ); + iStat += EqnTest ( "-(f1of1(1+2*3)+1*2)", -9, true ); + iStat += EqnTest ( "-(-f1of1(1+2*3)+1*2)", 5, true ); + iStat += EqnTest ( "-sin(8)", -0.989358, true ); + iStat += EqnTest ( "3-(-a)", 4, true ); + iStat += EqnTest ( "3--a", 4, true ); + iStat += EqnTest ( "-1*3", -3, true ); + + // Postfix / infix priorities + iStat += EqnTest ( "~2#", 8, true ); + iStat += EqnTest ( "~f1of1(2)#", 8, true ); + iStat += EqnTest ( "~(b)#", 8, true ); + iStat += EqnTest ( "(~b)#", 12, true ); + iStat += EqnTest ( "~(2#)", 8, true ); + iStat += EqnTest ( "~(f1of1(2)#)", 8, true ); + // + iStat += EqnTest ( "-2^2", -4, true ); + iStat += EqnTest ( "-(a+b)^2", -9, true ); + iStat += EqnTest ( "(-3)^2", 9, true ); + iStat += EqnTest ( "-(-2^2)", 4, true ); + iStat += EqnTest ( "3+-3^2", -6, true ); + // The following assumes use of sqr as postfix operator ("") together + // with a sign operator of low priority: + iStat += EqnTest ( "-2'", -4, true ); + iStat += EqnTest ( "-(1+1)'", -4, true ); + iStat += EqnTest ( "2+-(1+1)'", -2, true ); + iStat += EqnTest ( "2+-2'", -2, true ); + // This is the classic behaviour of the infix sign operator (here: "$") which is + // now deprecated: + iStat += EqnTest ( "$2^2", 4, true ); + iStat += EqnTest ( "$(a+b)^2", 9, true ); + iStat += EqnTest ( "($3)^2", 9, true ); + iStat += EqnTest ( "$($2^2)", -4, true ); + iStat += EqnTest ( "3+$3^2", 12, true ); + + // infix operators sharing the first few characters + iStat += EqnTest ( "~ 123", 123 + 2, true ); + iStat += EqnTest ( "~~ 123", 123 + 2, true ); + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestPostFix() +{ + int iStat = 0; + qDebug() << "testing postfix operators..."; + + // application + iStat += EqnTest ( "3{m}+5", 5.003, true ); + iStat += EqnTest ( "1000{m}", 1, true ); + iStat += EqnTest ( "1000 {m}", 1, true ); + iStat += EqnTest ( "(a){m}", 1e-3, true ); + iStat += EqnTest ( "a{m}", 1e-3, true ); + iStat += EqnTest ( "a {m}", 1e-3, true ); + iStat += EqnTest ( "-(a){m}", -1e-3, true ); + iStat += EqnTest ( "-2{m}", -2e-3, true ); + iStat += EqnTest ( "-2 {m}", -2e-3, true ); + iStat += EqnTest ( "f1of1(1000){m}", 1, true ); + iStat += EqnTest ( "-f1of1(1000){m}", -1, true ); + iStat += EqnTest ( "-f1of1(-1000){m}", 1, true ); + iStat += EqnTest ( "f4of4(0,0,0,1000){m}", 1, true ); + iStat += EqnTest ( "2+(a*1000){m}", 3, true ); + + // can postfix operators "m" und "meg" be told apart properly? + iStat += EqnTest ( "2*3000meg+2", 2 * 3e9 + 2, true ); + + // some incorrect results + iStat += EqnTest ( "1000{m}", 0.1, false ); + iStat += EqnTest ( "(a){m}", 2, false ); + // failure due to syntax checking + iStat += ThrowTest ( "0x", ecUNASSIGNABLE_TOKEN ); // incomplete hex definition + iStat += ThrowTest ( "3+", ecUNEXPECTED_EOF ); + iStat += ThrowTest ( "4 + {m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "{m}4", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "sin({m})", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "{m} {m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "{m}(8)", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "4,{m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "-{m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "2(-{m})", ecUNEXPECTED_PARENS ); + iStat += ThrowTest ( "2({m})", ecUNEXPECTED_PARENS ); + + iStat += ThrowTest ( "multi*1.0", ecUNASSIGNABLE_TOKEN ); + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestExpression() +{ + int iStat = 0; + qDebug() << "testing expression samples..."; + + qreal b = 2; + + // Optimization + iStat += EqnTest ( "2*b*5", 20, true ); + iStat += EqnTest ( "2*b*5 + 4*b", 28, true ); + iStat += EqnTest ( "2*a/3", 2.0 / 3.0, true ); + + // Addition auf cmVARMUL + iStat += EqnTest ( "3+b", b + 3, true ); + iStat += EqnTest ( "b+3", b + 3, true ); + iStat += EqnTest ( "b*3+2", b * 3 + 2, true ); + iStat += EqnTest ( "3*b+2", b * 3 + 2, true ); + iStat += EqnTest ( "2+b*3", b * 3 + 2, true ); + iStat += EqnTest ( "2+3*b", b * 3 + 2, true ); + iStat += EqnTest ( "b+3*b", b + 3 * b, true ); + iStat += EqnTest ( "3*b+b", b + 3 * b, true ); + + iStat += EqnTest ( "2+b*3+b", 2 + b * 3 + b, true ); + iStat += EqnTest ( "b+2+b*3", b + 2 + b * 3, true ); + + iStat += EqnTest ( "(2*b+1)*4", ( 2 * b + 1 ) * 4, true ); + iStat += EqnTest ( "4*(2*b+1)", ( 2 * b + 1 ) * 4, true ); + + // operator precedencs + iStat += EqnTest ( "1+2-3*4/5^6", 2.99923, true ); + iStat += EqnTest ( "1^2/3*4-5+6", 2.33333333, true ); + iStat += EqnTest ( "1+2*3", 7, true ); + iStat += EqnTest ( "1+2*3", 7, true ); + iStat += EqnTest ( "(1+2)*3", 9, true ); + iStat += EqnTest ( "(1+2)*(-3)", -9, true ); + iStat += EqnTest ( "2/4", 0.5, true ); + + iStat += EqnTest ( "exp(ln(7))", 7, true ); + iStat += EqnTest ( "e^ln(7)", 7, true ); + iStat += EqnTest ( "e^(ln(7))", 7, true ); + iStat += EqnTest ( "(e^(ln(7)))", 7, true ); + iStat += EqnTest ( "1-(e^(ln(7)))", -6, true ); + iStat += EqnTest ( "2*(e^(ln(7)))", 14, true ); + iStat += EqnTest ( "10^log(5)", 5, true ); + iStat += EqnTest ( "10^log10(5)", 5, true ); + iStat += EqnTest ( "2^log2(4)", 4, true ); + iStat += EqnTest ( "-(sin(0)+1)", -1, true ); + iStat += EqnTest ( "-(2^1.1)", -2.14354692, true ); + + iStat += EqnTest ( "(cos(2.41)/b)", -0.372056, true ); + iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160, true ); + iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120, true ); + iStat += EqnTest ( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))", + 0.00377999, true ); + + // long formula (Reference: Matlab) + iStat += EqnTest ( + "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))" + "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/" + "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-" + "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6" + "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e" + "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549, true ); + + // long formula (Reference: Matlab) + iStat += EqnTest ( + "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e" + ")+a)))*2.77)", -2.16995656, true ); + + // long formula (Reference: Matlab) + iStat += EqnTest ( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true ); + + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } + + return iStat; +} + + + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::TestIfThenElse() +{ + int iStat = 0; + qDebug() << "testing if-then-else operator..."; + + // Test error detection + iStat += ThrowTest ( ":3", ecUNEXPECTED_CONDITIONAL ); + iStat += ThrowTest ( "? 1 : 2", ecUNEXPECTED_CONDITIONAL ); + iStat += ThrowTest ( "(ab) ? 10 : 11", 11, true ); + iStat += EqnTest ( "(ab) ? c : d", -2, true ); + + iStat += EqnTest ( "(a>b) ? 1 : 0", 0, true ); + iStat += EqnTest ( "((a>b) ? 1 : 0) ? 1 : 2", 2, true ); + iStat += EqnTest ( "((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)", 2, true ); + iStat += EqnTest ( "((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)", 1, true ); + + iStat += EqnTest ( "sum((a>b) ? 1 : 2)", 2, true ); + iStat += EqnTest ( "sum((1) ? 1 : 2)", 1, true ); + iStat += EqnTest ( "sum((a>b) ? 1 : 2, 100)", 102, true ); + iStat += EqnTest ( "sum((1) ? 1 : 2, 100)", 101, true ); + iStat += EqnTest ( "sum(3, (a>b) ? 3 : 10)", 13, true ); + iStat += EqnTest ( "sum(3, (ab) ? 3 : 10)", 130, true ); + iStat += EqnTest ( "10*sum(3, (ab) ? 3 : 10)*10", 130, true ); + iStat += EqnTest ( "sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab)&&(a2)&&(1<2) ? 128 : 255", 255, true ); + iStat += EqnTest ( "((1<2)&&(1<2)) ? 128 : 255", 128, true ); + iStat += EqnTest ( "((1>2)&&(1<2)) ? 128 : 255", 255, true ); + iStat += EqnTest ( "((ab)&&(a0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 255, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)", 255, true ); + iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 128, true ); + iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)", 128, true ); + iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 32, true ); + iStat += EqnTest ( "1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 64, true ); + iStat += EqnTest ( "1>0 ? 50 : 1>0 ? 128 : 255", 50, true ); + iStat += EqnTest ( "1>0 ? 50 : (1>0 ? 128 : 255)", 50, true ); + iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 : 50", 128, true ); + iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16", 32, true ); + iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)", 32, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16", 255, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)", 255, true ); + iStat += EqnTest ( "1 ? 0 ? 128 : 255 : 1 ? 32 : 64", 255, true ); + + // assignment operators + iStat += EqnTest ( "a= 0 ? 128 : 255, a", 255, true ); + iStat += EqnTest ( "a=((a>b)&&(a + // this is now legal, for reference see: + // https://sourceforge.net/forum/message.php?msg_id=7411373 + // iStat += ThrowTest( "sin=9"), ecUNEXPECTED_OPERATOR); + //
    + + iStat += ThrowTest ( "(8)=5", ecUNEXPECTED_OPERATOR ); + iStat += ThrowTest ( "(a)=5", ecUNEXPECTED_OPERATOR ); + iStat += ThrowTest ( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT ); + + if ( iStat == 0 ) + { + qDebug() << "passed" ; + } + else + { + qDebug() << "\n failed with " << iStat << " errors" ; + } + + return iStat; +} + + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserTester::AddTest ( testfun_type a_pFun ) +{ + m_vTestFun.push_back ( a_pFun ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserTester::Run() +{ + int iStat = 0; + try + { + for ( int i = 0; i < ( int ) m_vTestFun.size(); ++i ) + { + iStat += ( this->*m_vTestFun[i] ) (); + } + } + catch ( QmuParser::exception_type &e ) + { + qDebug() << "\n" << e.GetMsg() ; + qDebug() << e.GetToken() ; + Abort(); + } + catch ( std::exception &e ) + { + qDebug() << e.what() ; + Abort(); + } + catch ( ... ) + { + qDebug() << "Internal error"; + Abort(); + } + + if ( iStat == 0 ) + { + qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" ; + } + else + { + qDebug() << "Test failed with " << iStat + << " errors (" << QmuParserTester::c_iCount + << " expressions)" ; + } + QmuParserTester::c_iCount = 0; +} + + +//---------------------------------------------------------------------------------------------------------------------- +int QmuParserTester::ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail ) +{ + QmuParserTester::c_iCount++; + + try + { + qreal fVal[] = {1, 1, 1}; + QmuParser p; + + p.DefineVar ( "a", &fVal[0] ); + p.DefineVar ( "b", &fVal[1] ); + p.DefineVar ( "c", &fVal[2] ); + p.DefinePostfixOprt ( "{m}", Milli ); + p.DefinePostfixOprt ( "m", Milli ); + p.DefineFun ( "ping", Ping ); + p.DefineFun ( "valueof", ValueOf ); + p.DefineFun ( "strfun1", StrFun1 ); + p.DefineFun ( "strfun2", StrFun2 ); + p.DefineFun ( "strfun3", StrFun3 ); + p.SetExpr ( a_str ); + p.Eval(); + } + catch ( QmuParserError &e ) + { + // output the formula in case of an failed test + if ( a_bFail == false || ( a_bFail == true && a_iErrc != e.GetCode() ) ) + { + qDebug() << "\n " + << "Expression: " << a_str + << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" + << " Expected:" << a_iErrc; + } + + return ( a_iErrc == e.GetCode() ) ? 0 : 1; + } + + // if a_bFail==false no exception is expected + bool bRet ( ( a_bFail == false ) ? 0 : 1 ); + if ( bRet == 1 ) + { + qDebug() << "\n " + << "Expression: " << a_str + << " did evaluate; Expected error:" << a_iErrc; + } + + return bRet; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Evaluate a tet expression. + * + * @return 1 in case of a failure, 0 otherwise. + */ +int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1, double a_fRes1, double a_fVar2, + double a_fRes2 ) +{ + QmuParserTester::c_iCount++; + qreal fVal[2] = { -999, -999 }; // should be equalinitially + + try + { + QmuParser p; + + // variable + qreal var = 0; + p.DefineVar ( "a", &var ); + p.SetExpr ( a_str ); + + var = a_fVar1; + fVal[0] = p.Eval(); + + var = a_fVar2; + fVal[1] = p.Eval(); + + if ( fabs ( a_fRes1 - fVal[0] ) > 0.0000000001 ) + { + throw std::runtime_error ( "incorrect result (first pass)" ); + } + + if ( fabs ( a_fRes2 - fVal[1] ) > 0.0000000001 ) + { + throw std::runtime_error ( "incorrect result (second pass)" ); + } + } + catch ( QmuParser::exception_type &e ) + { + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; + return 1; + } + catch ( std::exception &e ) + { + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; + return 1; // always return a failure since this exception is not expected + } + catch ( ... ) + { + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; + return 1; // exceptions other than ParserException are not allowed + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Evaluate a tet expression. + * + * @return 1 in case of a failure, 0 otherwise. + */ +int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ) +{ + QmuParserTester::c_iCount++; + int iRet ( 0 ); + qreal fVal[5] = { -999, -998, -997, -996, -995}; // initially should be different + + try + { + std::auto_ptr p1; + QmuParser p2, p3; // three parser objects + // they will be used for testing copy and assihnment operators + // p1 is a pointer since i'm going to delete it in order to test if + // parsers after copy construction still refer to members of it. + // !! If this is the case this function will crash !! + + p1.reset ( new qmu::QmuParser() ); + // Add constants + p1->DefineConst ( "pi", ( qreal ) M_PI ); + p1->DefineConst ( "e", ( qreal ) M_E ); + p1->DefineConst ( "const", 1 ); + p1->DefineConst ( "const1", 2 ); + p1->DefineConst ( "const2", 3 ); + // variables + qreal vVarVal[] = { 1, 2, 3, -2}; + p1->DefineVar ( "a", &vVarVal[0] ); + p1->DefineVar ( "aa", &vVarVal[1] ); + p1->DefineVar ( "b", &vVarVal[1] ); + p1->DefineVar ( "c", &vVarVal[2] ); + p1->DefineVar ( "d", &vVarVal[3] ); + + // custom value ident functions + p1->AddValIdent ( &QmuParserTester::IsHexVal ); + + // functions + p1->DefineFun ( "ping", Ping ); + p1->DefineFun ( "f1of1", f1of1 ); // one parameter + p1->DefineFun ( "f1of2", f1of2 ); // two parameter + p1->DefineFun ( "f2of2", f2of2 ); + p1->DefineFun ( "f1of3", f1of3 ); // three parameter + p1->DefineFun ( "f2of3", f2of3 ); + p1->DefineFun ( "f3of3", f3of3 ); + p1->DefineFun ( "f1of4", f1of4 ); // four parameter + p1->DefineFun ( "f2of4", f2of4 ); + p1->DefineFun ( "f3of4", f3of4 ); + p1->DefineFun ( "f4of4", f4of4 ); + p1->DefineFun ( "f1of5", f1of5 ); // five parameter + p1->DefineFun ( "f2of5", f2of5 ); + p1->DefineFun ( "f3of5", f3of5 ); + p1->DefineFun ( "f4of5", f4of5 ); + p1->DefineFun ( "f5of5", f5of5 ); + + // binary operators + p1->DefineOprt ( "add", add, 0 ); + p1->DefineOprt ( "++", add, 0 ); + p1->DefineOprt ( "&", land, prLAND ); + + // sample functions + p1->DefineFun ( "min", Min ); + p1->DefineFun ( "max", Max ); + p1->DefineFun ( "sum", Sum ); + p1->DefineFun ( "valueof", ValueOf ); + p1->DefineFun ( "atof", StrToFloat ); + p1->DefineFun ( "strfun1", StrFun1 ); + p1->DefineFun ( "strfun2", StrFun2 ); + p1->DefineFun ( "strfun3", StrFun3 ); + p1->DefineFun ( "lastArg", LastArg ); + p1->DefineFun ( "firstArg", FirstArg ); + p1->DefineFun ( "order", FirstArg ); + + // infix / postfix operator + // Note: Identifiers used here do not have any meaning + // they are mere placeholders to test certain features. + p1->DefineInfixOprt ( "$", sign, prPOW + 1 ); // sign with high priority + p1->DefineInfixOprt ( "~", plus2 ); // high priority + p1->DefineInfixOprt ( "~~", plus2 ); + p1->DefinePostfixOprt ( "{m}", Milli ); + p1->DefinePostfixOprt ( "{M}", Mega ); + p1->DefinePostfixOprt ( "m", Milli ); + p1->DefinePostfixOprt ( "meg", Mega ); + p1->DefinePostfixOprt ( "#", times3 ); + p1->DefinePostfixOprt ( "'", sqr ); + p1->SetExpr ( a_str ); + + // Test bytecode integrity + // String parsing and bytecode parsing must yield the same result + fVal[0] = p1->Eval(); // result from stringparsing + fVal[1] = p1->Eval(); // result from bytecode + if ( fVal[0] != fVal[1] ) + { + throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); + } + + // Test copy and assignement operators + try + { + // Test copy constructor + QVector vParser; + vParser.push_back ( * ( p1.get() ) ); + qmu::QmuParser p2 = vParser[0]; // take parser from vector + + // destroy the originals from p2 + vParser.clear(); // delete the vector + p1.reset ( 0 ); + + fVal[2] = p2.Eval(); + + // Test assignement operator + // additionally disable Optimizer this time + qmu::QmuParser p3; + p3 = p2; + p3.EnableOptimizer ( false ); + fVal[3] = p3.Eval(); + + // Test Eval function for multiple return values + // use p2 since it has the optimizer enabled! + int nNum; + qreal *v = p2.Eval ( nNum ); + fVal[4] = v[nNum - 1]; + } + catch ( std::exception &e ) + { + qDebug() << "\n " << e.what() << "\n"; + } + + // limited floating point accuracy requires the following test + bool bCloseEnough ( true ); + for ( unsigned i = 0; i < sizeof ( fVal ) / sizeof ( qreal ); ++i ) + { + bCloseEnough &= ( fabs ( a_fRes - fVal[i] ) <= fabs ( fVal[i] * 0.00001 ) ); + + // The tests equations never result in infinity, if they do thats a bug. + // reference: + // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825 + if ( numeric_limits::has_infinity ) + { + bCloseEnough &= ( fabs ( fVal[i] ) != numeric_limits::infinity() ); + } + } + + iRet = ( ( bCloseEnough && a_fPass ) || ( !bCloseEnough && !a_fPass ) ) ? 0 : 1; + + + if ( iRet == 1 ) + { + qDebug() << "\n fail: " << a_str + << " (incorrect result; expected: " << a_fRes + << " ;calculated: " << fVal[0] << "," + << fVal[1] << "," + << fVal[2] << "," + << fVal[3] << "," + << fVal[4] << ")."; + } + } + catch ( QmuParser::exception_type &e ) + { + if ( a_fPass ) + { + if ( fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998 ) + { + qDebug() << "\n fail: " << a_str << " (copy construction)"; + } + else + { + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; + } + return 1; + } + } + catch ( std::exception &e ) + { + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; + return 1; // always return a failure since this exception is not expected + } + catch ( ... ) + { + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; + return 1; // exceptions other than ParserException are not allowed + } + + return iRet; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Internal error in test class Test is going to be aborted. + */ +void QmuParserTester::Abort() const +{ + qDebug() << "Test failed (internal error in test class)" ; + while ( !getchar() ); + exit ( -1 ); +} +} // namespace test +} // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index b92338b3f..561bc3d2c 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -1,200 +1,302 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERTEST_H -#define QMUPARSERTEST_H - -#include -#include -#include // for accumulate -#include "qmuparser.h" -#include - -/** \file - \brief This file contains the parser test class. -*/ - -namespace qmu -{ - /** \brief Namespace for test cases. */ - namespace Test - { - //------------------------------------------------------------------------------ - /** \brief Test cases for unit testing. - - (C) 2004-2011 Ingo Berg - */ - class QmuParserTester // final - { - private: - static int c_iCount; - - // Multiarg callbacks - static qreal f1of1(qreal v) { return v;} - - static qreal f1of2(qreal v, qreal ) {return v;} - static qreal f2of2(qreal , qreal v) {return v;} - - static qreal f1of3(qreal v, qreal , qreal ) {return v;} - static qreal f2of3(qreal , qreal v, qreal ) {return v;} - static qreal f3of3(qreal , qreal , qreal v) {return v;} - - static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;} - static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;} - static qreal f3of4(qreal , qreal, qreal v, qreal ) {return v;} - static qreal f4of4(qreal , qreal, qreal , qreal v) {return v;} - - static qreal f1of5(qreal v, qreal, qreal , qreal , qreal ) { return v; } - static qreal f2of5(qreal , qreal v, qreal , qreal , qreal ) { return v; } - static qreal f3of5(qreal , qreal, qreal v, qreal , qreal ) { return v; } - static qreal f4of5(qreal , qreal, qreal , qreal v, qreal ) { return v; } - static qreal f5of5(qreal , qreal, qreal , qreal , qreal v) { return v; } - - static qreal Min(qreal a_fVal1, qreal a_fVal2) { return (a_fVal1a_fVal2) ? a_fVal1 : a_fVal2; } - - static qreal plus2(qreal v1) { return v1+2; } - static qreal times3(qreal v1) { return v1*3; } - static qreal sqr(qreal v1) { return v1*v1; } - static qreal sign(qreal v) { return -v; } - static qreal add(qreal v1, qreal v2) { return v1+v2; } - static qreal land(qreal v1, qreal v2) { return (int)v1 & (int)v2; } - - - static qreal FirstArg(const qreal* a_afArg, int a_iArgc) - { - if (!a_iArgc) - throw qmu::QmuParser::exception_type( "too few arguments for function FirstArg." ); - - return a_afArg[0]; - } - - static qreal LastArg(const qreal* a_afArg, int a_iArgc) - { - if (!a_iArgc) - throw qmu::QmuParser::exception_type( "too few arguments for function LastArg." ); - - return a_afArg[a_iArgc-1]; - } - - static qreal Sum(const qreal* a_afArg, int a_iArgc) - { - if (!a_iArgc) - throw qmu::QmuParser::exception_type( "too few arguments for function sum." ); - - qreal fRes=0; - for (int i=0; i m_vTestFun; - void AddTest(testfun_type a_pFun); - - // Test Double Parser - int EqnTest(const QString &a_str, double a_fRes, bool a_fPass); - int EqnTestWithVarChange(const QString &a_str, - double a_fRes1, - double a_fVar1, - double a_fRes2, - double a_fVar2); - int ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail = true); - }; - } // namespace Test -} // namespace qmu - -#endif - - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTEST_H +#define QMUPARSERTEST_H + +#include +#include +#include // for accumulate +#include "qmuparser.h" +#include + +/** + * @file + * @brief This file contains the parser test class. + */ + +namespace qmu +{ +/** + * @brief Namespace for test cases. + */ +namespace Test +{ +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Test cases for unit testing. + * + * (C) 2004-2011 Ingo Berg + */ +class QmuParserTester // final +{ +public: + typedef int ( QmuParserTester::*testfun_type ) (); + + QmuParserTester(); + void Run(); +private: + QVector m_vTestFun; + static int c_iCount; + + void AddTest ( testfun_type a_pFun ); + + // Test Double Parser + int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ); + int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 ); + int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true ); + + // Multiarg callbacks + static qreal f1of1 ( qreal v ) + { + return v; + } + + static qreal f1of2 ( qreal v, qreal ) + { + return v; + } + + static qreal f2of2 ( qreal , qreal v ) + { + return v; + } + + static qreal f1of3 ( qreal v, qreal , qreal ) + { + return v; + } + + static qreal f2of3 ( qreal , qreal v, qreal ) + { + return v; + } + + static qreal f3of3 ( qreal , qreal , qreal v ) + { + return v; + } + + static qreal f1of4 ( qreal v, qreal, qreal , qreal ) + { + return v; + } + + static qreal f2of4 ( qreal , qreal v, qreal , qreal ) + { + return v; + } + + static qreal f3of4 ( qreal , qreal, qreal v, qreal ) + { + return v; + } + + static qreal f4of4 ( qreal , qreal, qreal , qreal v ) + { + return v; + } + + static qreal f1of5 ( qreal v, qreal, qreal , qreal , qreal ) + { + return v; + } + + static qreal f2of5 ( qreal , qreal v, qreal , qreal , qreal ) + { + return v; + } + + static qreal f3of5 ( qreal , qreal, qreal v, qreal , qreal ) + { + return v; + } + + static qreal f4of5 ( qreal , qreal, qreal , qreal v, qreal ) + { + return v; + } + + static qreal f5of5 ( qreal , qreal, qreal , qreal , qreal v ) + { + return v; + } + + static qreal Min ( qreal a_fVal1, qreal a_fVal2 ) + { + return ( a_fVal1 < a_fVal2 ) ? a_fVal1 : a_fVal2; + } + + static qreal Max ( qreal a_fVal1, qreal a_fVal2 ) + { + return ( a_fVal1 > a_fVal2 ) ? a_fVal1 : a_fVal2; + } + + static qreal plus2 ( qreal v1 ) + { + return v1 + 2; + } + + static qreal times3 ( qreal v1 ) + { + return v1 * 3; + } + + static qreal sqr ( qreal v1 ) + { + return v1 * v1; + } + + static qreal sign ( qreal v ) + { + return -v; + } + + static qreal add ( qreal v1, qreal v2 ) + { + return v1 + v2; + } + + static qreal land ( qreal v1, qreal v2 ) + { + return ( int ) v1 & ( int ) v2; + } + + static qreal FirstArg ( const qreal* a_afArg, int a_iArgc ) + { + if ( !a_iArgc ) + { + throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." ); + } + + return a_afArg[0]; + } + + static qreal LastArg ( const qreal* a_afArg, int a_iArgc ) + { + if ( !a_iArgc ) + { + throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." ); + } + + return a_afArg[a_iArgc - 1]; + } + + static qreal Sum ( const qreal* a_afArg, int a_iArgc ) + { + if ( !a_iArgc ) + { + throw qmu::QmuParser::exception_type ( "too few arguments for function sum." ); + } + + qreal fRes = 0; + for ( int i = 0; i < a_iArgc; ++i ) + { + fRes += a_afArg[i]; + } + return fRes; + } + + static qreal Rnd ( qreal v ) + { + return ( qreal ) ( 1 + ( v * std::rand() / ( RAND_MAX + 1.0 ) ) ); + } + + static qreal RndWithString ( const char_type* ) + { + return ( qreal ) ( 1 + ( 1000.0f * std::rand() / ( RAND_MAX + 1.0 ) ) ); + } + + static qreal Ping() + { + return 10; + } + + static qreal ValueOf ( const QString & ) + { + return 123; + } + + static qreal StrFun1 ( const QString & v1 ) + { + int val = v1.toInt(); + return ( qreal ) val; + } + + static qreal StrFun2 ( const QString & v1, qreal v2 ) + { + int val = v1.toInt(); + return ( qreal ) ( val + v2 ); + } + + static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 ) + { + int val = v1.toInt(); + return val + v2 + v3; + } + + static qreal StrToFloat ( const QString & a_szMsg ) + { + qreal val = a_szMsg.toDouble(); + return val; + } + + // postfix operator callback + static qreal Mega ( qreal a_fVal ) + { + return a_fVal * ( qreal ) 1e6; + } + + static qreal Micro ( qreal a_fVal ) + { + return a_fVal * ( qreal ) 1e-6; + } + + static qreal Milli ( qreal a_fVal ) + { + return a_fVal / ( qreal ) 1e3; + } + + // Custom value recognition + static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ); + + int TestNames(); + int TestSyntax(); + int TestMultiArg(); + int TestPostFix(); + int TestExpression(); + int TestInfixOprt(); + int TestBinOprt(); + int TestVarConst(); + int TestInterface(); + int TestException(); + int TestStrArg(); + int TestIfThenElse(); + + void Abort() const; +}; +} // namespace Test +} // namespace qmu + +#endif + + diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 20e2b51bc..7253e234c 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -32,13 +32,13 @@ #include "qmuparsererror.h" #include "qmuparsercallback.h" -/** \file - \brief This file contains the parser token definition. +/** @file + @brief This file contains the parser token definition. */ namespace qmu { - /** \brief Encapsulation of the data for a single formula token. + /** @brief Encapsulation of the data for a single formula token. Formula token implementation. Part of the Math Parser Package. Formula tokens can be either one of the following: @@ -52,7 +52,7 @@ namespace qmu
  • binary operator
  • - \author (C) 2004-2013 Ingo Berg + @author (C) 2004-2013 Ingo Berg */ template class QmuParserToken @@ -71,11 +71,11 @@ namespace qmu public: //--------------------------------------------------------------------------- - /** \brief Constructor (default). + /** @brief Constructor (default). Sets token to an neutral state of type cmUNKNOWN. - \throw nothrow - \sa ECmdCode + @throw nothrow + @sa ECmdCode */ QmuParserToken() :m_iCode(cmUNKNOWN) @@ -87,12 +87,12 @@ namespace qmu {} //------------------------------------------------------------------------------ - /** \brief Create token from another one. + /** @brief Create token from another one. Implemented by calling Assign(...) - \throw nothrow - \post m_iType==cmUNKNOWN - \sa #Assign + @throw nothrow + @post m_iType==cmUNKNOWN + @sa #Assign */ QmuParserToken(const QmuParserToken &a_Tok) { @@ -100,11 +100,11 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Assignement operator. + /** @brief Assignement operator. Copy token state from another token and return this. Implemented by calling Assign(...). - \throw nothrow + @throw nothrow */ QmuParserToken& operator=(const QmuParserToken &a_Tok) { @@ -113,9 +113,9 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Copy token information from argument. + /** @brief Copy token information from argument. - \throw nothrow + @throw nothrow */ void Assign(const QmuParserToken &a_Tok) { @@ -131,15 +131,15 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Assign a token type. + /** @brief Assign a token type. Token may not be of type value, variable or function. Those have seperate set functions. \pre [assert] a_iType!=cmVAR \pre [assert] a_iType!=cmVAL \pre [assert] a_iType!=cmFUNC - \post m_fVal = 0 - \post m_pTok = 0 + @post m_fVal = 0 + @post m_pTok = 0 */ QmuParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString()) { @@ -158,7 +158,7 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Set Callback type. */ + /** @brief Set Callback type. */ QmuParserToken& Set(const QmuParserCallback &a_pCallback, const TString &a_sTok) { assert(a_pCallback.GetAddr()); @@ -175,10 +175,10 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Make this token a value token. + /** @brief Make this token a value token. Member variables not necessary for value tokens will be invalidated. - \throw nothrow + @throw nothrow */ QmuParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString()) { @@ -195,10 +195,10 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief make this token a variable token. + /** @brief make this token a variable token. Member variables not necessary for variable tokens will be invalidated. - \throw nothrow + @throw nothrow */ QmuParserToken& SetVar(TBase *a_pVar, const TString &a_strTok) { @@ -212,10 +212,10 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Make this token a variable token. + /** @brief Make this token a variable token. Member variables not necessary for variable tokens will be invalidated. - \throw nothrow + @throw nothrow */ QmuParserToken& SetString(const TString &a_strTok, std::size_t a_iSize) { @@ -230,11 +230,11 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Set an index associated with the token related data. + /** @brief Set an index associated with the token related data. In cmSTRFUNC - This is the index to a string table in the main parser. - \param a_iIdx The index the string function result will take in the bytecode parser. - \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING + * @param a_iIdx The index the string function result will take in the bytecode parser. + @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING */ void SetIdx(int a_iIdx) { @@ -245,12 +245,12 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Return Index associated with the token related data. + /** @brief Return Index associated with the token related data. In cmSTRFUNC - This is the index to a string table in the main parser. - \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING - \return The index the result will take in the Bytecode calculatin array (#m_iIdx). + @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING + * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). */ int GetIdx() const { @@ -261,10 +261,10 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Return the token type. + /** @brief Return the token type. - \return #m_iType - \throw nothrow + * @return #m_iType + @throw nothrow */ ECmdCode GetCode() const { @@ -313,11 +313,11 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Return the address of the callback function assoziated with + /** @brief Return the address of the callback function assoziated with function and operator tokens. - \return The pointer stored in #m_pTok. - \throw exception_type if token type is non of: + * @return The pointer stored in #m_pTok. + @throw exception_type if token type is non of:
    • cmFUNC
    • cmSTRFUNC
    • @@ -325,7 +325,7 @@ namespace qmu
    • cmINFIXOP
    • cmOPRT_BIN
    - \sa ECmdCode + @sa ECmdCode */ generic_fun_type GetFuncAddr() const { @@ -336,7 +336,7 @@ namespace qmu /** \biref Get value of the token. Only applicable to variable and value tokens. - \throw exception_type if token is no value/variable token. + @throw exception_type if token is no value/variable token. */ TBase GetVal() const { @@ -349,10 +349,10 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Get address of a variable token. + /** @brief Get address of a variable token. Valid only if m_iType==CmdVar. - \throw exception_type if token is no variable token. + @throw exception_type if token is no variable token. */ TBase* GetVar() const { @@ -363,7 +363,7 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Return the number of function arguments. + /** @brief Return the number of function arguments. Valid only if m_iType==CmdFUNC. */ @@ -378,13 +378,13 @@ namespace qmu } //------------------------------------------------------------------------------ - /** \brief Return the token identifier. + /** @brief Return the token identifier. If #m_iType is cmSTRING the token identifier is the value of the string argument for a string function. - \return #m_strTok - \throw nothrow - \sa m_strTok + * @return #m_strTok + @throw nothrow + @sa m_strTok */ const TString& GetAsString() const { diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index f21e80bf8..c47d33851 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -1,995 +1,997 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include - -#include "qmuparsertokenreader.h" -#include "qmuparserbase.h" - -/** \file - \brief This file contains the parser token reader implementation. -*/ - - -namespace qmu -{ - - // Forward declaration - class QmuParserBase; - - //--------------------------------------------------------------------------- - /** \brief Copy constructor. - - \sa Assign - \throw nothrow - */ - QmuParserTokenReader::QmuParserTokenReader(const QmuParserTokenReader &a_Reader) - { - Assign(a_Reader); - } - - //--------------------------------------------------------------------------- - /** \brief Assignement operator. - - Self assignement will be suppressed otherwise #Assign is called. - - \param a_Reader Object to copy to this token reader. - \throw nothrow - */ - QmuParserTokenReader& QmuParserTokenReader::operator=(const QmuParserTokenReader &a_Reader) - { - if (&a_Reader!=this) - Assign(a_Reader); - - return *this; - } - - //--------------------------------------------------------------------------- - /** \brief Assign state of a token reader to this token reader. - - \param a_Reader Object from which the state should be copied. - \throw nothrow - */ - void QmuParserTokenReader::Assign(const QmuParserTokenReader &a_Reader) - { - m_pParser = a_Reader.m_pParser; - m_strFormula = a_Reader.m_strFormula; - m_iPos = a_Reader.m_iPos; - m_iSynFlags = a_Reader.m_iSynFlags; - - m_UsedVar = a_Reader.m_UsedVar; - m_pFunDef = a_Reader.m_pFunDef; - m_pConstDef = a_Reader.m_pConstDef; - m_pVarDef = a_Reader.m_pVarDef; - m_pStrVarDef = a_Reader.m_pStrVarDef; - m_pPostOprtDef = a_Reader.m_pPostOprtDef; - m_pInfixOprtDef = a_Reader.m_pInfixOprtDef; - m_pOprtDef = a_Reader.m_pOprtDef; - m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar; - m_vIdentFun = a_Reader.m_vIdentFun; - m_pFactory = a_Reader.m_pFactory; - m_pFactoryData = a_Reader.m_pFactoryData; - m_iBrackets = a_Reader.m_iBrackets; - m_cArgSep = a_Reader.m_cArgSep; - } - - //--------------------------------------------------------------------------- - /** \brief Constructor. - - Create a Token reader and bind it to a parser object. - - \pre [assert] a_pParser may not be NULL - \post #m_pParser==a_pParser - \param a_pParent Parent parser object of the token reader. - */ - QmuParserTokenReader::QmuParserTokenReader(QmuParserBase *a_pParent) - :m_pParser(a_pParent) - ,m_strFormula() - ,m_iPos(0) - ,m_iSynFlags(0) - ,m_bIgnoreUndefVar(false) - ,m_pFunDef(NULL) - ,m_pPostOprtDef(NULL) - ,m_pInfixOprtDef(NULL) - ,m_pOprtDef(NULL) - ,m_pConstDef(NULL) - ,m_pStrVarDef(NULL) - ,m_pVarDef(NULL) - ,m_pFactory(NULL) - ,m_pFactoryData(NULL) - ,m_vIdentFun() - ,m_UsedVar() - ,m_fZero(0) - ,m_iBrackets(0) - ,m_lastTok() - ,m_cArgSep(',') - { - assert(m_pParser); - SetParent(m_pParser); - } - - //--------------------------------------------------------------------------- - /** \brief Create instance of a QParserTokenReader identical with this - and return its pointer. - - This is a factory method the calling function must take care of the object destruction. - - \return A new QParserTokenReader object. - \throw nothrow - */ - QmuParserTokenReader* QmuParserTokenReader::Clone(QmuParserBase *a_pParent) const - { - std::auto_ptr ptr(new QmuParserTokenReader(*this)); - ptr->SetParent(a_pParent); - return ptr.release(); - } - - //--------------------------------------------------------------------------- - QmuParserTokenReader::token_type& QmuParserTokenReader::SaveBeforeReturn(const token_type &tok) - { - m_lastTok = tok; - return m_lastTok; - } - - //--------------------------------------------------------------------------- - void QmuParserTokenReader::AddValIdent(identfun_type a_pCallback) - { - // Use push_front is used to give user defined callbacks a higher priority than - // the built in ones. Otherwise reading hex numbers would not work - // since the "0" in "0xff" would always be read first making parsing of - // the rest impossible. - // reference: - // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956 - m_vIdentFun.push_front(a_pCallback); - } - - //--------------------------------------------------------------------------- - void QmuParserTokenReader::SetVarCreator(facfun_type a_pFactory, void *pUserData) - { - m_pFactory = a_pFactory; - m_pFactoryData = pUserData; - } - - //--------------------------------------------------------------------------- - /** \brief Return the current position of the token reader in the formula string. - - \return #m_iPos - \throw nothrow - */ - int QmuParserTokenReader::GetPos() const - { - return m_iPos; - } - - //--------------------------------------------------------------------------- - /** \brief Return a reference to the formula. - - \return #m_strFormula - \throw nothrow - */ - const QString& QmuParserTokenReader::GetExpr() const - { - return m_strFormula; - } - - //--------------------------------------------------------------------------- - /** \brief Return a map containing the used variables only. */ - varmap_type& QmuParserTokenReader::GetUsedVar() - { - return m_UsedVar; - } - - //--------------------------------------------------------------------------- - /** \brief Initialize the token Reader. - - Sets the formula position index to zero and set Syntax flags to default for initial formula parsing. - \pre [assert] triggered if a_szFormula==0 - */ - void QmuParserTokenReader::SetFormula(const QString &a_strFormula) - { - m_strFormula = a_strFormula; - ReInit(); - } - - //--------------------------------------------------------------------------- - /** \brief Set Flag that contronls behaviour in case of undefined variables beeing found. - - If true, the parser does not throw an exception if an undefined variable is found. - otherwise it does. This variable is used internally only! - It supresses a "undefined variable" exception in GetUsedVar(). - Those function should return a complete list of variables including - those the are not defined by the time of it's call. - */ - void QmuParserTokenReader::IgnoreUndefVar(bool bIgnore) - { - m_bIgnoreUndefVar = bIgnore; - } - - //--------------------------------------------------------------------------- - /** \brief Reset the token reader to the start of the formula. - - The syntax flags will be reset to a value appropriate for the - start of a formula. - \post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR - \throw nothrow - \sa ESynCodes - */ - void QmuParserTokenReader::ReInit() - { - m_iPos = 0; - m_iSynFlags = sfSTART_OF_LINE; - m_iBrackets = 0; - m_UsedVar.clear(); - m_lastTok = token_type(); - } - - //--------------------------------------------------------------------------- - /** \brief Read the next token from the string. */ - QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken() - { - assert(m_pParser); - - //std::stack FunArgs; -#if defined(_UNICODE) - const char_type *szFormula = m_strFormula.toStdWString().c_str(); -#else - const char_type *szFormula = m_strFormula.toStdString().c_str(); -#endif - token_type tok; - - // Ignore all non printable characters when reading the expression - while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20) - { - ++m_iPos; - } - - if ( IsEOF(tok) ) return SaveBeforeReturn(tok); // Check for end of formula - if ( IsOprt(tok) ) return SaveBeforeReturn(tok); // Check for user defined binary operator - if ( IsFunTok(tok) ) return SaveBeforeReturn(tok); // Check for function token - if ( IsBuiltIn(tok) ) return SaveBeforeReturn(tok); // Check built in operators / tokens - if ( IsArgSep(tok) ) return SaveBeforeReturn(tok); // Check for function argument separators - if ( IsValTok(tok) ) return SaveBeforeReturn(tok); // Check for values / constant tokens - if ( IsVarTok(tok) ) return SaveBeforeReturn(tok); // Check for variable tokens - if ( IsStrVarTok(tok) ) return SaveBeforeReturn(tok); // Check for string variables - if ( IsString(tok) ) return SaveBeforeReturn(tok); // Check for String tokens - if ( IsInfixOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators - if ( IsPostOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators - - // Check String for undefined variable token. Done only if a - // flag is set indicating to ignore undefined variables. - // This is a way to conditionally avoid an error if - // undefined variables occur. - // (The GetUsedVar function must suppress the error for - // undefined variables in order to collect all variable - // names including the undefined ones.) - if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) ) - { - return SaveBeforeReturn(tok); - } - - // Check for unknown token - // - // !!! From this point on there is no exit without an exception possible... - // - QString strTok; - int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); - if (iEnd!=m_iPos) - { - Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok); - } - - Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid(m_iPos)); - return token_type(); // never reached - } - - //--------------------------------------------------------------------------- - void QmuParserTokenReader::SetParent(QmuParserBase *a_pParent) - { - m_pParser = a_pParent; - m_pFunDef = &a_pParent->m_FunDef; - m_pOprtDef = &a_pParent->m_OprtDef; - m_pInfixOprtDef = &a_pParent->m_InfixOprtDef; - m_pPostOprtDef = &a_pParent->m_PostOprtDef; - m_pVarDef = &a_pParent->m_VarDef; - m_pStrVarDef = &a_pParent->m_StrVarDef; - m_pConstDef = &a_pParent->m_ConstDef; - } - -//--------------------------------------------------------------------------- -/** \brief Extract all characters that belong to a certain charset. - -\param a_szCharSet [in] Const char array of the characters allowed in the token. -\param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. -\param a_iPos [in] Position in the string from where to start reading. -\return The Position of the first character not listed in a_szCharSet. -\throw nothrow -*/ -int QmuParserTokenReader::ExtractToken(const QString &a_szCharSet, QString &a_sTok, int a_iPos) const -{ -#if defined(_UNICODE) - const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); - const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); -#else - const std::string m_strFormulaStd = m_strFormula.toStdString(); - const std::string a_szCharSetStd = a_szCharSet.toStdString(); -#endif - - int iEnd = (int)m_strFormulaStd.find_first_not_of(a_szCharSetStd, a_iPos); - - if (iEnd==(int)string_type::npos) - { - iEnd = (int)m_strFormulaStd.length(); - } - - // Assign token string if there was something found - if (a_iPos!=iEnd) - { - #if defined(_UNICODE) - a_sTok = QString().fromStdWString(std::wstring( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd)); - #else - a_sTok = QString().fromStdString(std::string( m_strFormulaStd.begin()+a_iPos, m_strFormulaStd.begin()+iEnd)); - #endif - } - - return iEnd; -} - -//--------------------------------------------------------------------------- -/** \brief Check Expression for the presence of a binary operator token. - -Userdefined binary operator "++" gives inconsistent parsing result for -the equations "a++b" and "a ++ b" if alphabetic characters are allowed -in operator tokens. To avoid this this function checks specifically -for operator tokens. -*/ -int QmuParserTokenReader::ExtractOperatorToken(QString &a_sTok, int a_iPos) const -{ -#if defined(_UNICODE) - const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); - const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString(); -#else - const std::string m_strFormulaStd = m_strFormula.toStdString(); - const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); -#endif - int iEnd = (int)m_strFormulaStd.find_first_not_of(oprtCharsStd, a_iPos); - if (iEnd==(int)string_type::npos) - { - iEnd = (int)m_strFormulaStd.length(); - } - - // Assign token string if there was something found - if (a_iPos!=iEnd) - { - #if defined(_UNICODE) - a_sTok = QString().fromStdWString(string_type(m_strFormulaStd.begin() + a_iPos, - m_strFormulaStd.begin() + iEnd)); - #else - a_sTok = QString().fromStdString(string_type(m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd)); - #endif - return iEnd; - } - else - { - // There is still the chance of having to deal with an operator consisting exclusively - // of alphabetic characters. - return ExtractToken(QMUP_CHARS, a_sTok, a_iPos); - } -} - - //--------------------------------------------------------------------------- - /** \brief Check if a built in operator or other token can be found - \param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. - \return true if an operator token has been found. - */ - bool QmuParserTokenReader::IsBuiltIn(token_type &a_Tok) - { - const QStringList pOprtDef = m_pParser->GetOprtDef(); - - // Compare token with function and operator strings - // check string for operator/function - for (int i=0; i < pOprtDef.size(); ++i) - { - int len = pOprtDef.at(i).length(); - if ( pOprtDef.at(i) == m_strFormula.mid(m_iPos, m_iPos + len) ) - { - switch(i) - { - //case cmAND: - //case cmOR: - //case cmXOR: - case cmLAND: - case cmLOR: - case cmLT: - case cmGT: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: - case cmPOW: - case cmASSIGN: - //if (len!=sTok.length()) - // continue; - - // The assignement operator need special treatment - if (i==cmASSIGN && m_iSynFlags & noASSIGN) - Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i)); - - if (!m_pParser->HasBuiltInOprt()) continue; - if (m_iSynFlags & noOPT) - { - // Maybe its an infix operator not an operator - // Both operator types can share characters in - // their identifiers - if ( IsInfixOpTok(a_Tok) ) - return true; - - Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at(i)); - } - - m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; - m_iSynFlags |= ( (i != cmEND) && ( i != cmBC) ) ? noEND : 0; - break; - - case cmBO: - if (m_iSynFlags & noBO) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); - - if (m_lastTok.GetCode()==cmFUNC) - m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; - else - m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN| noIF | noELSE; - - ++m_iBrackets; - break; - - case cmBC: - if (m_iSynFlags & noBC) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); - - m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; - - if (--m_iBrackets<0) - Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at(i)); - break; - - case cmELSE: - if (m_iSynFlags & noELSE) - Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i)); - - m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; - break; - - case cmIF: - if (m_iSynFlags & noIF) - Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at(i)); - - m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; - break; - - default: // The operator is listed in c_DefaultOprt, but not here. This is a bad thing... - Error(ecINTERNAL_ERROR); - } // switch operator id - - m_iPos += len; - a_Tok.Set( (ECmdCode)i, pOprtDef.at(i) ); - return true; - } // if operator string found - } // end of for all operator strings - - return false; - } - - //--------------------------------------------------------------------------- - bool QmuParserTokenReader::IsArgSep(token_type &a_Tok) - { - if (m_strFormula.at(m_iPos)==m_cArgSep) - { - // copy the separator into null terminated string - QString szSep; - szSep[0] = m_cArgSep; - szSep[1] = 0; - - if (m_iSynFlags & noARG_SEP) - { - Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep); - } - - m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; - m_iPos++; - a_Tok.Set(cmARG_SEP, szSep); - return true; - } - - return false; - } - - //--------------------------------------------------------------------------- - /** \brief Check for End of Formula. - - \return true if an end of formula is found false otherwise. - \param a_Tok [out] If an eof is found the corresponding token will be stored there. - \throw nothrow - \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok - */ - bool QmuParserTokenReader::IsEOF(token_type &a_Tok) - { -#if defined(_UNICODE) - const char_type* szFormula = m_strFormula.toStdWString().c_str(); -#else - const char_type* szFormula = m_strFormula.toStdString().c_str(); -#endif - - // check for EOF - if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/) - { - if ( m_iSynFlags & noEND ) - Error(ecUNEXPECTED_EOF, m_iPos); - - if (m_iBrackets>0) - Error(ecMISSING_PARENS, m_iPos, ")"); - - m_iSynFlags = 0; - a_Tok.Set(cmEND); - return true; - } - - return false; - } - - //--------------------------------------------------------------------------- - /** \brief Check if a string position contains a unary infix operator. - \return true if a function token has been found false otherwise. - */ - bool QmuParserTokenReader::IsInfixOpTok(token_type &a_Tok) - { - QString sTok; - int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos); - if (iEnd==m_iPos) - return false; - - // iteraterate over all postfix operator strings - funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); - for ( ; it!=m_pInfixOprtDef->rend(); ++it) - { - if (sTok.indexOf(it->first)!=0) - continue; - - a_Tok.Set(it->second, it->first); - m_iPos += (int)it->first.length(); - - if (m_iSynFlags & noINFIXOP) - Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); - - m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; - return true; - } - - return false; - -/* - a_Tok.Set(item->second, sTok); - m_iPos = (int)iEnd; - - if (m_iSynFlags & noINFIXOP) - Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); - - m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; - return true; -*/ - } - - //--------------------------------------------------------------------------- - /** \brief Check whether the token at a given position is a function token. - \param a_Tok [out] If a value token is found it will be placed here. - \throw ParserException if Syntaxflags do not allow a function at a_iPos - \return true if a function token has been found false otherwise. - \pre [assert] m_pParser!=0 - */ - bool QmuParserTokenReader::IsFunTok(token_type &a_Tok) - { - QString strTok; - int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); - if (iEnd==m_iPos) - return false; - - funmap_type::const_iterator item = m_pFunDef->find(strTok); - if (item==m_pFunDef->end()) - return false; - - // Check if the next sign is an opening bracket - if (m_strFormula.at(iEnd)!='(') - return false; - - a_Tok.Set(item->second, strTok); - - m_iPos = iEnd; - if (m_iSynFlags & noFUN) - Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString()); - - m_iSynFlags = noANY ^ noBO; - return true; - } - - //--------------------------------------------------------------------------- - /** \brief Check if a string position contains a binary operator. - \param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. - \return true if an operator token has been found. - */ - bool QmuParserTokenReader::IsOprt(token_type &a_Tok) - { - QString strTok; - - int iEnd = ExtractOperatorToken(strTok, m_iPos); - if (iEnd==m_iPos) - return false; - - // Check if the operator is a built in operator, if so ignore it here - const QStringList pOprtDef = m_pParser->GetOprtDef(); - QStringList::const_iterator constIterator; - for (constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd(); - ++constIterator) - { - if ((*constIterator)==strTok) - return false; - } - - // Note: - // All tokens in oprt_bin_maptype are have been sorted by their length - // Long operators must come first! Otherwise short names (like: "add") that - // are part of long token names (like: "add123") will be found instead - // of the long ones. - // Length sorting is done with ascending length so we use a reverse iterator here. - funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); - for ( ; it!=m_pOprtDef->rend(); ++it) - { - const QString &sID = it->first; - if ( sID == m_strFormula.mid(m_iPos, m_iPos + sID.length()) ) - { - a_Tok.Set(it->second, strTok); - - // operator was found - if (m_iSynFlags & noOPT) - { - // An operator was found but is not expected to occur at - // this position of the formula, maybe it is an infix - // operator, not a binary operator. Both operator types - // can share characters in their identifiers. - if ( IsInfixOpTok(a_Tok) ) - return true; - else - { - // nope, no infix operator - return false; - //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); - } - - } - - m_iPos += (int)sID.length(); - m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; - return true; - } - } - - return false; - } - - //--------------------------------------------------------------------------- - /** \brief Check if a string position contains a unary post value operator. */ - bool QmuParserTokenReader::IsPostOpTok(token_type &a_Tok) - { - // Do not check for postfix operators if they are not allowed at - // the current expression index. - // - // This will fix the bug reported here: - // - // http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979 - // - if (m_iSynFlags & noPOSTOP) - return false; - // - - // Tricky problem with equations like "3m+5": - // m is a postfix operator, + is a valid sign for postfix operators and - // for binary operators parser detects "m+" as operator string and - // finds no matching postfix operator. - // - // This is a special case so this routine slightly differs from the other - // token readers. - - // Test if there could be a postfix operator - QString sTok; - int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos); - if (iEnd==m_iPos) - return false; - - // iteraterate over all postfix operator strings - funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); - for ( ; it!=m_pPostOprtDef->rend(); ++it) - { - if (sTok.indexOf(it->first)!=0) - continue; - - a_Tok.Set(it->second, sTok); - m_iPos += it->first.length(); - - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; - return true; - } - - return false; - } - - //--------------------------------------------------------------------------- - /** \brief Check whether the token at a given position is a value token. - - Value tokens are either values or constants. - - \param a_Tok [out] If a value token is found it will be placed here. - \return true if a value token has been found. - */ - bool QmuParserTokenReader::IsValTok(token_type &a_Tok) - { - assert(m_pConstDef); - assert(m_pParser); - - QString strTok; - qreal fVal(0); - int iEnd(0); - - // 2.) Check for user defined constant - // Read everything that could be a constant name - iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); - if (iEnd!=m_iPos) - { - valmap_type::const_iterator item = m_pConstDef->find(strTok); - if (item!=m_pConstDef->end()) - { - m_iPos = iEnd; - a_Tok.SetVal(item->second, strTok); - - if (m_iSynFlags & noVAL) - Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok); - - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; - return true; - } - } - - // 3.call the value recognition functions provided by the user - // Call user defined value recognition functions - std::list::const_iterator item = m_vIdentFun.begin(); - for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item) - { - int iStart = m_iPos; - if ( (*item)(m_strFormula.mid(m_iPos), &m_iPos, &fVal)==1 ) - { - strTok = m_strFormula.mid(iStart, m_iPos); - if (m_iSynFlags & noVAL) - Error(ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok); - - a_Tok.SetVal(fVal, strTok); - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; - return true; - } - } - - return false; - } - - //--------------------------------------------------------------------------- - /** \brief Check wheter a token at a given position is a variable token. - \param a_Tok [out] If a variable token has been found it will be placed here. - \return true if a variable token has been found. - */ - bool QmuParserTokenReader::IsVarTok(token_type &a_Tok) - { - if (!m_pVarDef->size()) - return false; - - QString strTok; - int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); - if (iEnd==m_iPos) - return false; - - varmap_type::const_iterator item = m_pVarDef->find(strTok); - if (item==m_pVarDef->end()) - return false; - - if (m_iSynFlags & noVAR) - Error(ecUNEXPECTED_VAR, m_iPos, strTok); - - m_pParser->OnDetectVar(&m_strFormula, m_iPos, iEnd); - - m_iPos = iEnd; - a_Tok.SetVar(item->second, strTok); - m_UsedVar[item->first] = item->second; // Add variable to used-var-list - - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR; - -// Zur Info hier die SynFlags von IsVal(): -// m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; - return true; - } - - //--------------------------------------------------------------------------- - bool QmuParserTokenReader::IsStrVarTok(token_type &a_Tok) - { - if (!m_pStrVarDef || !m_pStrVarDef->size()) - return false; - - QString strTok; - int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); - if (iEnd==m_iPos) - return false; - - strmap_type::const_iterator item = m_pStrVarDef->find(strTok); - if (item==m_pStrVarDef->end()) - return false; - - if (m_iSynFlags & noSTR) - Error(ecUNEXPECTED_VAR, m_iPos, strTok); - - m_iPos = iEnd; - if (!m_pParser->m_vStringVarBuf.size()) - Error(ecINTERNAL_ERROR); - - a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() ); - - m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP); - return true; - } - - - //--------------------------------------------------------------------------- - /** \brief Check wheter a token at a given position is an undefined variable. - - \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here. - \return true if a variable token has been found. - \throw nothrow - */ - bool QmuParserTokenReader::IsUndefVarTok(token_type &a_Tok) - { - QString strTok; - int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) ); - if ( iEnd==m_iPos ) - return false; - - if (m_iSynFlags & noVAR) - { - // 20061021 added token string strTok instead of a_Tok.GetAsString() as the - // token identifier. - // related bug report: - // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 - Error(ecUNEXPECTED_VAR, m_iPos - (int)a_Tok.GetAsString().length(), strTok); - } - - // If a factory is available implicitely create new variables - if (m_pFactory) - { - qreal *fVar = m_pFactory(strTok, m_pFactoryData); - a_Tok.SetVar(fVar, strTok ); - - // Do not use m_pParser->DefineVar( strTok, fVar ); - // in order to define the new variable, it will clear the - // m_UsedVar array which will kill previousely defined variables - // from the list - // This is safe because the new variable can never override an existing one - // because they are checked first! - (*m_pVarDef)[strTok] = fVar; - m_UsedVar[strTok] = fVar; // Add variable to used-var-list - } - else - { - a_Tok.SetVar((qreal*)&m_fZero, strTok); - m_UsedVar[strTok] = 0; // Add variable to used-var-list - } - - m_iPos = iEnd; - - // Call the variable factory in order to let it define a new parser variable - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR; - return true; - } - - - //--------------------------------------------------------------------------- - /** \brief Check wheter a token at a given position is a string. - \param a_Tok [out] If a variable token has been found it will be placed here. - \return true if a string token has been found. - \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok - \throw nothrow - */ - bool QmuParserTokenReader::IsString(token_type &a_Tok) - { - if (m_strFormula[m_iPos]!='"') - return false; - - QString strBuf(m_strFormula[m_iPos+1]); - int iEnd(0), iSkip(0); - - // parser over escaped '\"' end replace them with '"' - for(iEnd=strBuf.indexOf( "\"" ); iEnd!=0 && iEnd!=-1; iEnd=strBuf.indexOf( "\"", iEnd)) - { - if (strBuf[iEnd-1]!='\\') break; - strBuf.replace(iEnd-1, 2, "\"" ); - iSkip++; - } - - if (iEnd==-1) - Error(ecUNTERMINATED_STRING, m_iPos, "\"" ); - - QString strTok = strBuf.mid(0, iEnd); - - if (m_iSynFlags & noSTR) - Error(ecUNEXPECTED_STR, m_iPos, strTok); - - m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer - a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size()); - - m_iPos += (int)strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen - m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); - - return true; - } - - //--------------------------------------------------------------------------- - /** \brief Create an error containing the parse error position. - - This function will create an Parser Exception object containing the error text and its position. - - \param a_iErrc [in] The error code of type #EErrorCodes. - \param a_iPos [in] The position where the error was detected. - \param a_strTok [in] The token string representation associated with the error. - \throw ParserException always throws thats the only purpose of this function. - */ - void QmuParserTokenReader::Error( EErrorCodes a_iErrc, - int a_iPos, - const QString &a_sTok) const - { - m_pParser->Error(a_iErrc, a_iPos, a_sTok); - } - - //--------------------------------------------------------------------------- - void QmuParserTokenReader::SetArgSep(char_type cArgSep) - { - m_cArgSep = cArgSep; - } - - //--------------------------------------------------------------------------- - QChar QmuParserTokenReader::GetArgSep() const - { - return m_cArgSep; - } -} // namespace qmu - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhinsky + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparsertokenreader.h" +#include "qmuparserbase.h" + +#include + +/** + * @file + * @brief This file contains the parser token reader implementation. + */ + +namespace qmu +{ + +// Forward declaration +class QmuParserBase; + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy constructor. + * + * @sa Assign + * @throw nothrow + */ +QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader ) +{ + Assign ( a_Reader ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Assignement operator. + * + * Self assignement will be suppressed otherwise #Assign is called. + * + * @param a_Reader Object to copy to this token reader. + * @throw nothrow + */ +QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenReader &a_Reader ) +{ + if ( &a_Reader != this ) + { + Assign ( a_Reader ); + } + + return *this; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Assign state of a token reader to this token reader. + * + * @param a_Reader Object from which the state should be copied. + * @throw nothrow + */ +void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) +{ + m_pParser = a_Reader.m_pParser; + m_strFormula = a_Reader.m_strFormula; + m_iPos = a_Reader.m_iPos; + m_iSynFlags = a_Reader.m_iSynFlags; + + m_UsedVar = a_Reader.m_UsedVar; + m_pFunDef = a_Reader.m_pFunDef; + m_pConstDef = a_Reader.m_pConstDef; + m_pVarDef = a_Reader.m_pVarDef; + m_pStrVarDef = a_Reader.m_pStrVarDef; + m_pPostOprtDef = a_Reader.m_pPostOprtDef; + m_pInfixOprtDef = a_Reader.m_pInfixOprtDef; + m_pOprtDef = a_Reader.m_pOprtDef; + m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar; + m_vIdentFun = a_Reader.m_vIdentFun; + m_pFactory = a_Reader.m_pFactory; + m_pFactoryData = a_Reader.m_pFactoryData; + m_iBrackets = a_Reader.m_iBrackets; + m_cArgSep = a_Reader.m_cArgSep; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor. + * + * Create a Token reader and bind it to a parser object. + * + * @pre [assert] a_pParser may not be NULL + * @post #m_pParser==a_pParser + * @param a_pParent Parent parser object of the token reader. + */ +QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) + : m_pParser ( a_pParent ), m_strFormula(), m_iPos ( 0 ), m_iSynFlags ( 0 ), m_bIgnoreUndefVar ( false ), + m_pFunDef ( NULL ), m_pPostOprtDef ( NULL ), m_pInfixOprtDef ( NULL ), m_pOprtDef ( NULL ), m_pConstDef ( NULL ), + m_pStrVarDef ( NULL ), m_pVarDef ( NULL ), m_pFactory ( NULL ), m_pFactoryData ( NULL ), m_vIdentFun(), + m_UsedVar(), m_fZero ( 0 ), m_iBrackets ( 0 ), m_lastTok(), m_cArgSep ( ',' ) +{ + assert ( m_pParser ); + SetParent ( m_pParser ); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Create instance of a QParserTokenReader identical with this and return its pointer. + * + * This is a factory method the calling function must take care of the object destruction. + * + * @return A new QParserTokenReader object. + * @throw nothrow + */ +QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const +{ + std::auto_ptr ptr ( new QmuParserTokenReader ( *this ) ); + ptr->SetParent ( a_pParent ); + return ptr.release(); +} + +//---------------------------------------------------------------------------------------------------------------------- +QmuParserTokenReader::token_type& QmuParserTokenReader::SaveBeforeReturn ( const token_type &tok ) +{ + m_lastTok = tok; + return m_lastTok; +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserTokenReader::AddValIdent ( identfun_type a_pCallback ) +{ + // Use push_front is used to give user defined callbacks a higher priority than + // the built in ones. Otherwise reading hex numbers would not work + // since the "0" in "0xff" would always be read first making parsing of + // the rest impossible. + // reference: + // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956 + m_vIdentFun.push_front ( a_pCallback ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserTokenReader::SetVarCreator ( facfun_type a_pFactory, void *pUserData ) +{ + m_pFactory = a_pFactory; + m_pFactoryData = pUserData; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the current position of the token reader in the formula string. + * + * @return #m_iPos + * @throw nothrow + */ +int QmuParserTokenReader::GetPos() const +{ + return m_iPos; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return a reference to the formula. + * + * @return #m_strFormula + * @throw nothrow + */ +const QString& QmuParserTokenReader::GetExpr() const +{ + return m_strFormula; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return a map containing the used variables only. + */ +varmap_type& QmuParserTokenReader::GetUsedVar() +{ + return m_UsedVar; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize the token Reader. + * + * Sets the formula position index to zero and set Syntax flags to default for initial formula parsing. + * @pre [assert] triggered if a_szFormula==0 + */ +void QmuParserTokenReader::SetFormula ( const QString &a_strFormula ) +{ + m_strFormula = a_strFormula; + ReInit(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set Flag that contronls behaviour in case of undefined variables beeing found. + * + * If true, the parser does not throw an exception if an undefined variable is found. Otherwise it does. This variable + * is used internally only! It supresses a "undefined variable" exception in GetUsedVar(). + * Those function should return a complete list of variables including + * those the are not defined by the time of it's call. + */ +void QmuParserTokenReader::IgnoreUndefVar ( bool bIgnore ) +{ + m_bIgnoreUndefVar = bIgnore; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Reset the token reader to the start of the formula. + * + * The syntax flags will be reset to a value appropriate for the start of a formula. + * @post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR + * @throw nothrow + * @sa ESynCodes + */ +void QmuParserTokenReader::ReInit() +{ + m_iPos = 0; + m_iSynFlags = sfSTART_OF_LINE; + m_iBrackets = 0; + m_UsedVar.clear(); + m_lastTok = token_type(); +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Read the next token from the string. + */ +QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken() +{ + assert ( m_pParser ); + +#if defined(_UNICODE) + const char_type *szFormula = m_strFormula.toStdWString().c_str(); +#else + const char_type *szFormula = m_strFormula.toStdString().c_str(); +#endif + token_type tok; + + // Ignore all non printable characters when reading the expression + while ( szFormula[m_iPos] > 0 && szFormula[m_iPos] <= 0x20 ) + { + ++m_iPos; + } + + if ( IsEOF ( tok ) ) return SaveBeforeReturn ( tok ); // Check for end of formula + if ( IsOprt ( tok ) ) return SaveBeforeReturn ( tok ); // Check for user defined binary operator + if ( IsFunTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for function token + if ( IsBuiltIn ( tok ) ) return SaveBeforeReturn ( tok ); // Check built in operators / tokens + if ( IsArgSep ( tok ) ) return SaveBeforeReturn ( tok ); // Check for function argument separators + if ( IsValTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for values / constant tokens + if ( IsVarTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for variable tokens + if ( IsStrVarTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for string variables + if ( IsString ( tok ) ) return SaveBeforeReturn ( tok ); // Check for String tokens + if ( IsInfixOpTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for unary operators + if ( IsPostOpTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for unary operators + + // Check String for undefined variable token. Done only if a + // flag is set indicating to ignore undefined variables. + // This is a way to conditionally avoid an error if + // undefined variables occur. + // (The GetUsedVar function must suppress the error for + // undefined variables in order to collect all variable + // names including the undefined ones.) + if ( ( m_bIgnoreUndefVar || m_pFactory ) && IsUndefVarTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); + } + + // Check for unknown token + // + // !!! From this point on there is no exit without an exception possible... + // + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd != m_iPos ) + { + Error ( ecUNASSIGNABLE_TOKEN, m_iPos, strTok ); + } + + Error ( ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid ( m_iPos ) ); + return token_type(); // never reached +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserTokenReader::SetParent ( QmuParserBase *a_pParent ) +{ + m_pParser = a_pParent; + m_pFunDef = &a_pParent->m_FunDef; + m_pOprtDef = &a_pParent->m_OprtDef; + m_pInfixOprtDef = &a_pParent->m_InfixOprtDef; + m_pPostOprtDef = &a_pParent->m_PostOprtDef; + m_pVarDef = &a_pParent->m_VarDef; + m_pStrVarDef = &a_pParent->m_StrVarDef; + m_pConstDef = &a_pParent->m_ConstDef; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Extract all characters that belong to a certain charset. + * + * @param a_szCharSet [in] Const char array of the characters allowed in the token. + * @param a_strTok [out] The string that consists entirely of characters listed in a_szCharSet. + * @param a_iPos [in] Position in the string from where to start reading. + * @return The Position of the first character not listed in a_szCharSet. + * @throw nothrow + */ +int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_sTok, int a_iPos ) const +{ +#if defined(_UNICODE) + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); +#else + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + + int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos ); + + if ( iEnd == ( int ) string_type::npos ) + { + iEnd = ( int ) m_strFormulaStd.length(); + } + + // Assign token string if there was something found + if ( a_iPos != iEnd ) + { +#if defined(_UNICODE) + a_sTok = QString().fromStdWString ( std::wstring ( m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd ) ); +#else + a_sTok = QString().fromStdString ( std::string ( m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd ) ); +#endif + } + + return iEnd; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check Expression for the presence of a binary operator token. + * + * Userdefined binary operator "++" gives inconsistent parsing result for the equations "a++b" and "a ++ b" if + * alphabetic characters are allowed in operator tokens. To avoid this this function checks specifically + * for operator tokens. + */ +int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) const +{ +#if defined(_UNICODE) + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString(); +#else + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); +#endif + int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ); + if ( iEnd == ( int ) string_type::npos ) + { + iEnd = ( int ) m_strFormulaStd.length(); + } + + // Assign token string if there was something found + if ( a_iPos != iEnd ) + { +#if defined(_UNICODE) + a_sTok = QString().fromStdWString ( string_type ( m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd ) ); +#else + a_sTok = QString().fromStdString ( string_type ( m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd ) ); +#endif + return iEnd; + } + else + { + // There is still the chance of having to deal with an operator consisting exclusively + // of alphabetic characters. + return ExtractToken ( QMUP_CHARS, a_sTok, a_iPos ); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a built in operator or other token can be found + * @param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. + * @return true if an operator token has been found. + */ +bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok ) +{ + const QStringList pOprtDef = m_pParser->GetOprtDef(); + + // Compare token with function and operator strings + // check string for operator/function + for ( int i = 0; i < pOprtDef.size(); ++i ) + { + int len = pOprtDef.at ( i ).length(); + if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, m_iPos + len ) ) + { + switch ( i ) + { + //case cmAND: + //case cmOR: + //case cmXOR: + case cmLAND: + case cmLOR: + case cmLT: + case cmGT: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmASSIGN: + //if (len!=sTok.length()) + // continue; + + // The assignement operator need special treatment + if ( i == cmASSIGN && m_iSynFlags & noASSIGN ) + Error ( ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at ( i ) ); + + if ( !m_pParser->HasBuiltInOprt() ) continue; + if ( m_iSynFlags & noOPT ) + { + // Maybe its an infix operator not an operator + // Both operator types can share characters in + // their identifiers + if ( IsInfixOpTok ( a_Tok ) ) + return true; + + Error ( ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at ( i ) ); + } + + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + m_iSynFlags |= ( ( i != cmEND ) && ( i != cmBC ) ) ? noEND : 0; + break; + + case cmBO: + if ( m_iSynFlags & noBO ) + Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + + if ( m_lastTok.GetCode() == cmFUNC ) + m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + else + m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + + ++m_iBrackets; + break; + + case cmBC: + if ( m_iSynFlags & noBC ) + Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + + m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; + + if ( --m_iBrackets < 0 ) + Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + break; + + case cmELSE: + if ( m_iSynFlags & noELSE ) + Error ( ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at ( i ) ); + + m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; + break; + + case cmIF: + if ( m_iSynFlags & noIF ) + Error ( ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at ( i ) ); + + m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; + break; + + default: // The operator is listed in c_DefaultOprt, but not here. This is a bad thing... + Error ( ecINTERNAL_ERROR ); + } // switch operator id + + m_iPos += len; + a_Tok.Set ( ( ECmdCode ) i, pOprtDef.at ( i ) ); + return true; + } // if operator string found + } // end of for all operator strings + + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok ) +{ + if ( m_strFormula.at ( m_iPos ) == m_cArgSep ) + { + // copy the separator into null terminated string + QString szSep; + szSep[0] = m_cArgSep; + szSep[1] = 0; + + if ( m_iSynFlags & noARG_SEP ) + { + Error ( ecUNEXPECTED_ARG_SEP, m_iPos, szSep ); + } + + m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; + m_iPos++; + a_Tok.Set ( cmARG_SEP, szSep ); + return true; + } + + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check for End of Formula. + * + * @return true if an end of formula is found false otherwise. + * @param a_Tok [out] If an eof is found the corresponding token will be stored there. + * @throw nothrow + * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok + */ +bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) +{ +#if defined(_UNICODE) + const char_type* szFormula = m_strFormula.toStdWString().c_str(); +#else + const char_type* szFormula = m_strFormula.toStdString().c_str(); +#endif + + // check for EOF + if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/ ) + { + if ( m_iSynFlags & noEND ) + Error ( ecUNEXPECTED_EOF, m_iPos ); + + if ( m_iBrackets > 0 ) + Error ( ecMISSING_PARENS, m_iPos, ")" ); + + m_iSynFlags = 0; + a_Tok.Set ( cmEND ); + return true; + } + + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a string position contains a unary infix operator. + * @return true if a function token has been found false otherwise. + */ +bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok ) +{ + QString sTok; + int iEnd = ExtractToken ( m_pParser->ValidInfixOprtChars(), sTok, m_iPos ); + if ( iEnd == m_iPos ) + return false; + + // iteraterate over all postfix operator strings + funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); + for ( ; it != m_pInfixOprtDef->rend(); ++it ) + { + if ( sTok.indexOf ( it->first ) != 0 ) + continue; + + a_Tok.Set ( it->second, it->first ); + m_iPos += ( int ) it->first.length(); + + if ( m_iSynFlags & noINFIXOP ) + Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() ); + + m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; + return true; + } + + return false; + + /* + a_Tok.Set(item->second, sTok); + m_iPos = (int)iEnd; + + if (m_iSynFlags & noINFIXOP) + Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + + m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; + return true; + */ +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check whether the token at a given position is a function token. + * @param a_Tok [out] If a value token is found it will be placed here. + * @throw ParserException if Syntaxflags do not allow a function at a_iPos + * @return true if a function token has been found false otherwise. + * @pre [assert] m_pParser!=0 + */ +bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok ) +{ + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd == m_iPos ) + return false; + + funmap_type::const_iterator item = m_pFunDef->find ( strTok ); + if ( item == m_pFunDef->end() ) + return false; + + // Check if the next sign is an opening bracket + if ( m_strFormula.at ( iEnd ) != '(' ) + return false; + + a_Tok.Set ( item->second, strTok ); + + m_iPos = iEnd; + if ( m_iSynFlags & noFUN ) + Error ( ecUNEXPECTED_FUN, m_iPos - ( int ) a_Tok.GetAsString().length(), a_Tok.GetAsString() ); + + m_iSynFlags = noANY ^ noBO; + return true; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a string position contains a binary operator. + * @param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. + * @return true if an operator token has been found. + */ +bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) +{ + QString strTok; + + int iEnd = ExtractOperatorToken ( strTok, m_iPos ); + if ( iEnd == m_iPos ) + return false; + + // Check if the operator is a built in operator, if so ignore it here + const QStringList pOprtDef = m_pParser->GetOprtDef(); + QStringList::const_iterator constIterator; + for ( constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd(); + ++constIterator ) + { + if ( ( *constIterator ) == strTok ) + return false; + } + + // Note: + // All tokens in oprt_bin_maptype are have been sorted by their length + // Long operators must come first! Otherwise short names (like: "add") that + // are part of long token names (like: "add123") will be found instead + // of the long ones. + // Length sorting is done with ascending length so we use a reverse iterator here. + funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); + for ( ; it != m_pOprtDef->rend(); ++it ) + { + const QString &sID = it->first; + if ( sID == m_strFormula.mid ( m_iPos, m_iPos + sID.length() ) ) + { + a_Tok.Set ( it->second, strTok ); + + // operator was found + if ( m_iSynFlags & noOPT ) + { + // An operator was found but is not expected to occur at + // this position of the formula, maybe it is an infix + // operator, not a binary operator. Both operator types + // can share characters in their identifiers. + if ( IsInfixOpTok ( a_Tok ) ) + return true; + else + { + // nope, no infix operator + return false; + //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + } + + } + + m_iPos += ( int ) sID.length(); + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; + return true; + } + } + + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a string position contains a unary post value operator. + */ +bool QmuParserTokenReader::IsPostOpTok ( token_type &a_Tok ) +{ + // Do not check for postfix operators if they are not allowed at + // the current expression index. + // + // This will fix the bug reported here: + // + // http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979 + // + if ( m_iSynFlags & noPOSTOP ) + return false; + // + + // Tricky problem with equations like "3m+5": + // m is a postfix operator, + is a valid sign for postfix operators and + // for binary operators parser detects "m+" as operator string and + // finds no matching postfix operator. + // + // This is a special case so this routine slightly differs from the other + // token readers. + + // Test if there could be a postfix operator + QString sTok; + int iEnd = ExtractToken ( m_pParser->ValidOprtChars(), sTok, m_iPos ); + if ( iEnd == m_iPos ) + return false; + + // iteraterate over all postfix operator strings + funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); + for ( ; it != m_pPostOprtDef->rend(); ++it ) + { + if ( sTok.indexOf ( it->first ) != 0 ) + continue; + + a_Tok.Set ( it->second, sTok ); + m_iPos += it->first.length(); + + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; + return true; + } + + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check whether the token at a given position is a value token. + * + * Value tokens are either values or constants. + * + * @param a_Tok [out] If a value token is found it will be placed here. + * @return true if a value token has been found. + */ +bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) +{ + assert ( m_pConstDef ); + assert ( m_pParser ); + + QString strTok; + qreal fVal ( 0 ); + int iEnd ( 0 ); + + // 2.) Check for user defined constant + // Read everything that could be a constant name + iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd != m_iPos ) + { + valmap_type::const_iterator item = m_pConstDef->find ( strTok ); + if ( item != m_pConstDef->end() ) + { + m_iPos = iEnd; + a_Tok.SetVal ( item->second, strTok ); + + if ( m_iSynFlags & noVAL ) + Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); + + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + } + + // 3.call the value recognition functions provided by the user + // Call user defined value recognition functions + std::list::const_iterator item = m_vIdentFun.begin(); + for ( item = m_vIdentFun.begin(); item != m_vIdentFun.end(); ++item ) + { + int iStart = m_iPos; + if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 ) + { + strTok = m_strFormula.mid ( iStart, m_iPos ); + if ( m_iSynFlags & noVAL ) + Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); + + a_Tok.SetVal ( fVal, strTok ); + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + } + + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check wheter a token at a given position is a variable token. + * @param a_Tok [out] If a variable token has been found it will be placed here. + * @return true if a variable token has been found. + */ +bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok ) +{ + if ( !m_pVarDef->size() ) + return false; + + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd == m_iPos ) + return false; + + varmap_type::const_iterator item = m_pVarDef->find ( strTok ); + if ( item == m_pVarDef->end() ) + return false; + + if ( m_iSynFlags & noVAR ) + Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); + + m_pParser->OnDetectVar ( &m_strFormula, m_iPos, iEnd ); + + m_iPos = iEnd; + a_Tok.SetVar ( item->second, strTok ); + m_UsedVar[item->first] = item->second; // Add variable to used-var-list + + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR; + +// Zur Info hier die SynFlags von IsVal(): +// m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; +} + +//---------------------------------------------------------------------------------------------------------------------- +bool QmuParserTokenReader::IsStrVarTok ( token_type &a_Tok ) +{ + if ( !m_pStrVarDef || !m_pStrVarDef->size() ) + return false; + + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd == m_iPos ) + return false; + + strmap_type::const_iterator item = m_pStrVarDef->find ( strTok ); + if ( item == m_pStrVarDef->end() ) + return false; + + if ( m_iSynFlags & noSTR ) + Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); + + m_iPos = iEnd; + if ( !m_pParser->m_vStringVarBuf.size() ) + Error ( ecINTERNAL_ERROR ); + + a_Tok.SetString ( m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() ); + + m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP ); + return true; +} + + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check wheter a token at a given position is an undefined variable. + * + * @param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here. + * @return true if a variable token has been found. + * @throw nothrow + */ +bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) +{ + QString strTok; + int iEnd ( ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ) ); + if ( iEnd == m_iPos ) + { + return false; + } + + if ( m_iSynFlags & noVAR ) + { + // 20061021 added token string strTok instead of a_Tok.GetAsString() as the + // token identifier. + // related bug report: + // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 + Error ( ecUNEXPECTED_VAR, m_iPos - ( int ) a_Tok.GetAsString().length(), strTok ); + } + + // If a factory is available implicitely create new variables + if ( m_pFactory ) + { + qreal *fVar = m_pFactory ( strTok, m_pFactoryData ); + a_Tok.SetVar ( fVar, strTok ); + + // Do not use m_pParser->DefineVar( strTok, fVar ); + // in order to define the new variable, it will clear the + // m_UsedVar array which will kill previousely defined variables + // from the list + // This is safe because the new variable can never override an existing one + // because they are checked first! + ( *m_pVarDef ) [strTok] = fVar; + m_UsedVar[strTok] = fVar; // Add variable to used-var-list + } + else + { + a_Tok.SetVar ( ( qreal* ) &m_fZero, strTok ); + m_UsedVar[strTok] = 0; // Add variable to used-var-list + } + + m_iPos = iEnd; + + // Call the variable factory in order to let it define a new parser variable + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR; + return true; +} + + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check wheter a token at a given position is a string. + * @param a_Tok [out] If a variable token has been found it will be placed here. + * @return true if a string token has been found. + * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok + * @throw nothrow + */ +bool QmuParserTokenReader::IsString ( token_type &a_Tok ) +{ + if ( m_strFormula[m_iPos] != '"' ) + return false; + + QString strBuf ( m_strFormula[m_iPos + 1] ); + int iEnd ( 0 ), iSkip ( 0 ); + + // parser over escaped '\"' end replace them with '"' + for ( iEnd = strBuf.indexOf ( "\"" ); iEnd != 0 && iEnd != -1; iEnd = strBuf.indexOf ( "\"", iEnd ) ) + { + if ( strBuf[iEnd - 1] != '\\' ) break; + strBuf.replace ( iEnd - 1, 2, "\"" ); + iSkip++; + } + + if ( iEnd == -1 ) + Error ( ecUNTERMINATED_STRING, m_iPos, "\"" ); + + QString strTok = strBuf.mid ( 0, iEnd ); + + if ( m_iSynFlags & noSTR ) + Error ( ecUNEXPECTED_STR, m_iPos, strTok ); + + m_pParser->m_vStringBuf.push_back ( strTok ); // Store string in internal buffer + a_Tok.SetString ( strTok, m_pParser->m_vStringBuf.size() ); + + m_iPos += ( int ) strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); + + return true; +} + +//---------------------------------------------------------------------------------------------------------------------- +/** + * @brief Create an error containing the parse error position. + * + * This function will create an Parser Exception object containing the error text and its position. + * + * @param a_iErrc [in] The error code of type #EErrorCodes. + * @param a_iPos [in] The position where the error was detected. + * @param a_strTok [in] The token string representation associated with the error. + * @throw ParserException always throws thats the only purpose of this function. + */ +void QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const +{ + m_pParser->Error ( a_iErrc, a_iPos, a_sTok ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void QmuParserTokenReader::SetArgSep ( char_type cArgSep ) +{ + m_cArgSep = cArgSep; +} + +//---------------------------------------------------------------------------------------------------------------------- +QChar QmuParserTokenReader::GetArgSep() const +{ + return m_cArgSep; +} +} // namespace qmu + diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index de73388eb..48ea055be 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -35,8 +35,8 @@ #include "qmuparserdef.h" #include "qmuparsertoken.h" -/** \file - \brief This file contains the parser token reader definition. +/** @file + @brief This file contains the parser token reader definition. */ @@ -45,7 +45,7 @@ namespace qmu // Forward declaration class QmuParserBase; - /** \brief Token reader for the ParserBase class. + /** @brief Token reader for the ParserBase class. */ class QmuParserTokenReader @@ -75,7 +75,7 @@ namespace qmu private: - /** \brief Syntax codes. + /** @brief Syntax codes. The syntax codes control the syntax check done during the first time parsing of the expression string. They are flags that indicate which tokens are allowed next From f505234bbd175929b5b6a1e8681024688a095c9f Mon Sep 17 00:00:00 2001 From: dismine Date: Wed, 30 Apr 2014 08:38:52 +0300 Subject: [PATCH 15/26] My surname like in my passport. --HG-- branch : feature --- dist/copyright_template.txt | 4 ++-- src/app/container/calculator.cpp | 2 +- src/app/container/calculator.h | 2 +- src/app/container/vcontainer.cpp | 2 +- src/app/container/vcontainer.h | 2 +- src/app/container/vincrement.cpp | 2 +- src/app/container/vincrement.h | 2 +- src/app/container/vmeasurement.cpp | 2 +- src/app/container/vmeasurement.h | 2 +- src/app/dialogs/app/configdialog.cpp | 2 +- src/app/dialogs/app/configdialog.h | 2 +- src/app/dialogs/app/dialoghistory.cpp | 2 +- src/app/dialogs/app/dialoghistory.h | 2 +- src/app/dialogs/app/dialogincrements.cpp | 2 +- src/app/dialogs/app/dialogincrements.h | 2 +- src/app/dialogs/app/dialogindividualmeasurements.cpp | 2 +- src/app/dialogs/app/dialogindividualmeasurements.h | 2 +- src/app/dialogs/app/dialogmeasurements.cpp | 2 +- src/app/dialogs/app/dialogmeasurements.h | 2 +- src/app/dialogs/app/dialogpatternproperties.cpp | 2 +- src/app/dialogs/app/dialogpatternproperties.h | 2 +- src/app/dialogs/app/dialogstandardmeasurements.cpp | 2 +- src/app/dialogs/app/dialogstandardmeasurements.h | 2 +- src/app/dialogs/app/pages.cpp | 2 +- src/app/dialogs/app/pages.h | 2 +- src/app/dialogs/dialogs.h | 2 +- src/app/dialogs/tools/dialogalongline.cpp | 2 +- src/app/dialogs/tools/dialogalongline.h | 2 +- src/app/dialogs/tools/dialogarc.cpp | 2 +- src/app/dialogs/tools/dialogarc.h | 2 +- src/app/dialogs/tools/dialogbisector.cpp | 2 +- src/app/dialogs/tools/dialogbisector.h | 2 +- src/app/dialogs/tools/dialogcutarc.cpp | 2 +- src/app/dialogs/tools/dialogcutarc.h | 2 +- src/app/dialogs/tools/dialogcutspline.cpp | 2 +- src/app/dialogs/tools/dialogcutspline.h | 2 +- src/app/dialogs/tools/dialogcutsplinepath.cpp | 2 +- src/app/dialogs/tools/dialogcutsplinepath.h | 2 +- src/app/dialogs/tools/dialogdetail.cpp | 2 +- src/app/dialogs/tools/dialogdetail.h | 2 +- src/app/dialogs/tools/dialogendline.cpp | 2 +- src/app/dialogs/tools/dialogendline.h | 2 +- src/app/dialogs/tools/dialogheight.cpp | 2 +- src/app/dialogs/tools/dialogheight.h | 2 +- src/app/dialogs/tools/dialogline.cpp | 2 +- src/app/dialogs/tools/dialogline.h | 2 +- src/app/dialogs/tools/dialoglineintersect.cpp | 2 +- src/app/dialogs/tools/dialoglineintersect.h | 2 +- src/app/dialogs/tools/dialognormal.cpp | 2 +- src/app/dialogs/tools/dialognormal.h | 2 +- src/app/dialogs/tools/dialogpointofcontact.cpp | 2 +- src/app/dialogs/tools/dialogpointofcontact.h | 2 +- src/app/dialogs/tools/dialogpointofintersection.cpp | 2 +- src/app/dialogs/tools/dialogpointofintersection.h | 2 +- src/app/dialogs/tools/dialogshoulderpoint.cpp | 2 +- src/app/dialogs/tools/dialogshoulderpoint.h | 2 +- src/app/dialogs/tools/dialogsinglepoint.cpp | 2 +- src/app/dialogs/tools/dialogsinglepoint.h | 2 +- src/app/dialogs/tools/dialogspline.cpp | 2 +- src/app/dialogs/tools/dialogspline.h | 2 +- src/app/dialogs/tools/dialogsplinepath.cpp | 2 +- src/app/dialogs/tools/dialogsplinepath.h | 2 +- src/app/dialogs/tools/dialogtool.cpp | 2 +- src/app/dialogs/tools/dialogtool.h | 2 +- src/app/dialogs/tools/dialogtriangle.cpp | 2 +- src/app/dialogs/tools/dialogtriangle.h | 2 +- src/app/dialogs/tools/dialoguniondetails.cpp | 2 +- src/app/dialogs/tools/dialoguniondetails.h | 2 +- src/app/exception/vexception.cpp | 2 +- src/app/exception/vexception.h | 2 +- src/app/exception/vexceptionbadid.cpp | 2 +- src/app/exception/vexceptionbadid.h | 2 +- src/app/exception/vexceptionconversionerror.cpp | 2 +- src/app/exception/vexceptionconversionerror.h | 2 +- src/app/exception/vexceptionemptyparameter.cpp | 2 +- src/app/exception/vexceptionemptyparameter.h | 2 +- src/app/exception/vexceptionobjecterror.cpp | 2 +- src/app/exception/vexceptionobjecterror.h | 2 +- src/app/exception/vexceptionwrongid.cpp | 2 +- src/app/exception/vexceptionwrongid.h | 2 +- src/app/geometry/varc.cpp | 2 +- src/app/geometry/varc.h | 2 +- src/app/geometry/vdetail.cpp | 2 +- src/app/geometry/vdetail.h | 2 +- src/app/geometry/vequidistant.cpp | 2 +- src/app/geometry/vequidistant.h | 2 +- src/app/geometry/vgobject.cpp | 2 +- src/app/geometry/vgobject.h | 2 +- src/app/geometry/vnodedetail.cpp | 2 +- src/app/geometry/vnodedetail.h | 2 +- src/app/geometry/vpointf.cpp | 2 +- src/app/geometry/vpointf.h | 2 +- src/app/geometry/vspline.cpp | 2 +- src/app/geometry/vspline.h | 2 +- src/app/geometry/vsplinepath.cpp | 2 +- src/app/geometry/vsplinepath.h | 2 +- src/app/geometry/vsplinepoint.cpp | 2 +- src/app/geometry/vsplinepoint.h | 2 +- src/app/main.cpp | 2 +- src/app/mainwindow.cpp | 2 +- src/app/mainwindow.h | 2 +- src/app/options.h | 2 +- src/app/stable.cpp | 2 +- src/app/stable.h | 2 +- src/app/tablewindow.cpp | 2 +- src/app/tablewindow.h | 2 +- src/app/tools/drawTools/drawtools.h | 2 +- src/app/tools/drawTools/vabstractspline.cpp | 2 +- src/app/tools/drawTools/vabstractspline.h | 2 +- src/app/tools/drawTools/vdrawtool.cpp | 2 +- src/app/tools/drawTools/vdrawtool.h | 2 +- src/app/tools/drawTools/vtoolalongline.cpp | 2 +- src/app/tools/drawTools/vtoolalongline.h | 2 +- src/app/tools/drawTools/vtoolarc.cpp | 2 +- src/app/tools/drawTools/vtoolarc.h | 2 +- src/app/tools/drawTools/vtoolbisector.cpp | 2 +- src/app/tools/drawTools/vtoolbisector.h | 2 +- src/app/tools/drawTools/vtoolcutarc.cpp | 2 +- src/app/tools/drawTools/vtoolcutarc.h | 2 +- src/app/tools/drawTools/vtoolcutspline.cpp | 2 +- src/app/tools/drawTools/vtoolcutspline.h | 2 +- src/app/tools/drawTools/vtoolcutsplinepath.cpp | 2 +- src/app/tools/drawTools/vtoolcutsplinepath.h | 2 +- src/app/tools/drawTools/vtoolendline.cpp | 2 +- src/app/tools/drawTools/vtoolendline.h | 2 +- src/app/tools/drawTools/vtoolheight.cpp | 2 +- src/app/tools/drawTools/vtoolheight.h | 2 +- src/app/tools/drawTools/vtoolline.cpp | 2 +- src/app/tools/drawTools/vtoolline.h | 2 +- src/app/tools/drawTools/vtoollineintersect.cpp | 2 +- src/app/tools/drawTools/vtoollineintersect.h | 2 +- src/app/tools/drawTools/vtoollinepoint.cpp | 2 +- src/app/tools/drawTools/vtoollinepoint.h | 2 +- src/app/tools/drawTools/vtoolnormal.cpp | 2 +- src/app/tools/drawTools/vtoolnormal.h | 2 +- src/app/tools/drawTools/vtoolpoint.cpp | 2 +- src/app/tools/drawTools/vtoolpoint.h | 2 +- src/app/tools/drawTools/vtoolpointofcontact.cpp | 2 +- src/app/tools/drawTools/vtoolpointofcontact.h | 2 +- src/app/tools/drawTools/vtoolpointofintersection.cpp | 2 +- src/app/tools/drawTools/vtoolpointofintersection.h | 2 +- src/app/tools/drawTools/vtoolshoulderpoint.cpp | 2 +- src/app/tools/drawTools/vtoolshoulderpoint.h | 2 +- src/app/tools/drawTools/vtoolsinglepoint.cpp | 2 +- src/app/tools/drawTools/vtoolsinglepoint.h | 2 +- src/app/tools/drawTools/vtoolspline.cpp | 2 +- src/app/tools/drawTools/vtoolspline.h | 2 +- src/app/tools/drawTools/vtoolsplinepath.cpp | 2 +- src/app/tools/drawTools/vtoolsplinepath.h | 2 +- src/app/tools/drawTools/vtooltriangle.cpp | 2 +- src/app/tools/drawTools/vtooltriangle.h | 2 +- src/app/tools/nodeDetails/nodedetails.h | 2 +- src/app/tools/nodeDetails/vabstractnode.cpp | 2 +- src/app/tools/nodeDetails/vabstractnode.h | 2 +- src/app/tools/nodeDetails/vnodearc.cpp | 2 +- src/app/tools/nodeDetails/vnodearc.h | 2 +- src/app/tools/nodeDetails/vnodepoint.cpp | 2 +- src/app/tools/nodeDetails/vnodepoint.h | 2 +- src/app/tools/nodeDetails/vnodespline.cpp | 2 +- src/app/tools/nodeDetails/vnodespline.h | 2 +- src/app/tools/nodeDetails/vnodesplinepath.cpp | 2 +- src/app/tools/nodeDetails/vnodesplinepath.h | 2 +- src/app/tools/tools.h | 2 +- src/app/tools/vabstracttool.cpp | 2 +- src/app/tools/vabstracttool.h | 2 +- src/app/tools/vdatatool.cpp | 2 +- src/app/tools/vdatatool.h | 2 +- src/app/tools/vtooldetail.cpp | 2 +- src/app/tools/vtooldetail.h | 2 +- src/app/tools/vtooluniondetails.cpp | 2 +- src/app/tools/vtooluniondetails.h | 2 +- src/app/version.cpp | 2 +- src/app/version.h | 2 +- src/app/widgets/doubledelegate.cpp | 2 +- src/app/widgets/doubledelegate.h | 2 +- src/app/widgets/textdelegate.cpp | 2 +- src/app/widgets/textdelegate.h | 2 +- src/app/widgets/vapplication.cpp | 2 +- src/app/widgets/vapplication.h | 2 +- src/app/widgets/vcontrolpointspline.cpp | 2 +- src/app/widgets/vcontrolpointspline.h | 2 +- src/app/widgets/vgraphicssimpletextitem.cpp | 2 +- src/app/widgets/vgraphicssimpletextitem.h | 2 +- src/app/widgets/vitem.cpp | 2 +- src/app/widgets/vitem.h | 2 +- src/app/widgets/vmaingraphicsscene.cpp | 2 +- src/app/widgets/vmaingraphicsscene.h | 2 +- src/app/widgets/vmaingraphicsview.cpp | 2 +- src/app/widgets/vmaingraphicsview.h | 2 +- src/app/widgets/vsimplearc.cpp | 2 +- src/app/widgets/vsimplearc.h | 2 +- src/app/widgets/vsimplespline.cpp | 2 +- src/app/widgets/vsimplespline.h | 2 +- src/app/widgets/vsimplesplinepath.cpp | 2 +- src/app/widgets/vsimplesplinepath.h | 2 +- src/app/widgets/vtablegraphicsview.cpp | 2 +- src/app/widgets/vtablegraphicsview.h | 2 +- src/app/xml/vdomdocument.cpp | 2 +- src/app/xml/vdomdocument.h | 2 +- src/app/xml/vindividualmeasurements.cpp | 2 +- src/app/xml/vindividualmeasurements.h | 2 +- src/app/xml/vpattern.cpp | 2 +- src/app/xml/vpattern.h | 2 +- src/app/xml/vstandardmeasurements.cpp | 2 +- src/app/xml/vstandardmeasurements.h | 2 +- src/app/xml/vtoolrecord.cpp | 2 +- src/app/xml/vtoolrecord.h | 2 +- src/libs/qmuparser/qmuparser.cpp | 2 +- src/libs/qmuparser/qmuparser.h | 2 +- src/libs/qmuparser/qmuparser_global.h | 2 +- src/libs/qmuparser/qmuparserbase.cpp | 2 +- src/libs/qmuparser/qmuparserbase.h | 2 +- src/libs/qmuparser/qmuparserbytecode.cpp | 2 +- src/libs/qmuparser/qmuparserbytecode.h | 2 +- src/libs/qmuparser/qmuparsercallback.cpp | 2 +- src/libs/qmuparser/qmuparsercallback.h | 2 +- src/libs/qmuparser/qmuparserdef.h | 2 +- src/libs/qmuparser/qmuparsererror.cpp | 2 +- src/libs/qmuparser/qmuparsererror.h | 2 +- src/libs/qmuparser/qmuparserfixes.h | 2 +- src/libs/qmuparser/qmuparsertest.cpp | 2 +- src/libs/qmuparser/qmuparsertest.h | 2 +- src/libs/qmuparser/qmuparsertoken.h | 2 +- src/libs/qmuparser/qmuparsertokenreader.cpp | 2 +- src/libs/qmuparser/qmuparsertokenreader.h | 2 +- src/libs/qmuparser/stable.cpp | 2 +- src/libs/qmuparser/stable.h | 2 +- 227 files changed, 228 insertions(+), 228 deletions(-) diff --git a/dist/copyright_template.txt b/dist/copyright_template.txt index 9339f95da..0d8dc9653 100644 --- a/dist/copyright_template.txt +++ b/dist/copyright_template.txt @@ -1,14 +1,14 @@ /************************************************************************ ** ** @file %FILENAME% - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date %DAY% %MONTH%, %YEAR% ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. - ** Copyright (C) 2013 Valentina project + ** Copyright (C) %YEAR% Valentina project ** All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify diff --git a/src/app/container/calculator.cpp b/src/app/container/calculator.cpp index cc625a6e6..6ea776396 100644 --- a/src/app/container/calculator.cpp +++ b/src/app/container/calculator.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file calculator.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/calculator.h b/src/app/container/calculator.h index 00b0fe7ef..24963b21d 100644 --- a/src/app/container/calculator.h +++ b/src/app/container/calculator.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file calculator.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/vcontainer.cpp b/src/app/container/vcontainer.cpp index b108b3b81..e3d954f42 100644 --- a/src/app/container/vcontainer.cpp +++ b/src/app/container/vcontainer.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vcontainer.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/vcontainer.h b/src/app/container/vcontainer.h index 6ccf5c1e1..c00e3ebee 100644 --- a/src/app/container/vcontainer.h +++ b/src/app/container/vcontainer.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vcontainer.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/vincrement.cpp b/src/app/container/vincrement.cpp index bcabed46c..83ef32a48 100644 --- a/src/app/container/vincrement.cpp +++ b/src/app/container/vincrement.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vincrementtablerow.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/vincrement.h b/src/app/container/vincrement.h index 943dc6683..32691f6d5 100644 --- a/src/app/container/vincrement.h +++ b/src/app/container/vincrement.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vincrementtablerow.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/vmeasurement.cpp b/src/app/container/vmeasurement.cpp index 3aa743ce6..248181a7f 100644 --- a/src/app/container/vmeasurement.cpp +++ b/src/app/container/vmeasurement.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vstandardtablecell.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/container/vmeasurement.h b/src/app/container/vmeasurement.h index 4dab3e8f4..8e2138f05 100644 --- a/src/app/container/vmeasurement.h +++ b/src/app/container/vmeasurement.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vstandardtablecell.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/app/configdialog.cpp b/src/app/dialogs/app/configdialog.cpp index a5e1a1244..c1bfacfbe 100644 --- a/src/app/dialogs/app/configdialog.cpp +++ b/src/app/dialogs/app/configdialog.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file configdialog.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 12 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/configdialog.h b/src/app/dialogs/app/configdialog.h index d1bfef44f..3af959906 100644 --- a/src/app/dialogs/app/configdialog.h +++ b/src/app/dialogs/app/configdialog.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file configdialog.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 12 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialoghistory.cpp b/src/app/dialogs/app/dialoghistory.cpp index 5c21887d8..d21274707 100644 --- a/src/app/dialogs/app/dialoghistory.cpp +++ b/src/app/dialogs/app/dialoghistory.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialoghistory.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/app/dialoghistory.h b/src/app/dialogs/app/dialoghistory.h index 9b1337df4..d3c5aea69 100644 --- a/src/app/dialogs/app/dialoghistory.h +++ b/src/app/dialogs/app/dialoghistory.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialoghistory.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/app/dialogincrements.cpp b/src/app/dialogs/app/dialogincrements.cpp index d91ab7e4b..560a21f1a 100644 --- a/src/app/dialogs/app/dialogincrements.cpp +++ b/src/app/dialogs/app/dialogincrements.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogincrements.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/app/dialogincrements.h b/src/app/dialogs/app/dialogincrements.h index c988f5b1e..f7e8e6fa3 100644 --- a/src/app/dialogs/app/dialogincrements.h +++ b/src/app/dialogs/app/dialogincrements.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogincrements.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/app/dialogindividualmeasurements.cpp b/src/app/dialogs/app/dialogindividualmeasurements.cpp index 46766d555..9b8337cf4 100644 --- a/src/app/dialogs/app/dialogindividualmeasurements.cpp +++ b/src/app/dialogs/app/dialogindividualmeasurements.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogindividualmeasurements.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 22 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogindividualmeasurements.h b/src/app/dialogs/app/dialogindividualmeasurements.h index 338391b5c..092e44c42 100644 --- a/src/app/dialogs/app/dialogindividualmeasurements.h +++ b/src/app/dialogs/app/dialogindividualmeasurements.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogindividualmeasurements.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 22 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogmeasurements.cpp b/src/app/dialogs/app/dialogmeasurements.cpp index 55e2e954b..621e87f60 100644 --- a/src/app/dialogs/app/dialogmeasurements.cpp +++ b/src/app/dialogs/app/dialogmeasurements.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpatterntype.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 21 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogmeasurements.h b/src/app/dialogs/app/dialogmeasurements.h index 23ef5a64e..82d2b9429 100644 --- a/src/app/dialogs/app/dialogmeasurements.h +++ b/src/app/dialogs/app/dialogmeasurements.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpatterntype.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 21 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogpatternproperties.cpp b/src/app/dialogs/app/dialogpatternproperties.cpp index 77503e337..5843bb240 100644 --- a/src/app/dialogs/app/dialogpatternproperties.cpp +++ b/src/app/dialogs/app/dialogpatternproperties.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpatternproperties.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 18 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogpatternproperties.h b/src/app/dialogs/app/dialogpatternproperties.h index 3c4fae0c5..d24ca735a 100644 --- a/src/app/dialogs/app/dialogpatternproperties.h +++ b/src/app/dialogs/app/dialogpatternproperties.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpatternproperties.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 18 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogstandardmeasurements.cpp b/src/app/dialogs/app/dialogstandardmeasurements.cpp index 20c9b96bd..e47ce9c53 100644 --- a/src/app/dialogs/app/dialogstandardmeasurements.cpp +++ b/src/app/dialogs/app/dialogstandardmeasurements.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogstandardmeasurements.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 21 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/dialogstandardmeasurements.h b/src/app/dialogs/app/dialogstandardmeasurements.h index 917bcb754..864c8c798 100644 --- a/src/app/dialogs/app/dialogstandardmeasurements.h +++ b/src/app/dialogs/app/dialogstandardmeasurements.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogstandardmeasurements.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 21 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/pages.cpp b/src/app/dialogs/app/pages.cpp index 68b27a7c9..50521eea4 100644 --- a/src/app/dialogs/app/pages.cpp +++ b/src/app/dialogs/app/pages.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file pages.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 12 2, 2014 ** ** @brief diff --git a/src/app/dialogs/app/pages.h b/src/app/dialogs/app/pages.h index ef8e96e1c..f709d6c79 100644 --- a/src/app/dialogs/app/pages.h +++ b/src/app/dialogs/app/pages.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file pages.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 12 2, 2014 ** ** @brief diff --git a/src/app/dialogs/dialogs.h b/src/app/dialogs/dialogs.h index 325c096a1..d85318e0b 100644 --- a/src/app/dialogs/dialogs.h +++ b/src/app/dialogs/dialogs.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogs.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogalongline.cpp b/src/app/dialogs/tools/dialogalongline.cpp index 32453506a..539909950 100644 --- a/src/app/dialogs/tools/dialogalongline.cpp +++ b/src/app/dialogs/tools/dialogalongline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogalongline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogalongline.h b/src/app/dialogs/tools/dialogalongline.h index 5aa093457..947c31793 100644 --- a/src/app/dialogs/tools/dialogalongline.h +++ b/src/app/dialogs/tools/dialogalongline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogalongline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogarc.cpp b/src/app/dialogs/tools/dialogarc.cpp index 97be1a470..dc9d5e6c1 100644 --- a/src/app/dialogs/tools/dialogarc.cpp +++ b/src/app/dialogs/tools/dialogarc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogarc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogarc.h b/src/app/dialogs/tools/dialogarc.h index 0611c9b94..729d39f63 100644 --- a/src/app/dialogs/tools/dialogarc.h +++ b/src/app/dialogs/tools/dialogarc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogarc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogbisector.cpp b/src/app/dialogs/tools/dialogbisector.cpp index e0003192a..9fd74a8b0 100644 --- a/src/app/dialogs/tools/dialogbisector.cpp +++ b/src/app/dialogs/tools/dialogbisector.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogbisector.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogbisector.h b/src/app/dialogs/tools/dialogbisector.h index 6b928f807..89fab7a10 100644 --- a/src/app/dialogs/tools/dialogbisector.h +++ b/src/app/dialogs/tools/dialogbisector.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogbisector.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogcutarc.cpp b/src/app/dialogs/tools/dialogcutarc.cpp index 2206bec4d..3239bb371 100644 --- a/src/app/dialogs/tools/dialogcutarc.cpp +++ b/src/app/dialogs/tools/dialogcutarc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogcutarc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 7 1, 2014 ** ** @brief diff --git a/src/app/dialogs/tools/dialogcutarc.h b/src/app/dialogs/tools/dialogcutarc.h index c2af664e9..8f9d93ed7 100644 --- a/src/app/dialogs/tools/dialogcutarc.h +++ b/src/app/dialogs/tools/dialogcutarc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogcutarc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 7 1, 2014 ** ** @brief diff --git a/src/app/dialogs/tools/dialogcutspline.cpp b/src/app/dialogs/tools/dialogcutspline.cpp index ce959b199..9ff85d2b1 100644 --- a/src/app/dialogs/tools/dialogcutspline.cpp +++ b/src/app/dialogs/tools/dialogcutspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogcutspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogcutspline.h b/src/app/dialogs/tools/dialogcutspline.h index 88d4c634b..35041872f 100644 --- a/src/app/dialogs/tools/dialogcutspline.h +++ b/src/app/dialogs/tools/dialogcutspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogcutspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogcutsplinepath.cpp b/src/app/dialogs/tools/dialogcutsplinepath.cpp index 003383392..4b6a51174 100644 --- a/src/app/dialogs/tools/dialogcutsplinepath.cpp +++ b/src/app/dialogs/tools/dialogcutsplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogcutsplinrpath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogcutsplinepath.h b/src/app/dialogs/tools/dialogcutsplinepath.h index 622d1f73d..417e85d94 100644 --- a/src/app/dialogs/tools/dialogcutsplinepath.h +++ b/src/app/dialogs/tools/dialogcutsplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogcutsplinrpath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogdetail.cpp b/src/app/dialogs/tools/dialogdetail.cpp index b877cca27..0a7699ffe 100644 --- a/src/app/dialogs/tools/dialogdetail.cpp +++ b/src/app/dialogs/tools/dialogdetail.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogdetail.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogdetail.h b/src/app/dialogs/tools/dialogdetail.h index 38dbe5a3b..b2edce30b 100644 --- a/src/app/dialogs/tools/dialogdetail.h +++ b/src/app/dialogs/tools/dialogdetail.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogdetail.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogendline.cpp b/src/app/dialogs/tools/dialogendline.cpp index 806a7f43d..c096433f9 100644 --- a/src/app/dialogs/tools/dialogendline.cpp +++ b/src/app/dialogs/tools/dialogendline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogendline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogendline.h b/src/app/dialogs/tools/dialogendline.h index 97015d833..7dfc82b03 100644 --- a/src/app/dialogs/tools/dialogendline.h +++ b/src/app/dialogs/tools/dialogendline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogendline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogheight.cpp b/src/app/dialogs/tools/dialogheight.cpp index 249e45fa7..ac3e1f437 100644 --- a/src/app/dialogs/tools/dialogheight.cpp +++ b/src/app/dialogs/tools/dialogheight.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogheight.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogheight.h b/src/app/dialogs/tools/dialogheight.h index 79df86f24..63ebbf5bb 100644 --- a/src/app/dialogs/tools/dialogheight.h +++ b/src/app/dialogs/tools/dialogheight.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogheight.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogline.cpp b/src/app/dialogs/tools/dialogline.cpp index e5a580c88..78d2d3f05 100644 --- a/src/app/dialogs/tools/dialogline.cpp +++ b/src/app/dialogs/tools/dialogline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogline.h b/src/app/dialogs/tools/dialogline.h index 82e8c4fa1..2978b6d1a 100644 --- a/src/app/dialogs/tools/dialogline.h +++ b/src/app/dialogs/tools/dialogline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialoglineintersect.cpp b/src/app/dialogs/tools/dialoglineintersect.cpp index 22f7d0b05..a1e3fb66b 100644 --- a/src/app/dialogs/tools/dialoglineintersect.cpp +++ b/src/app/dialogs/tools/dialoglineintersect.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialoglineintersect.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialoglineintersect.h b/src/app/dialogs/tools/dialoglineintersect.h index c74e0b555..3196210f7 100644 --- a/src/app/dialogs/tools/dialoglineintersect.h +++ b/src/app/dialogs/tools/dialoglineintersect.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialoglineintersect.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialognormal.cpp b/src/app/dialogs/tools/dialognormal.cpp index 298e36885..851cd40a3 100644 --- a/src/app/dialogs/tools/dialognormal.cpp +++ b/src/app/dialogs/tools/dialognormal.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialognormal.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialognormal.h b/src/app/dialogs/tools/dialognormal.h index 51a2f1c20..a47aae457 100644 --- a/src/app/dialogs/tools/dialognormal.h +++ b/src/app/dialogs/tools/dialognormal.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialognormal.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogpointofcontact.cpp b/src/app/dialogs/tools/dialogpointofcontact.cpp index 8d9881e7f..7f024a6d9 100644 --- a/src/app/dialogs/tools/dialogpointofcontact.cpp +++ b/src/app/dialogs/tools/dialogpointofcontact.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpointofcontact.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogpointofcontact.h b/src/app/dialogs/tools/dialogpointofcontact.h index 9c8949ed7..d99ae957d 100644 --- a/src/app/dialogs/tools/dialogpointofcontact.h +++ b/src/app/dialogs/tools/dialogpointofcontact.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpointofcontact.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogpointofintersection.cpp b/src/app/dialogs/tools/dialogpointofintersection.cpp index 7a2646422..52297d452 100644 --- a/src/app/dialogs/tools/dialogpointofintersection.cpp +++ b/src/app/dialogs/tools/dialogpointofintersection.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpointofintersection.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogpointofintersection.h b/src/app/dialogs/tools/dialogpointofintersection.h index b0f41e510..8c8b98c2a 100644 --- a/src/app/dialogs/tools/dialogpointofintersection.h +++ b/src/app/dialogs/tools/dialogpointofintersection.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogpointofintersection.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogshoulderpoint.cpp b/src/app/dialogs/tools/dialogshoulderpoint.cpp index 2a679c2b4..21ae6e598 100644 --- a/src/app/dialogs/tools/dialogshoulderpoint.cpp +++ b/src/app/dialogs/tools/dialogshoulderpoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogshoulderpoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogshoulderpoint.h b/src/app/dialogs/tools/dialogshoulderpoint.h index 2fc36dcc5..9d9130eb6 100644 --- a/src/app/dialogs/tools/dialogshoulderpoint.h +++ b/src/app/dialogs/tools/dialogshoulderpoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogshoulderpoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogsinglepoint.cpp b/src/app/dialogs/tools/dialogsinglepoint.cpp index f4f07b064..2df4c0f8e 100644 --- a/src/app/dialogs/tools/dialogsinglepoint.cpp +++ b/src/app/dialogs/tools/dialogsinglepoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogsinglepoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogsinglepoint.h b/src/app/dialogs/tools/dialogsinglepoint.h index a4f994043..f0da08178 100644 --- a/src/app/dialogs/tools/dialogsinglepoint.h +++ b/src/app/dialogs/tools/dialogsinglepoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogsinglepoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogspline.cpp b/src/app/dialogs/tools/dialogspline.cpp index 411868d5b..615834b03 100644 --- a/src/app/dialogs/tools/dialogspline.cpp +++ b/src/app/dialogs/tools/dialogspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogspline.h b/src/app/dialogs/tools/dialogspline.h index c88ec7bb8..47aa5a5c5 100644 --- a/src/app/dialogs/tools/dialogspline.h +++ b/src/app/dialogs/tools/dialogspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogsplinepath.cpp b/src/app/dialogs/tools/dialogsplinepath.cpp index ed7d10dbf..8fc9c5960 100644 --- a/src/app/dialogs/tools/dialogsplinepath.cpp +++ b/src/app/dialogs/tools/dialogsplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogsplinepath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogsplinepath.h b/src/app/dialogs/tools/dialogsplinepath.h index 287d316cb..8e1ddca4a 100644 --- a/src/app/dialogs/tools/dialogsplinepath.h +++ b/src/app/dialogs/tools/dialogsplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogsplinepath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogtool.cpp b/src/app/dialogs/tools/dialogtool.cpp index 320dea50a..e9294d7f1 100644 --- a/src/app/dialogs/tools/dialogtool.cpp +++ b/src/app/dialogs/tools/dialogtool.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogtool.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogtool.h b/src/app/dialogs/tools/dialogtool.h index 1073a4a69..6def423d3 100644 --- a/src/app/dialogs/tools/dialogtool.h +++ b/src/app/dialogs/tools/dialogtool.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogtool.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogtriangle.cpp b/src/app/dialogs/tools/dialogtriangle.cpp index d58a3094d..83604fd70 100644 --- a/src/app/dialogs/tools/dialogtriangle.cpp +++ b/src/app/dialogs/tools/dialogtriangle.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogtriangle.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialogtriangle.h b/src/app/dialogs/tools/dialogtriangle.h index d1d132857..609e94cea 100644 --- a/src/app/dialogs/tools/dialogtriangle.h +++ b/src/app/dialogs/tools/dialogtriangle.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialogtriangle.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialoguniondetails.cpp b/src/app/dialogs/tools/dialoguniondetails.cpp index 4eb9e10ad..1bc93d7ae 100644 --- a/src/app/dialogs/tools/dialoguniondetails.cpp +++ b/src/app/dialogs/tools/dialoguniondetails.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialoguniondetails.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 23 12, 2013 ** ** @brief diff --git a/src/app/dialogs/tools/dialoguniondetails.h b/src/app/dialogs/tools/dialoguniondetails.h index 5d8e4a225..a02a2d95b 100644 --- a/src/app/dialogs/tools/dialoguniondetails.h +++ b/src/app/dialogs/tools/dialoguniondetails.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file dialoguniondetails.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 23 12, 2013 ** ** @brief diff --git a/src/app/exception/vexception.cpp b/src/app/exception/vexception.cpp index 4221c65f9..aaffd3e54 100644 --- a/src/app/exception/vexception.cpp +++ b/src/app/exception/vexception.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexception.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexception.h b/src/app/exception/vexception.h index be5ba90e0..9771bb004 100644 --- a/src/app/exception/vexception.h +++ b/src/app/exception/vexception.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexception.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionbadid.cpp b/src/app/exception/vexceptionbadid.cpp index 78bfc6327..39106eea9 100644 --- a/src/app/exception/vexceptionbadid.cpp +++ b/src/app/exception/vexceptionbadid.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionbadid.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionbadid.h b/src/app/exception/vexceptionbadid.h index beee3cdf0..9d4108241 100644 --- a/src/app/exception/vexceptionbadid.h +++ b/src/app/exception/vexceptionbadid.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionbadid.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionconversionerror.cpp b/src/app/exception/vexceptionconversionerror.cpp index bc216ba43..cdbebbc77 100644 --- a/src/app/exception/vexceptionconversionerror.cpp +++ b/src/app/exception/vexceptionconversionerror.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionconversionerror.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionconversionerror.h b/src/app/exception/vexceptionconversionerror.h index fbf5d4ac2..addade580 100644 --- a/src/app/exception/vexceptionconversionerror.h +++ b/src/app/exception/vexceptionconversionerror.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionconversionerror.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionemptyparameter.cpp b/src/app/exception/vexceptionemptyparameter.cpp index ed767abc9..0f8ce145e 100644 --- a/src/app/exception/vexceptionemptyparameter.cpp +++ b/src/app/exception/vexceptionemptyparameter.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionemptyparameter.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionemptyparameter.h b/src/app/exception/vexceptionemptyparameter.h index 8f9f5525a..fb04a7ed3 100644 --- a/src/app/exception/vexceptionemptyparameter.h +++ b/src/app/exception/vexceptionemptyparameter.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionemptyparameter.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionobjecterror.cpp b/src/app/exception/vexceptionobjecterror.cpp index 4273a745b..61b0867c9 100644 --- a/src/app/exception/vexceptionobjecterror.cpp +++ b/src/app/exception/vexceptionobjecterror.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionobjecterror.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionobjecterror.h b/src/app/exception/vexceptionobjecterror.h index 864a78e13..ccebfcebd 100644 --- a/src/app/exception/vexceptionobjecterror.h +++ b/src/app/exception/vexceptionobjecterror.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionobjecterror.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionwrongid.cpp b/src/app/exception/vexceptionwrongid.cpp index 76471d0c7..5eff5cf81 100644 --- a/src/app/exception/vexceptionwrongid.cpp +++ b/src/app/exception/vexceptionwrongid.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionwrongparameterid.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/exception/vexceptionwrongid.h b/src/app/exception/vexceptionwrongid.h index 22be31c60..b275acfe5 100644 --- a/src/app/exception/vexceptionwrongid.h +++ b/src/app/exception/vexceptionwrongid.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vexceptionwrongparameterid.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/varc.cpp b/src/app/geometry/varc.cpp index b9d323dc7..c81506f13 100644 --- a/src/app/geometry/varc.cpp +++ b/src/app/geometry/varc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file varc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/varc.h b/src/app/geometry/varc.h index b2e002e9d..950c5403a 100644 --- a/src/app/geometry/varc.h +++ b/src/app/geometry/varc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file varc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vdetail.cpp b/src/app/geometry/vdetail.cpp index e1517bc1e..0ae8ed608 100644 --- a/src/app/geometry/vdetail.cpp +++ b/src/app/geometry/vdetail.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdetail.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vdetail.h b/src/app/geometry/vdetail.h index 6c0a2975c..bdd166dc8 100644 --- a/src/app/geometry/vdetail.h +++ b/src/app/geometry/vdetail.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdetail.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vequidistant.cpp b/src/app/geometry/vequidistant.cpp index 96f90fb84..255cd7f27 100644 --- a/src/app/geometry/vequidistant.cpp +++ b/src/app/geometry/vequidistant.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vequidistant.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 28 1, 2014 ** ** @brief diff --git a/src/app/geometry/vequidistant.h b/src/app/geometry/vequidistant.h index 13830858b..d92ff2487 100644 --- a/src/app/geometry/vequidistant.h +++ b/src/app/geometry/vequidistant.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vequidistant.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 28 1, 2014 ** ** @brief diff --git a/src/app/geometry/vgobject.cpp b/src/app/geometry/vgobject.cpp index cd051d540..4002472ed 100644 --- a/src/app/geometry/vgobject.cpp +++ b/src/app/geometry/vgobject.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vgobject.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 27 12, 2013 ** ** @brief diff --git a/src/app/geometry/vgobject.h b/src/app/geometry/vgobject.h index 773e6ce2e..c05a73ce0 100644 --- a/src/app/geometry/vgobject.h +++ b/src/app/geometry/vgobject.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vgobject.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 27 12, 2013 ** ** @brief diff --git a/src/app/geometry/vnodedetail.cpp b/src/app/geometry/vnodedetail.cpp index ca8183fad..3c52ab31f 100644 --- a/src/app/geometry/vnodedetail.cpp +++ b/src/app/geometry/vnodedetail.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodedetail.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vnodedetail.h b/src/app/geometry/vnodedetail.h index 2a16dac7d..72b11d893 100644 --- a/src/app/geometry/vnodedetail.h +++ b/src/app/geometry/vnodedetail.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodedetail.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vpointf.cpp b/src/app/geometry/vpointf.cpp index 97646ca9c..81ecfb5f3 100644 --- a/src/app/geometry/vpointf.cpp +++ b/src/app/geometry/vpointf.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vpointf.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vpointf.h b/src/app/geometry/vpointf.h index a88c8c99e..3737f4a75 100644 --- a/src/app/geometry/vpointf.h +++ b/src/app/geometry/vpointf.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vpointf.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vspline.cpp b/src/app/geometry/vspline.cpp index a3457a45b..23cd0ae63 100644 --- a/src/app/geometry/vspline.cpp +++ b/src/app/geometry/vspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vspline.h b/src/app/geometry/vspline.h index e6b1fb013..218bfaa4d 100644 --- a/src/app/geometry/vspline.h +++ b/src/app/geometry/vspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vsplinepath.cpp b/src/app/geometry/vsplinepath.cpp index 0351451e2..0698b93c2 100644 --- a/src/app/geometry/vsplinepath.cpp +++ b/src/app/geometry/vsplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsplinepath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vsplinepath.h b/src/app/geometry/vsplinepath.h index 1b780f42a..3c11c3bd3 100644 --- a/src/app/geometry/vsplinepath.h +++ b/src/app/geometry/vsplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsplinepath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vsplinepoint.cpp b/src/app/geometry/vsplinepoint.cpp index 18ebf0408..a638c7f42 100644 --- a/src/app/geometry/vsplinepoint.cpp +++ b/src/app/geometry/vsplinepoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsplinepoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/geometry/vsplinepoint.h b/src/app/geometry/vsplinepoint.h index dbe57a5db..509d63f26 100644 --- a/src/app/geometry/vsplinepoint.h +++ b/src/app/geometry/vsplinepoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsplinepoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/main.cpp b/src/app/main.cpp index 5677647d4..ba9eed428 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file main.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 39c75bb32..ace057485 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file mainwindow.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/mainwindow.h b/src/app/mainwindow.h index 8df7c3985..9a8f8407f 100644 --- a/src/app/mainwindow.h +++ b/src/app/mainwindow.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file mainwindow.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/options.h b/src/app/options.h index 6ed030062..cff42b632 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file options.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/stable.cpp b/src/app/stable.cpp index 57b3c2027..243b23938 100644 --- a/src/app/stable.cpp +++ b/src/app/stable.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file stable.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/stable.h b/src/app/stable.h index 3e556d0ab..7ebbe41f9 100644 --- a/src/app/stable.h +++ b/src/app/stable.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file stable.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tablewindow.cpp b/src/app/tablewindow.cpp index ff2bff51b..23ff21da2 100644 --- a/src/app/tablewindow.cpp +++ b/src/app/tablewindow.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file tablewindow.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tablewindow.h b/src/app/tablewindow.h index 2db91a8ff..f36342fc8 100644 --- a/src/app/tablewindow.h +++ b/src/app/tablewindow.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file tablewindow.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/drawtools.h b/src/app/tools/drawTools/drawtools.h index f3dc544bc..3a06646b1 100644 --- a/src/app/tools/drawTools/drawtools.h +++ b/src/app/tools/drawTools/drawtools.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file drawtools.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vabstractspline.cpp b/src/app/tools/drawTools/vabstractspline.cpp index e138d4ba4..3f4ce2cdc 100644 --- a/src/app/tools/drawTools/vabstractspline.cpp +++ b/src/app/tools/drawTools/vabstractspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vabstractspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 4 3, 2014 ** ** @brief diff --git a/src/app/tools/drawTools/vabstractspline.h b/src/app/tools/drawTools/vabstractspline.h index 46261a5c3..e5cc6ff9d 100644 --- a/src/app/tools/drawTools/vabstractspline.h +++ b/src/app/tools/drawTools/vabstractspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vabstractspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 4 3, 2014 ** ** @brief diff --git a/src/app/tools/drawTools/vdrawtool.cpp b/src/app/tools/drawTools/vdrawtool.cpp index 69e864c3b..8312f4fa5 100644 --- a/src/app/tools/drawTools/vdrawtool.cpp +++ b/src/app/tools/drawTools/vdrawtool.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdrawtool.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vdrawtool.h b/src/app/tools/drawTools/vdrawtool.h index d6e86c05d..af389a880 100644 --- a/src/app/tools/drawTools/vdrawtool.h +++ b/src/app/tools/drawTools/vdrawtool.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdrawtool.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolalongline.cpp b/src/app/tools/drawTools/vtoolalongline.cpp index ac8e65204..0e9b5396a 100644 --- a/src/app/tools/drawTools/vtoolalongline.cpp +++ b/src/app/tools/drawTools/vtoolalongline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolalongline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolalongline.h b/src/app/tools/drawTools/vtoolalongline.h index 89924d36e..f9a50f86e 100644 --- a/src/app/tools/drawTools/vtoolalongline.h +++ b/src/app/tools/drawTools/vtoolalongline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolalongline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolarc.cpp b/src/app/tools/drawTools/vtoolarc.cpp index 02d6d8f6a..842c14675 100644 --- a/src/app/tools/drawTools/vtoolarc.cpp +++ b/src/app/tools/drawTools/vtoolarc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolarc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolarc.h b/src/app/tools/drawTools/vtoolarc.h index 8dd66a768..f6ae530a9 100644 --- a/src/app/tools/drawTools/vtoolarc.h +++ b/src/app/tools/drawTools/vtoolarc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolarc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolbisector.cpp b/src/app/tools/drawTools/vtoolbisector.cpp index 34bf702b6..caac9b893 100644 --- a/src/app/tools/drawTools/vtoolbisector.cpp +++ b/src/app/tools/drawTools/vtoolbisector.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolbisector.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolbisector.h b/src/app/tools/drawTools/vtoolbisector.h index 84aeac0f8..9af080e12 100644 --- a/src/app/tools/drawTools/vtoolbisector.h +++ b/src/app/tools/drawTools/vtoolbisector.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolbisector.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolcutarc.cpp b/src/app/tools/drawTools/vtoolcutarc.cpp index c363d4723..2ca7bf4f6 100644 --- a/src/app/tools/drawTools/vtoolcutarc.cpp +++ b/src/app/tools/drawTools/vtoolcutarc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolcutarc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 7 1, 2014 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolcutarc.h b/src/app/tools/drawTools/vtoolcutarc.h index 5d44d47b6..e9933f812 100644 --- a/src/app/tools/drawTools/vtoolcutarc.h +++ b/src/app/tools/drawTools/vtoolcutarc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolcutarc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 7 1, 2014 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolcutspline.cpp b/src/app/tools/drawTools/vtoolcutspline.cpp index 9c0e88a96..e7bb7f458 100644 --- a/src/app/tools/drawTools/vtoolcutspline.cpp +++ b/src/app/tools/drawTools/vtoolcutspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolcutspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolcutspline.h b/src/app/tools/drawTools/vtoolcutspline.h index 5ed16027d..0bff6ea89 100644 --- a/src/app/tools/drawTools/vtoolcutspline.h +++ b/src/app/tools/drawTools/vtoolcutspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolcutspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolcutsplinepath.cpp b/src/app/tools/drawTools/vtoolcutsplinepath.cpp index da87b2d83..7c879f690 100644 --- a/src/app/tools/drawTools/vtoolcutsplinepath.cpp +++ b/src/app/tools/drawTools/vtoolcutsplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolcutsplinepath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolcutsplinepath.h b/src/app/tools/drawTools/vtoolcutsplinepath.h index 08b319439..e2c288291 100644 --- a/src/app/tools/drawTools/vtoolcutsplinepath.h +++ b/src/app/tools/drawTools/vtoolcutsplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolcutsplinepath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 15 12, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolendline.cpp b/src/app/tools/drawTools/vtoolendline.cpp index 98603c373..d57ef5f78 100644 --- a/src/app/tools/drawTools/vtoolendline.cpp +++ b/src/app/tools/drawTools/vtoolendline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolendline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolendline.h b/src/app/tools/drawTools/vtoolendline.h index f386e360e..acf0bcf20 100644 --- a/src/app/tools/drawTools/vtoolendline.h +++ b/src/app/tools/drawTools/vtoolendline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolendline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolheight.cpp b/src/app/tools/drawTools/vtoolheight.cpp index 5a0640718..5ecfdc5b7 100644 --- a/src/app/tools/drawTools/vtoolheight.cpp +++ b/src/app/tools/drawTools/vtoolheight.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolheight.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolheight.h b/src/app/tools/drawTools/vtoolheight.h index ce1105806..56d2160e1 100644 --- a/src/app/tools/drawTools/vtoolheight.h +++ b/src/app/tools/drawTools/vtoolheight.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolheight.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolline.cpp b/src/app/tools/drawTools/vtoolline.cpp index 8eede987d..950cbf85e 100644 --- a/src/app/tools/drawTools/vtoolline.cpp +++ b/src/app/tools/drawTools/vtoolline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolline.h b/src/app/tools/drawTools/vtoolline.h index be951fb59..6302a26e5 100644 --- a/src/app/tools/drawTools/vtoolline.h +++ b/src/app/tools/drawTools/vtoolline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoollineintersect.cpp b/src/app/tools/drawTools/vtoollineintersect.cpp index 9598a3873..80630b280 100644 --- a/src/app/tools/drawTools/vtoollineintersect.cpp +++ b/src/app/tools/drawTools/vtoollineintersect.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoollineintersect.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoollineintersect.h b/src/app/tools/drawTools/vtoollineintersect.h index 521458048..572142b36 100644 --- a/src/app/tools/drawTools/vtoollineintersect.h +++ b/src/app/tools/drawTools/vtoollineintersect.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoollineintersect.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoollinepoint.cpp b/src/app/tools/drawTools/vtoollinepoint.cpp index 7c7bde930..89d2ab7c4 100644 --- a/src/app/tools/drawTools/vtoollinepoint.cpp +++ b/src/app/tools/drawTools/vtoollinepoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoollinepoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoollinepoint.h b/src/app/tools/drawTools/vtoollinepoint.h index 52628620a..1a242ab6d 100644 --- a/src/app/tools/drawTools/vtoollinepoint.h +++ b/src/app/tools/drawTools/vtoollinepoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoollinepoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolnormal.cpp b/src/app/tools/drawTools/vtoolnormal.cpp index 83b00e6af..0a2c038b5 100644 --- a/src/app/tools/drawTools/vtoolnormal.cpp +++ b/src/app/tools/drawTools/vtoolnormal.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolnormal.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolnormal.h b/src/app/tools/drawTools/vtoolnormal.h index da1d0170b..415b70e33 100644 --- a/src/app/tools/drawTools/vtoolnormal.h +++ b/src/app/tools/drawTools/vtoolnormal.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolnormal.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolpoint.cpp b/src/app/tools/drawTools/vtoolpoint.cpp index d7d4a90b3..0c03e937c 100644 --- a/src/app/tools/drawTools/vtoolpoint.cpp +++ b/src/app/tools/drawTools/vtoolpoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolpoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolpoint.h b/src/app/tools/drawTools/vtoolpoint.h index 4622d6bc9..ab505e14e 100644 --- a/src/app/tools/drawTools/vtoolpoint.h +++ b/src/app/tools/drawTools/vtoolpoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolpoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolpointofcontact.cpp b/src/app/tools/drawTools/vtoolpointofcontact.cpp index b1221b45e..69aa5bf20 100644 --- a/src/app/tools/drawTools/vtoolpointofcontact.cpp +++ b/src/app/tools/drawTools/vtoolpointofcontact.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolpointofcontact.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolpointofcontact.h b/src/app/tools/drawTools/vtoolpointofcontact.h index 0199dbdba..b283f238a 100644 --- a/src/app/tools/drawTools/vtoolpointofcontact.h +++ b/src/app/tools/drawTools/vtoolpointofcontact.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolpointofcontact.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolpointofintersection.cpp b/src/app/tools/drawTools/vtoolpointofintersection.cpp index c66fc0c04..2b91430f7 100644 --- a/src/app/tools/drawTools/vtoolpointofintersection.cpp +++ b/src/app/tools/drawTools/vtoolpointofintersection.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolpointofintersection.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolpointofintersection.h b/src/app/tools/drawTools/vtoolpointofintersection.h index 89fc26709..194d09395 100644 --- a/src/app/tools/drawTools/vtoolpointofintersection.h +++ b/src/app/tools/drawTools/vtoolpointofintersection.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolpointofintersection.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolshoulderpoint.cpp b/src/app/tools/drawTools/vtoolshoulderpoint.cpp index 4aa522f9c..47fb729ac 100644 --- a/src/app/tools/drawTools/vtoolshoulderpoint.cpp +++ b/src/app/tools/drawTools/vtoolshoulderpoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolshoulderpoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolshoulderpoint.h b/src/app/tools/drawTools/vtoolshoulderpoint.h index 8885dc8d6..ba5e2b96f 100644 --- a/src/app/tools/drawTools/vtoolshoulderpoint.h +++ b/src/app/tools/drawTools/vtoolshoulderpoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolshoulderpoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolsinglepoint.cpp b/src/app/tools/drawTools/vtoolsinglepoint.cpp index f88570791..fd0f63c18 100644 --- a/src/app/tools/drawTools/vtoolsinglepoint.cpp +++ b/src/app/tools/drawTools/vtoolsinglepoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolsinglepoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolsinglepoint.h b/src/app/tools/drawTools/vtoolsinglepoint.h index 90fbfbd67..116734b6f 100644 --- a/src/app/tools/drawTools/vtoolsinglepoint.h +++ b/src/app/tools/drawTools/vtoolsinglepoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolsinglepoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolspline.cpp b/src/app/tools/drawTools/vtoolspline.cpp index ce1a7f6e1..71a5a9dd9 100644 --- a/src/app/tools/drawTools/vtoolspline.cpp +++ b/src/app/tools/drawTools/vtoolspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolspline.h b/src/app/tools/drawTools/vtoolspline.h index 1f42f5060..a13f6655b 100644 --- a/src/app/tools/drawTools/vtoolspline.h +++ b/src/app/tools/drawTools/vtoolspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolsplinepath.cpp b/src/app/tools/drawTools/vtoolsplinepath.cpp index 523c5e087..1de4c5327 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.cpp +++ b/src/app/tools/drawTools/vtoolsplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolsplinepath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtoolsplinepath.h b/src/app/tools/drawTools/vtoolsplinepath.h index 4e7ca8358..e760d6560 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.h +++ b/src/app/tools/drawTools/vtoolsplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolsplinepath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtooltriangle.cpp b/src/app/tools/drawTools/vtooltriangle.cpp index 4bfbb486e..c88450982 100644 --- a/src/app/tools/drawTools/vtooltriangle.cpp +++ b/src/app/tools/drawTools/vtooltriangle.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtooltriangle.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/drawTools/vtooltriangle.h b/src/app/tools/drawTools/vtooltriangle.h index 7495e3b3c..0a6e12f8a 100644 --- a/src/app/tools/drawTools/vtooltriangle.h +++ b/src/app/tools/drawTools/vtooltriangle.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtooltriangle.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/nodedetails.h b/src/app/tools/nodeDetails/nodedetails.h index d230f7456..fbdf2b2ba 100644 --- a/src/app/tools/nodeDetails/nodedetails.h +++ b/src/app/tools/nodeDetails/nodedetails.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file nodedetails.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vabstractnode.cpp b/src/app/tools/nodeDetails/vabstractnode.cpp index 52285c2c8..1b721a203 100644 --- a/src/app/tools/nodeDetails/vabstractnode.cpp +++ b/src/app/tools/nodeDetails/vabstractnode.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vabstractnode.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vabstractnode.h b/src/app/tools/nodeDetails/vabstractnode.h index b91bde905..5261c99f6 100644 --- a/src/app/tools/nodeDetails/vabstractnode.h +++ b/src/app/tools/nodeDetails/vabstractnode.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vabstractnode.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodearc.cpp b/src/app/tools/nodeDetails/vnodearc.cpp index 161c7f5fc..a31ebf812 100644 --- a/src/app/tools/nodeDetails/vnodearc.cpp +++ b/src/app/tools/nodeDetails/vnodearc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodearc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodearc.h b/src/app/tools/nodeDetails/vnodearc.h index e548a2e5e..a73e6c517 100644 --- a/src/app/tools/nodeDetails/vnodearc.h +++ b/src/app/tools/nodeDetails/vnodearc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodearc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodepoint.cpp b/src/app/tools/nodeDetails/vnodepoint.cpp index 0b2a0204c..854d5fcf7 100644 --- a/src/app/tools/nodeDetails/vnodepoint.cpp +++ b/src/app/tools/nodeDetails/vnodepoint.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodepoint.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodepoint.h b/src/app/tools/nodeDetails/vnodepoint.h index af513d3b5..46c643771 100644 --- a/src/app/tools/nodeDetails/vnodepoint.h +++ b/src/app/tools/nodeDetails/vnodepoint.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodepoint.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodespline.cpp b/src/app/tools/nodeDetails/vnodespline.cpp index a9ad3124e..f0d017d79 100644 --- a/src/app/tools/nodeDetails/vnodespline.cpp +++ b/src/app/tools/nodeDetails/vnodespline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodespline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodespline.h b/src/app/tools/nodeDetails/vnodespline.h index b7e680e40..a21b44842 100644 --- a/src/app/tools/nodeDetails/vnodespline.h +++ b/src/app/tools/nodeDetails/vnodespline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodespline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodesplinepath.cpp b/src/app/tools/nodeDetails/vnodesplinepath.cpp index c8a01a065..35a02aee4 100644 --- a/src/app/tools/nodeDetails/vnodesplinepath.cpp +++ b/src/app/tools/nodeDetails/vnodesplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodesplinepath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/nodeDetails/vnodesplinepath.h b/src/app/tools/nodeDetails/vnodesplinepath.h index 8c0829543..843c4038c 100644 --- a/src/app/tools/nodeDetails/vnodesplinepath.h +++ b/src/app/tools/nodeDetails/vnodesplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vnodesplinepath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/tools.h b/src/app/tools/tools.h index 69adbf1ce..2802f71ce 100644 --- a/src/app/tools/tools.h +++ b/src/app/tools/tools.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file tools.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vabstracttool.cpp b/src/app/tools/vabstracttool.cpp index 78748c3db..50ff3af22 100644 --- a/src/app/tools/vabstracttool.cpp +++ b/src/app/tools/vabstracttool.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vabstracttool.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vabstracttool.h b/src/app/tools/vabstracttool.h index 74cb53a17..e3642313e 100644 --- a/src/app/tools/vabstracttool.h +++ b/src/app/tools/vabstracttool.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vabstracttool.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vdatatool.cpp b/src/app/tools/vdatatool.cpp index 5d857321a..3c791f08b 100644 --- a/src/app/tools/vdatatool.cpp +++ b/src/app/tools/vdatatool.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdatatool.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vdatatool.h b/src/app/tools/vdatatool.h index 69ef0a00f..ceb185b34 100644 --- a/src/app/tools/vdatatool.h +++ b/src/app/tools/vdatatool.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdatatool.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vtooldetail.cpp b/src/app/tools/vtooldetail.cpp index 9690202a3..2e109114c 100644 --- a/src/app/tools/vtooldetail.cpp +++ b/src/app/tools/vtooldetail.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtooldetail.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vtooldetail.h b/src/app/tools/vtooldetail.h index 2b3e1b451..c6e69eab3 100644 --- a/src/app/tools/vtooldetail.h +++ b/src/app/tools/vtooldetail.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtooldetail.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/tools/vtooluniondetails.cpp b/src/app/tools/vtooluniondetails.cpp index 6fa37d28a..006403c9e 100644 --- a/src/app/tools/vtooluniondetails.cpp +++ b/src/app/tools/vtooluniondetails.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtooluniondetails.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 26 12, 2013 ** ** @brief diff --git a/src/app/tools/vtooluniondetails.h b/src/app/tools/vtooluniondetails.h index 43e3dd014..e1c7bfc3a 100644 --- a/src/app/tools/vtooluniondetails.h +++ b/src/app/tools/vtooluniondetails.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtooluniondetails.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 26 12, 2013 ** ** @brief diff --git a/src/app/version.cpp b/src/app/version.cpp index 3f6cf8961..dd8ffccbc 100644 --- a/src/app/version.cpp +++ b/src/app/version.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file version.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 16 4, 2014 ** ** @brief diff --git a/src/app/version.h b/src/app/version.h index f5964d750..7ffb4371e 100644 --- a/src/app/version.h +++ b/src/app/version.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file version.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/doubledelegate.cpp b/src/app/widgets/doubledelegate.cpp index 596bbbd91..bce09af06 100644 --- a/src/app/widgets/doubledelegate.cpp +++ b/src/app/widgets/doubledelegate.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file doubledelegate.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/doubledelegate.h b/src/app/widgets/doubledelegate.h index f515b14cb..9d8c258a7 100644 --- a/src/app/widgets/doubledelegate.h +++ b/src/app/widgets/doubledelegate.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file doubledelegate.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/textdelegate.cpp b/src/app/widgets/textdelegate.cpp index 9fd9e9c43..e7c7ebad8 100644 --- a/src/app/widgets/textdelegate.cpp +++ b/src/app/widgets/textdelegate.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file textdelegate.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 29 1, 2014 ** ** @brief diff --git a/src/app/widgets/textdelegate.h b/src/app/widgets/textdelegate.h index c904e2223..ff05b52d1 100644 --- a/src/app/widgets/textdelegate.h +++ b/src/app/widgets/textdelegate.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file textdelegate.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 29 1, 2014 ** ** @brief diff --git a/src/app/widgets/vapplication.cpp b/src/app/widgets/vapplication.cpp index 45ecac5d6..e754ffc63 100644 --- a/src/app/widgets/vapplication.cpp +++ b/src/app/widgets/vapplication.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vapplication.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vapplication.h b/src/app/widgets/vapplication.h index c6a3ff14f..599d7e1c8 100644 --- a/src/app/widgets/vapplication.h +++ b/src/app/widgets/vapplication.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vapplication.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vcontrolpointspline.cpp b/src/app/widgets/vcontrolpointspline.cpp index 9f850ff44..6968f9459 100644 --- a/src/app/widgets/vcontrolpointspline.cpp +++ b/src/app/widgets/vcontrolpointspline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vcontrolpointspline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vcontrolpointspline.h b/src/app/widgets/vcontrolpointspline.h index 550420bfb..9a6745b59 100644 --- a/src/app/widgets/vcontrolpointspline.h +++ b/src/app/widgets/vcontrolpointspline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vcontrolpointspline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vgraphicssimpletextitem.cpp b/src/app/widgets/vgraphicssimpletextitem.cpp index 65c7a818f..10a8f01eb 100644 --- a/src/app/widgets/vgraphicssimpletextitem.cpp +++ b/src/app/widgets/vgraphicssimpletextitem.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vgraphicssimpletextitem.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vgraphicssimpletextitem.h b/src/app/widgets/vgraphicssimpletextitem.h index 4c6967a60..9593d0da8 100644 --- a/src/app/widgets/vgraphicssimpletextitem.h +++ b/src/app/widgets/vgraphicssimpletextitem.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vgraphicssimpletextitem.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vitem.cpp b/src/app/widgets/vitem.cpp index 698a1e1f2..561549b7f 100644 --- a/src/app/widgets/vitem.cpp +++ b/src/app/widgets/vitem.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vitem.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vitem.h b/src/app/widgets/vitem.h index 4822e0f4b..e30c12cdd 100644 --- a/src/app/widgets/vitem.h +++ b/src/app/widgets/vitem.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vitem.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vmaingraphicsscene.cpp b/src/app/widgets/vmaingraphicsscene.cpp index 047f86e16..f9d445ffe 100644 --- a/src/app/widgets/vmaingraphicsscene.cpp +++ b/src/app/widgets/vmaingraphicsscene.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vmaingraphicsscene.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vmaingraphicsscene.h b/src/app/widgets/vmaingraphicsscene.h index 87620d695..b32ab8470 100644 --- a/src/app/widgets/vmaingraphicsscene.h +++ b/src/app/widgets/vmaingraphicsscene.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vmaingraphicsscene.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vmaingraphicsview.cpp b/src/app/widgets/vmaingraphicsview.cpp index 2b972be03..017789898 100644 --- a/src/app/widgets/vmaingraphicsview.cpp +++ b/src/app/widgets/vmaingraphicsview.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vmaingraphicsview.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vmaingraphicsview.h b/src/app/widgets/vmaingraphicsview.h index 55cdfd648..7cf1c0ecf 100644 --- a/src/app/widgets/vmaingraphicsview.h +++ b/src/app/widgets/vmaingraphicsview.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vmaingraphicsview.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vsimplearc.cpp b/src/app/widgets/vsimplearc.cpp index 6427c4bf4..20e35aac6 100644 --- a/src/app/widgets/vsimplearc.cpp +++ b/src/app/widgets/vsimplearc.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsimplearc.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 7 1, 2014 ** ** @brief diff --git a/src/app/widgets/vsimplearc.h b/src/app/widgets/vsimplearc.h index 914e93daf..fcbfe2d90 100644 --- a/src/app/widgets/vsimplearc.h +++ b/src/app/widgets/vsimplearc.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsimplearc.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 7 1, 2014 ** ** @brief diff --git a/src/app/widgets/vsimplespline.cpp b/src/app/widgets/vsimplespline.cpp index 78136df83..2aa9d83fb 100644 --- a/src/app/widgets/vsimplespline.cpp +++ b/src/app/widgets/vsimplespline.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsimplespline.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 17 12, 2013 ** ** @brief diff --git a/src/app/widgets/vsimplespline.h b/src/app/widgets/vsimplespline.h index 05f2bc816..eb77e1b6e 100644 --- a/src/app/widgets/vsimplespline.h +++ b/src/app/widgets/vsimplespline.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsimplespline.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 17 12, 2013 ** ** @brief diff --git a/src/app/widgets/vsimplesplinepath.cpp b/src/app/widgets/vsimplesplinepath.cpp index ccf688c11..d73b71b52 100644 --- a/src/app/widgets/vsimplesplinepath.cpp +++ b/src/app/widgets/vsimplesplinepath.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsimplesplinepath.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 17 12, 2013 ** ** @brief diff --git a/src/app/widgets/vsimplesplinepath.h b/src/app/widgets/vsimplesplinepath.h index 6cb9df94b..a3c88f6aa 100644 --- a/src/app/widgets/vsimplesplinepath.h +++ b/src/app/widgets/vsimplesplinepath.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vsimplesplinepath.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 17 12, 2013 ** ** @brief diff --git a/src/app/widgets/vtablegraphicsview.cpp b/src/app/widgets/vtablegraphicsview.cpp index 2e99a518c..385fc26c8 100644 --- a/src/app/widgets/vtablegraphicsview.cpp +++ b/src/app/widgets/vtablegraphicsview.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtablegraphicsview.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/widgets/vtablegraphicsview.h b/src/app/widgets/vtablegraphicsview.h index abd79573a..ac826609d 100644 --- a/src/app/widgets/vtablegraphicsview.h +++ b/src/app/widgets/vtablegraphicsview.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtablegraphicsview.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/xml/vdomdocument.cpp b/src/app/xml/vdomdocument.cpp index a6994361c..0cb27e2eb 100644 --- a/src/app/xml/vdomdocument.cpp +++ b/src/app/xml/vdomdocument.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdomdocument.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/xml/vdomdocument.h b/src/app/xml/vdomdocument.h index cab334494..c2765254d 100644 --- a/src/app/xml/vdomdocument.h +++ b/src/app/xml/vdomdocument.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vdomdocument.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/xml/vindividualmeasurements.cpp b/src/app/xml/vindividualmeasurements.cpp index 0f9d62271..455f848b7 100644 --- a/src/app/xml/vindividualmeasurements.cpp +++ b/src/app/xml/vindividualmeasurements.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vindividualmeasurements.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 8 3, 2014 ** ** @brief diff --git a/src/app/xml/vindividualmeasurements.h b/src/app/xml/vindividualmeasurements.h index 7af71045e..d5894bd4a 100644 --- a/src/app/xml/vindividualmeasurements.h +++ b/src/app/xml/vindividualmeasurements.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vindividualmeasurements.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 8 3, 2014 ** ** @brief diff --git a/src/app/xml/vpattern.cpp b/src/app/xml/vpattern.cpp index 16e5b320d..ec8f0db9e 100644 --- a/src/app/xml/vpattern.cpp +++ b/src/app/xml/vpattern.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vpattern.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 24 2, 2014 ** ** @brief diff --git a/src/app/xml/vpattern.h b/src/app/xml/vpattern.h index 6a95f56fc..101e95002 100644 --- a/src/app/xml/vpattern.h +++ b/src/app/xml/vpattern.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vpattern.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 24 2, 2014 ** ** @brief diff --git a/src/app/xml/vstandardmeasurements.cpp b/src/app/xml/vstandardmeasurements.cpp index b61a373ef..cb96b7908 100644 --- a/src/app/xml/vstandardmeasurements.cpp +++ b/src/app/xml/vstandardmeasurements.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vstandardmeasurements.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 8 3, 2014 ** ** @brief diff --git a/src/app/xml/vstandardmeasurements.h b/src/app/xml/vstandardmeasurements.h index 2e23de685..d0e992eba 100644 --- a/src/app/xml/vstandardmeasurements.h +++ b/src/app/xml/vstandardmeasurements.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vstandardmeasurements.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date 8 3, 2014 ** ** @brief diff --git a/src/app/xml/vtoolrecord.cpp b/src/app/xml/vtoolrecord.cpp index ed6f0e756..6f5875037 100644 --- a/src/app/xml/vtoolrecord.cpp +++ b/src/app/xml/vtoolrecord.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolrecord.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/app/xml/vtoolrecord.h b/src/app/xml/vtoolrecord.h index edbe2aae6..52dd16603 100644 --- a/src/app/xml/vtoolrecord.h +++ b/src/app/xml/vtoolrecord.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file vtoolrecord.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 05744f952..2224dabc2 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 685fecd02..861325a5e 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparser_global.h b/src/libs/qmuparser/qmuparser_global.h index c20d95488..95202fc48 100644 --- a/src/libs/qmuparser/qmuparser_global.h +++ b/src/libs/qmuparser/qmuparser_global.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 0f46773c7..62a76871c 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 25ffdbd4a..9a1a9f522 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 495f7f6a0..ea3c46a17 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparserbytecode.h b/src/libs/qmuparser/qmuparserbytecode.h index 2f937d82b..f4ad3ce56 100644 --- a/src/libs/qmuparser/qmuparserbytecode.h +++ b/src/libs/qmuparser/qmuparserbytecode.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsercallback.cpp b/src/libs/qmuparser/qmuparsercallback.cpp index 0a1db5ac9..3d7d729b1 100644 --- a/src/libs/qmuparser/qmuparsercallback.cpp +++ b/src/libs/qmuparser/qmuparsercallback.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsercallback.h b/src/libs/qmuparser/qmuparsercallback.h index 3fce55943..2ebb4c5f3 100644 --- a/src/libs/qmuparser/qmuparsercallback.h +++ b/src/libs/qmuparser/qmuparsercallback.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 4a1abd67e..e7f5a4028 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index f0c2f4c11..571ae7241 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index 0bf9328d3..dd7592fc0 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparserfixes.h b/src/libs/qmuparser/qmuparserfixes.h index 1cabcda6d..be7056930 100644 --- a/src/libs/qmuparser/qmuparserfixes.h +++ b/src/libs/qmuparser/qmuparserfixes.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 16900978b..a5ed854a3 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 561bc3d2c..560b94420 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 7253e234c..f2f481c6a 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index c47d33851..a87f87548 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 48ea055be..8abf62de6 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -1,7 +1,7 @@ /*************************************************************************************************** ** ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhinsky + ** Modified work Copyright 2014 Roman Telezhynskyi ** ** Permission is hereby granted, free of charge, to any person obtaining a copy of this ** software and associated documentation files (the "Software"), to deal in the Software diff --git a/src/libs/qmuparser/stable.cpp b/src/libs/qmuparser/stable.cpp index 57b3c2027..243b23938 100644 --- a/src/libs/qmuparser/stable.cpp +++ b/src/libs/qmuparser/stable.cpp @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file stable.cpp - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief diff --git a/src/libs/qmuparser/stable.h b/src/libs/qmuparser/stable.h index d02111e92..ec80ff9ca 100644 --- a/src/libs/qmuparser/stable.h +++ b/src/libs/qmuparser/stable.h @@ -1,7 +1,7 @@ /************************************************************************ ** ** @file stable.h - ** @author Roman Telezhinsky + ** @author Roman Telezhynskyi ** @date November 15, 2013 ** ** @brief From 37ecf9fd868e68ffbcc514c74b2552edc28388b7 Mon Sep 17 00:00:00 2001 From: dismine Date: Thu, 1 May 2014 12:55:23 +0300 Subject: [PATCH 16/26] Fix gcc's warnings. --HG-- branch : feature --- src/libs/qmuparser/qmuparser.cpp | 23 +- src/libs/qmuparser/qmuparser.h | 2 +- src/libs/qmuparser/qmuparserbase.cpp | 662 ++++++++++++-- src/libs/qmuparser/qmuparserbase.h | 404 ++++----- src/libs/qmuparser/qmuparserbytecode.cpp | 356 +++++++- src/libs/qmuparser/qmuparsercallback.cpp | 188 ++-- src/libs/qmuparser/qmuparserdef.h | 2 +- src/libs/qmuparser/qmuparsererror.cpp | 30 +- src/libs/qmuparser/qmuparsererror.h | 3 +- src/libs/qmuparser/qmuparsertest.cpp | 23 +- src/libs/qmuparser/qmuparsertest.h | 16 +- src/libs/qmuparser/qmuparsertoken.h | 913 +++++++++++--------- src/libs/qmuparser/qmuparsertokenreader.cpp | 42 +- 13 files changed, 1829 insertions(+), 835 deletions(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 2224dabc2..0c7d38ea0 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -64,7 +64,7 @@ qreal QmuParser::ACosh(qreal v) qreal QmuParser::ATanh(qreal v) { - return ((qreal)0.5 * log((1 + v) / (1 - v))); + return (0.5 * log((1 + v) / (1 - v))); } //---------------------------------------------------------------------------------------------------------------------- // Logarithm functions @@ -78,7 +78,7 @@ qreal QmuParser::Log2(qreal v) throw QmuParserError(ecDOMAIN_ERROR, "Log2"); } #endif - return log(v)/log((qreal)2); + return log(v)/log(2.0); } // Logarithm base 10 @@ -102,12 +102,12 @@ qreal QmuParser::Abs(qreal v) qreal QmuParser::Rint(qreal v) { - return qFloor(v + (qreal)0.5); + return qFloor(v + 0.5); } qreal QmuParser::Sign(qreal v) { - return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0); + return ((v<0) ? -1 : (v>0) ? 1 : 0); } //---------------------------------------------------------------------------------------------------------------------- @@ -152,7 +152,7 @@ qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc) } qreal fRes=0; for (int i=0; i(a_iArgc); } //---------------------------------------------------------------------------------------------------------------------- @@ -218,12 +218,12 @@ int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) stream >> fVal; stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading - if (iEnd==(stringstream_type::pos_type)-1) + if (iEnd==static_cast(-1)) { return 0; } - *a_iPos += (int)iEnd; + *a_iPos += static_cast(iEnd); *a_fVal = fVal; return 1; } @@ -325,8 +325,11 @@ void QmuParser::InitOprt() } //---------------------------------------------------------------------------------------------------------------------- -void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) +void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) { + Q_UNUSED(pExpr); + Q_UNUSED(nStart); + Q_UNUSED(nEnd); // this is just sample code to illustrate modifying variable names on the fly. // I'm not sure anyone really needs such a feature... /* @@ -372,9 +375,9 @@ qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const // Backwards compatible calculation of epsilon inc case the user doesnt provide // his own epsilon - if (fEpsilon==0) + if (qFuzzyCompare(fEpsilon + 1, 1 + 0)) { - fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos; + fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast(1e-10) : static_cast(1e-7) * a_fPos; } *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 861325a5e..bb713ed76 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -51,7 +51,7 @@ namespace qmu virtual void InitFun(); virtual void InitConst(); virtual void InitOprt(); - virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); + virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; protected: static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 62a76871c..07ecfea7a 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -58,9 +58,9 @@ const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" < * @throw ParserException if a_szFormula is null. */ QmuParserBase::QmuParserBase() - :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(), - m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), - m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), + m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), + m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), m_nFinalResultIdx(0) { InitTokenReader(); @@ -73,9 +73,10 @@ QmuParserBase::QmuParserBase() * Tha parser can be safely copy constructed but the bytecode is reset during copy construction. */ QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) -:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(), - m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), - m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0) + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), + m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), + m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + m_nFinalResultIdx(0) { m_pTokenReader.reset(new token_reader_type(this)); Assign(a_Parser); @@ -216,8 +217,12 @@ void QmuParserBase::ReInit() const } //---------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) -{} +void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) +{ + Q_UNUSED(pExpr); + Q_UNUSED(nStart); + Q_UNUSED(nEnd); +} //---------------------------------------------------------------------------------------------------------------------- /** @@ -361,6 +366,108 @@ void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a case cmOPRT_INFIX: Error(ecINVALID_INFIX_IDENT, -1, a_sName); break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINVALID_NAME, -1, a_sName); break; @@ -660,6 +767,54 @@ int QmuParserBase::GetOprtPrecedence(const token_type &a_Tok) const case cmOPRT_INFIX: case cmOPRT_BIN: return a_Tok.GetPri(); + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINTERNAL_ERROR, 5); return 999; @@ -693,6 +848,69 @@ EOprtAssociativity QmuParserBase::GetOprtAssociativity(const token_type &a_Tok) return oaRIGHT; case cmOPRT_BIN: return a_Tok.GetAssociativity(); + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: return oaNONE; } @@ -888,30 +1106,122 @@ void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack & switch(funTok.GetCode()) { - case cmFUNC_STR: - stArg.push_back(a_stVal.pop()); + case cmFUNC_STR: + stArg.push_back(a_stVal.pop()); - if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) - { - Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); - } + if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); + } - ApplyStrFunc(funTok, stArg); - break; - case cmFUNC_BULK: - m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); - break; - case cmOPRT_BIN: - case cmOPRT_POSTFIX: - case cmOPRT_INFIX: - case cmFUNC: - if (funTok.GetArgCount()==-1 && iArgCount==0) - { - Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); - } + ApplyStrFunc(funTok, stArg); + break; + case cmFUNC_BULK: + m_vRPN.AddBulkFun(funTok.GetFuncAddr(), stArg.size()); + break; + case cmOPRT_BIN: + case cmOPRT_POSTFIX: + case cmOPRT_INFIX: + case cmFUNC: + if (funTok.GetArgCount()==-1 && iArgCount==0) + { + Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); + } - m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); - break; + m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); + break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + break; } // Push dummy value representing the function result to the stack token_type token; @@ -939,7 +1249,7 @@ void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack token_type vVal1 = a_stVal.pop(); token_type vExpr = a_stVal.pop(); - a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2); + a_stVal.push( (qFuzzyCompare(vExpr.GetVal()+1, 1+0)==false) ? vVal1 : vVal2); token_type opIf = a_stOpt.pop(); Q_ASSERT(opElse.GetCode()==cmELSE); @@ -1031,6 +1341,63 @@ void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStackOprt.ptr = Stack[sidx+1]; continue; - //case cmBO: // unused, listed for compiler optimization purposes - //case cmBC: + case cmBO: // unused, listed for compiler optimization purposes + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; case cmIF: - if (Stack[sidx--]==0) + if (qFuzzyCompare(Stack[sidx--]+1, 1+0)) { pTok += pTok->Oprt.offset; } @@ -1149,7 +1534,9 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const continue; case cmENDIF: continue; - //case cmARG_SEP: + case cmARG_SEP: + Q_UNREACHABLE(); + break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; @@ -1185,55 +1572,57 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const { case 0: sidx += 1; - Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(); continue; case 1: - Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx]); continue; case 2: sidx -= 1; - Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1]); continue; case 3: sidx -= 2; - Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2]); continue; case 4: sidx -= 3; - Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3]); continue; case 5: sidx -= 4; - Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; case 6: sidx -= 5; - Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; case 7: sidx -= 6; - Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; case 8: sidx -= 7; - Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7]); continue; case 9: sidx -= 8; - Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], - Stack[sidx+8]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7], Stack[sidx+8]); continue; case 10: sidx -= 9; - Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], - Stack[sidx+8], Stack[sidx+9]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue; default: if (iArgCount>0) // function with variable arguments store the number as a negative value @@ -1242,7 +1631,7 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const } sidx -= -iArgCount - 1; - Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount); + Stack[sidx] =(*reinterpret_cast(pTok->Fun.ptr))(&Stack[sidx], -iArgCount); continue; } } @@ -1253,25 +1642,27 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const // The index of the string argument in the string table int iIdxStack = pTok->Fun.idx; - Q_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() ); + Q_ASSERT( iIdxStack>=0 && iIdxStackFun.argc) // switch according to argument count { case 0: - Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack)); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack)); continue; case 1: - Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), + Stack[sidx]); continue; case 2: - Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx], - Stack[sidx+1]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), + Stack[sidx], Stack[sidx+1]); continue; + default: + break; } continue; } - case cmFUNC_BULK: { int iArgCount = pTok->Fun.argc; @@ -1281,59 +1672,61 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const { case 0: sidx += 1; - Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID); continue; case 1: - Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, + Stack[sidx]); continue; case 2: sidx -= 1; - Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue; case 3: sidx -= 2; - Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue; case 4: sidx -= 3; - Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue; case 5: sidx -= 4; - Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue; case 6: sidx -= 5; - Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue; case 7: sidx -= 6; - Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue; case 8: sidx -= 7; - Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue; case 9: sidx -= 8; - Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue; case 10: sidx -= 9; - Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, + Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); @@ -1343,16 +1736,30 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const continue; } } - //case cmSTRING: - //case cmOPRT_BIN: - //case cmOPRT_POSTFIX: - //case cmOPRT_INFIX: + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; - - //case cmEND: + case cmEND: + Q_UNREACHABLE(); + break; // return Stack[m_nFinalResultIdx]; - + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINTERNAL_ERROR, 3); return 0; @@ -1392,7 +1799,7 @@ void QmuParserBase::CreateRPN() const // Next three are different kind of value entries // case cmSTRING: - opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token + opt.SetIdx(m_vStringBuf.size()); // Assign buffer index to token stVal.push(opt); m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer break; @@ -1549,6 +1956,27 @@ void QmuParserBase::CreateRPN() const stOpt.push(opt); ApplyFunc(stOpt, stVal, 1); // this is the postfix operator break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: Error(ecINTERNAL_ERROR, 3); } // end of switch operator-token @@ -1634,7 +2062,7 @@ qreal QmuParserBase::ParseString() const * @param a_strTok [in] The token string representation associated with the error. * @throw ParserException always throws thats the only purpose of this function. */ -void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const +void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const { throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); } @@ -1882,6 +2310,72 @@ void QmuParserBase::StackDump(const QStack &a_stVal, const QStack - void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) - { - AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); - } - protected: - static const QStringList c_DefaultOprt; - static std::locale s_locale; ///< The locale used by the parser - static bool g_DbgDumpCmdCode; - static bool g_DbgDumpStack; - void Init(); - virtual void InitCharSets() = 0; - virtual void InitFun() = 0; - virtual void InitConst() = 0; - virtual void InitOprt() = 0; - virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd); - /** - * @brief A facet class used to change decimal and thousands separator. - */ - template - class change_dec_sep : public std::numpunct - { - public: - explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) - :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) - {} - protected: - virtual char_type do_decimal_point() const - { - return m_cDecPoint; - } + static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); + qreal Eval() const; + qreal* Eval(int &nStackSize) const; + void Eval(qreal *results, int nBulkSize); + int GetNumResults() const; + void SetExpr(const QString &a_sExpr); + void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); + void SetDecSep(char_type cDecSep); + void SetThousandsSep(char_type cThousandsSep = 0); + void ResetLocale(); + void EnableOptimizer(bool a_bIsOn=true); + void EnableBuiltInOprt(bool a_bIsOn=true); + bool HasBuiltInOprt() const; + void AddValIdent(identfun_type a_pCallback); + void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, + EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); + void DefineConst(const QString &a_sName, qreal a_fVal); + void DefineStrConst(const QString &a_sName, const QString &a_strVal); + void DefineVar(const QString &a_sName, qreal *a_fVar); + void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); + void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, + bool a_bAllowOpt=true); + // Clear user defined variables, constants or functions + void ClearVar(); + void ClearFun(); + void ClearConst(); + void ClearInfixOprt(); + void ClearPostfixOprt(); + void ClearOprt(); + void RemoveVar(const QString &a_strVarName); + const varmap_type& GetUsedVar() const; + const varmap_type& GetVar() const; + const valmap_type& GetConst() const; + const QString& GetExpr() const; + const funmap_type& GetFunDef() const; + QString GetVersion(EParserVersionInfo eInfo = pviFULL) const; + const QStringList& GetOprtDef() const; + void DefineNameChars(const QString &a_szCharset); + void DefineOprtChars(const QString &a_szCharset); + void DefineInfixOprtChars(const QString &a_szCharset); + const QString& ValidNameChars() const; + const QString& ValidOprtChars() const; + const QString& ValidInfixOprtChars() const; + void SetArgSep(char_type cArgSep); + QChar GetArgSep() const; + void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; + /** + * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, + * bool a_bAllowOpt = true) + * @brief Define a parser function without arguments. + * @param a_strName Name of the function + * @param a_pFun Pointer to the callback function + * @param a_bAllowOpt A flag indicating this function may be optimized + */ + template + void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) + { + AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); + } +protected: + static const QStringList c_DefaultOprt; + static std::locale s_locale; ///< The locale used by the parser + static bool g_DbgDumpCmdCode; + static bool g_DbgDumpStack; + void Init(); + virtual void InitCharSets() = 0; + virtual void InitFun() = 0; + virtual void InitConst() = 0; + virtual void InitOprt() = 0; + virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); + /** + * @brief A facet class used to change decimal and thousands separator. + */ + template + class change_dec_sep : public std::numpunct + { + public: + explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) + :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) + {} + protected: + virtual char_type do_decimal_point() const + { + return m_cDecPoint; + } - virtual char_type do_thousands_sep() const - { - return m_cThousandsSep; - } + virtual char_type do_thousands_sep() const + { + return m_cThousandsSep; + } - virtual std::string do_grouping() const - { - return std::string(1, m_nGroup); - } - private: - int m_nGroup; - char_type m_cDecPoint; - char_type m_cThousandsSep; - }; - private: - /** - * @brief Typedef for the parse functions. - * - * The parse function do the actual work. The parser exchanges - * the function pointer to the parser function depending on - * which state it is in. (i.e. bytecode parser vs. string parser) - */ - typedef qreal (QmuParserBase::*ParseFunction)() const; + virtual std::string do_grouping() const + { + return std::string(1, m_nGroup); + } + private: + int m_nGroup; + char_type m_cDecPoint; + char_type m_cThousandsSep; + }; +private: + /** + * @brief Typedef for the parse functions. + * + * The parse function do the actual work. The parser exchanges + * the function pointer to the parser function depending on + * which state it is in. (i.e. bytecode parser vs. string parser) + */ + typedef qreal (QmuParserBase::*ParseFunction)() const; - /** - * @brief Type used for storing an array of values. - */ - typedef QVector valbuf_type; + /** + * @brief Type used for storing an array of values. + */ + typedef QVector valbuf_type; - /** - * @brief Type for a vector of strings. - */ - typedef QVector stringbuf_type; + /** + * @brief Type for a vector of strings. + */ + typedef QVector stringbuf_type; - /** - * @brief Typedef for the token reader. - */ - typedef QmuParserTokenReader token_reader_type; + /** + * @brief Typedef for the token reader. + */ + typedef QmuParserTokenReader token_reader_type; - /** - * @brief Type used for parser tokens. - */ - typedef QmuParserToken token_type; + /** + * @brief Type used for parser tokens. + */ + typedef QmuParserToken token_type; - /** - * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. - */ - static const int s_MaxNumOpenMPThreads = 4; + /** + * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. + */ + static const int s_MaxNumOpenMPThreads = 4; - /** - * @brief Pointer to the parser function. - * - * Eval() calls the function whose address is stored there. - */ - mutable ParseFunction m_pParseFormula; - mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. - mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments - stringbuf_type m_vStringVarBuf; + /** + * @brief Pointer to the parser function. + * + * Eval() calls the function whose address is stored there. + */ + mutable ParseFunction m_pParseFormula; + mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. + mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments + stringbuf_type m_vStringVarBuf; - std::auto_ptr m_pTokenReader; ///< Managed pointer to the token reader object. + std::unique_ptr m_pTokenReader; ///< Managed pointer to the token reader object. - funmap_type m_FunDef; ///< Map of function names and pointers. - funmap_type m_PostOprtDef; ///< Postfix operator callbacks - funmap_type m_InfixOprtDef; ///< unary infix operator. - funmap_type m_OprtDef; ///< Binary operator callbacks - valmap_type m_ConstDef; ///< user constants. - strmap_type m_StrVarDef; ///< user defined string constants - varmap_type m_VarDef; ///< user defind variables. + funmap_type m_FunDef; ///< Map of function names and pointers. + funmap_type m_PostOprtDef; ///< Postfix operator callbacks + funmap_type m_InfixOprtDef; ///< unary infix operator. + funmap_type m_OprtDef; ///< Binary operator callbacks + valmap_type m_ConstDef; ///< user constants. + strmap_type m_StrVarDef; ///< user defined string constants + varmap_type m_VarDef; ///< user defind variables. - bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off + bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off - QString m_sNameChars; ///< Charset for names - QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens - QString m_sInfixOprtChars; ///< Charset for infix operator tokens + QString m_sNameChars; ///< Charset for names + QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens + QString m_sInfixOprtChars; ///< Charset for infix operator tokens - mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses + mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses - // items merely used for caching state information - mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine - mutable int m_nFinalResultIdx; + // items merely used for caching state information + mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine + mutable int m_nFinalResultIdx; - void Assign(const QmuParserBase &a_Parser); - void InitTokenReader(); - void ReInit() const; - void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, - funmap_type &a_Storage, const QString &a_szCharSet ); - void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; - token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; - int GetOprtPrecedence(const token_type &a_Tok) const; - EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; - void CreateRPN() const; - qreal ParseString() const; - qreal ParseCmdCode() const; - qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; - void CheckName(const QString &a_strName, const QString &a_CharSet) const; - void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const QString &a_szCharSet) const; - void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; - }; + void Assign(const QmuParserBase &a_Parser); + void InitTokenReader(); + void ReInit() const; + void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, + funmap_type &a_Storage, const QString &a_szCharSet ); + void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; + token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; + int GetOprtPrecedence(const token_type &a_Tok) const; + EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; + void CreateRPN() const; + qreal ParseString() const; + qreal ParseCmdCode() const; + qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; + void CheckName(const QString &a_strName, const QString &a_CharSet) const; + void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, + const QString &a_szCharSet) const; + void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; +}; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index ea3c46a17..80e6822ea 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -52,6 +52,8 @@ QmuParserByteCode::QmuParserByteCode() * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) */ QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) + :m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN), + m_bEnableOptimizer(true) { Assign(a_ByteCode); } @@ -101,7 +103,7 @@ void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) void QmuParserByteCode::AddVar(qreal *a_pVar) { ++m_iStackPos; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); // optimization does not apply SToken tok; @@ -129,7 +131,7 @@ void QmuParserByteCode::AddVar(qreal *a_pVar) void QmuParserByteCode::AddVal(qreal a_fVal) { ++m_iStackPos; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); // If optimization does not apply SToken tok; @@ -145,15 +147,15 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) { std::size_t sz = m_vRPN.size(); qreal &x = m_vRPN[sz-2].Val.data2, - &y = m_vRPN[sz-1].Val.data2; + &y = m_vRPN[sz-1].Val.data2; switch (a_Oprt) { case cmLAND: - x = (int)x && (int)y; + x = static_cast(x) && static_cast(y); m_vRPN.pop_back(); break; case cmLOR: - x = (int)x || (int)y; + x = static_cast(x) || static_cast(y); m_vRPN.pop_back(); break; case cmLT: @@ -173,11 +175,11 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) m_vRPN.pop_back(); break; case cmNEQ: - x = x != y; + x = (qFuzzyCompare(x, y) == false); m_vRPN.pop_back(); break; case cmEQ: - x = x == y; + x = qFuzzyCompare(x, y); m_vRPN.pop_back(); break; case cmADD: @@ -202,10 +204,79 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) x = x / y; m_vRPN.pop_back(); break; - case cmPOW: - x = qPow(x, y); - m_vRPN.pop_back(); - break; + case cmPOW: + x = qPow(x, y); + m_vRPN.pop_back(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; default: break; } // switch opcode @@ -248,15 +319,15 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) // Optimization for ploynomials of low order if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) { - if (m_vRPN[sz-1].Val.data2==2) + if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 2)) { m_vRPN[sz-2].Cmd = cmVARPOW2; } - else if (m_vRPN[sz-1].Val.data2==3) + else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 3)) { m_vRPN[sz-2].Cmd = cmVARPOW3; } - else if (m_vRPN[sz-1].Val.data2==4) + else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 4)) { m_vRPN[sz-2].Cmd = cmVARPOW4; } @@ -291,8 +362,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | - (long long)(m_vRPN[sz-1].Val.ptr)); // variable + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); // variable m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior m_vRPN.pop_back(); @@ -304,8 +376,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) { m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | - (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; m_vRPN[sz-2].Val.data2 = 0; m_vRPN.pop_back(); @@ -316,8 +389,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) { // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | - (long long)(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); if (m_vRPN[sz-1].Cmd == cmVAL) { m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; @@ -341,7 +415,8 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) } break; case cmDIV: - if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0) + if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && + (qFuzzyCompare(m_vRPN[sz-1].Val.data2+1, 1+0)==false)) { // Optimization: 4*a/2 -> 2*a m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; @@ -350,8 +425,103 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) bOptimized = true; } break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + break; - } // switch a_Oprt + } // switch a_Oprt } } @@ -413,7 +583,7 @@ void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) // function with unlimited number of arguments m_iStackPos = m_iStackPos + a_iArgc + 1; } - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); SToken tok; tok.Cmd = cmFUNC; @@ -432,7 +602,7 @@ void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) { m_iStackPos = m_iStackPos - a_iArgc + 1; - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); SToken tok; tok.Cmd = cmFUNC_BULK; @@ -460,7 +630,7 @@ void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iI tok.Fun.ptr = a_pFun; m_vRPN.push_back(tok); - m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); } //---------------------------------------------------------------------------------------------------------------------- @@ -479,7 +649,7 @@ void QmuParserByteCode::Finalize() // Determine the if-then-else jump offsets QStack stIf, stElse; int idx; - for (int i=0; i<(int)m_vRPN.size(); ++i) + for (int i=0; i ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), m_iCode ( a_iCode ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), + m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} @@ -47,9 +54,12 @@ QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int * @brief Constructor for constructing funcstion callbacks taking two arguments. * @throw nothrow */ +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- @@ -61,72 +71,105 @@ QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) * @param a_eOprtAsct The operators associativity * @throw nothrow */ +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eOprtAsct ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- @@ -134,81 +177,120 @@ QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) * @brief Constructor for constructing funcstion callbacks taking two arguments. * @throw nothrow */ +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ), - m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), - m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- +#ifdef __GNUC__ +__extension__ +#endif QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ), - m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} //---------------------------------------------------------------------------------------------------------------------- @@ -227,6 +309,8 @@ QmuParserCallback::QmuParserCallback() * @throw nothrow */ QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref ) + : m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ), + m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti ) { m_pFun = ref.m_pFun; m_iArgc = ref.m_iArgc; diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index e7f5a4028..4edd3f390 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -44,7 +44,7 @@ OpenMP is used only in the bulk mode it may increase the performance a bit. */ -//#define MUP_USE_OPENMP +//#define QMUP_USE_OPENMP #if defined(_UNICODE) /** @brief Definition of the basic parser string type. */ diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 571ae7241..543d60d9f 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -37,27 +37,13 @@ const QmuParserErrorMsg& QmuParserErrorMsg::Instance() //---------------------------------------------------------------------------------------------------------------------- QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const { - return ( a_iIdx < m_vErrMsg.size() ) ? m_vErrMsg[a_iIdx] : QString(); + return ( a_iIdx < static_cast( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString(); } //---------------------------------------------------------------------------------------------------------------------- QmuParserErrorMsg::~QmuParserErrorMsg() {} -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Assignement operator is deactivated. - */ -QmuParserErrorMsg& QmuParserErrorMsg::operator= ( const QmuParserErrorMsg& ) -{ - assert ( false ); - return *this; -} - -//---------------------------------------------------------------------------------------------------------------------- -QmuParserErrorMsg::QmuParserErrorMsg ( const QmuParserErrorMsg& ) -{} - //---------------------------------------------------------------------------------------------------------------------- QmuParserErrorMsg::QmuParserErrorMsg() : m_vErrMsg ( 0 ) @@ -147,11 +133,9 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) * @brief Construct an error from a message text. */ QmuParserError::QmuParserError ( const QString &sMsg ) - : m_ErrMsg ( QmuParserErrorMsg::Instance() ) -{ - Reset(); - m_strMsg = sMsg; -} + : m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) +{} //---------------------------------------------------------------------------------------------------------------------- /** @@ -264,9 +248,9 @@ void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFi */ void QmuParserError::Reset() { - m_strMsg = ""; - m_strFormula = ""; - m_strTok = ""; + m_strMsg.clear(); + m_strFormula.clear(); + m_strTok.clear(); m_iPos = -1; m_iErrc = ecUNDEFINED; } diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index dd7592fc0..0ed154df6 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -99,8 +99,6 @@ class QmuParserErrorMsg public: typedef QmuParserErrorMsg self_type; - QmuParserErrorMsg& operator= ( const QmuParserErrorMsg & ); - QmuParserErrorMsg ( const QmuParserErrorMsg& ); QmuParserErrorMsg(); ~QmuParserErrorMsg(); @@ -108,6 +106,7 @@ public: QString operator[] ( unsigned a_iIdx ) const; private: + Q_DISABLE_COPY(QmuParserErrorMsg) QVector m_vErrMsg; ///< A vector with the predefined error messages static const self_type m_Instance; ///< The instance pointer }; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index a5ed854a3..fa6fcb4b1 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -81,8 +81,8 @@ int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_f return 1; } - *a_iPos += ( int ) ( 2 + nPos ); - *a_fVal = ( qreal ) iVal; + *a_iPos += 2 + nPos; + *a_fVal = static_cast(iVal); return 1; } else @@ -460,7 +460,7 @@ int QmuParserTester::TestVarConst() // 4 used variables p.SetExpr ( "a+b+c+d" ); qmu::varmap_type UsedVar = p.GetUsedVar(); - int iCount = ( int ) UsedVar.size(); + int iCount = static_cast(UsedVar.size()); if ( iCount != 4 ) { throw false; @@ -485,7 +485,7 @@ int QmuParserTester::TestVarConst() // Test lookup of undefined variables p.SetExpr ( "undef1+undef2+undef3" ); UsedVar = p.GetUsedVar(); - iCount = ( int ) UsedVar.size(); + iCount = static_cast(UsedVar.size()); if ( iCount != 3 ) { throw false; @@ -509,7 +509,7 @@ int QmuParserTester::TestVarConst() // 1 used variables p.SetExpr ( "a+b" ); UsedVar = p.GetUsedVar(); - iCount = ( int ) UsedVar.size(); + iCount = static_cast(UsedVar.size()); if ( iCount != 2 ) { throw false; @@ -1072,7 +1072,7 @@ void QmuParserTester::Run() int iStat = 0; try { - for ( int i = 0; i < ( int ) m_vTestFun.size(); ++i ) + for ( int i = 0; i < m_vTestFun.size(); ++i ) { iStat += ( this->*m_vTestFun[i] ) (); } @@ -1227,7 +1227,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass try { - std::auto_ptr p1; + std::unique_ptr p1; QmuParser p2, p3; // three parser objects // they will be used for testing copy and assihnment operators // p1 is a pointer since i'm going to delete it in order to test if @@ -1306,7 +1306,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass // String parsing and bytecode parsing must yield the same result fVal[0] = p1->Eval(); // result from stringparsing fVal[1] = p1->Eval(); // result from bytecode - if ( fVal[0] != fVal[1] ) + if ( qFuzzyCompare( fVal[0], fVal[1] ) == false ) { throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); } @@ -1354,7 +1354,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825 if ( numeric_limits::has_infinity ) { - bCloseEnough &= ( fabs ( fVal[i] ) != numeric_limits::infinity() ); + bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), numeric_limits::infinity())==false ); } } @@ -1376,7 +1376,8 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass { if ( a_fPass ) { - if ( fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998 ) + if ( (qFuzzyCompare(fVal[0], fVal[2])==false) && (qFuzzyCompare(fVal[0], -999)==false) && + (qFuzzyCompare(fVal[1], -998 )==false)) { qDebug() << "\n fail: " << a_str << " (copy construction)"; } @@ -1405,7 +1406,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass /** * @brief Internal error in test class Test is going to be aborted. */ -void QmuParserTester::Abort() const +void Q_NORETURN QmuParserTester::Abort() const { qDebug() << "Test failed (internal error in test class)" ; while ( !getchar() ); diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 560b94420..aaf5ab48d 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -178,7 +178,7 @@ private: static qreal land ( qreal v1, qreal v2 ) { - return ( int ) v1 & ( int ) v2; + return static_cast( v1 ) & static_cast( v2 ); } static qreal FirstArg ( const qreal* a_afArg, int a_iArgc ) @@ -218,12 +218,12 @@ private: static qreal Rnd ( qreal v ) { - return ( qreal ) ( 1 + ( v * std::rand() / ( RAND_MAX + 1.0 ) ) ); + return static_cast( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) ); } static qreal RndWithString ( const char_type* ) { - return ( qreal ) ( 1 + ( 1000.0f * std::rand() / ( RAND_MAX + 1.0 ) ) ); + return static_cast( ( 1 + ( 1000.0f * static_cast(qrand()) / ( RAND_MAX + 1.0 ) ) ) ); } static qreal Ping() @@ -239,13 +239,13 @@ private: static qreal StrFun1 ( const QString & v1 ) { int val = v1.toInt(); - return ( qreal ) val; + return static_cast(val); } static qreal StrFun2 ( const QString & v1, qreal v2 ) { int val = v1.toInt(); - return ( qreal ) ( val + v2 ); + return static_cast( val + v2 ); } static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 ) @@ -263,17 +263,17 @@ private: // postfix operator callback static qreal Mega ( qreal a_fVal ) { - return a_fVal * ( qreal ) 1e6; + return a_fVal * static_cast( 1e6 ); } static qreal Micro ( qreal a_fVal ) { - return a_fVal * ( qreal ) 1e-6; + return a_fVal * static_cast( 1e-6 ); } static qreal Milli ( qreal a_fVal ) { - return a_fVal / ( qreal ) 1e3; + return a_fVal / static_cast( 1e3 ); } // Custom value recognition diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index f2f481c6a..a1ef34a13 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -1,396 +1,517 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERTOKEN_H -#define QMUPARSERTOKEN_H - -#include -#include -#include -#include -#include - -#include "qmuparsererror.h" -#include "qmuparsercallback.h" - -/** @file - @brief This file contains the parser token definition. -*/ - -namespace qmu -{ - /** @brief Encapsulation of the data for a single formula token. - - Formula token implementation. Part of the Math Parser Package. - Formula tokens can be either one of the following: -
      -
    • value
    • -
    • variable
    • -
    • function with numerical arguments
    • -
    • functions with a string as argument
    • -
    • prefix operators
    • -
    • infix operators
    • -
    • binary operator
    • -
    - - @author (C) 2004-2013 Ingo Berg - */ - template - class QmuParserToken - { - private: - - ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. - ETypeCode m_iType; - void *m_pTok; ///< Stores Token pointer; not applicable for all tokens - int m_iIdx; ///< An otional index to an external buffer storing the token data - TString m_strTok; ///< Token string - TString m_strVal; ///< Value for string variables - qreal m_fVal; ///< the value - std::auto_ptr m_pCallback; - - public: - - //--------------------------------------------------------------------------- - /** @brief Constructor (default). - - Sets token to an neutral state of type cmUNKNOWN. - @throw nothrow - @sa ECmdCode - */ - QmuParserToken() - :m_iCode(cmUNKNOWN) - ,m_iType(tpVOID) - ,m_pTok(0) - ,m_iIdx(-1) - ,m_strTok() - ,m_pCallback() - {} - - //------------------------------------------------------------------------------ - /** @brief Create token from another one. - - Implemented by calling Assign(...) - @throw nothrow - @post m_iType==cmUNKNOWN - @sa #Assign - */ - QmuParserToken(const QmuParserToken &a_Tok) - { - Assign(a_Tok); - } - - //------------------------------------------------------------------------------ - /** @brief Assignement operator. - - Copy token state from another token and return this. - Implemented by calling Assign(...). - @throw nothrow - */ - QmuParserToken& operator=(const QmuParserToken &a_Tok) - { - Assign(a_Tok); - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Copy token information from argument. - - @throw nothrow - */ - void Assign(const QmuParserToken &a_Tok) - { - m_iCode = a_Tok.m_iCode; - m_pTok = a_Tok.m_pTok; - m_strTok = a_Tok.m_strTok; - m_iIdx = a_Tok.m_iIdx; - m_strVal = a_Tok.m_strVal; - m_iType = a_Tok.m_iType; - m_fVal = a_Tok.m_fVal; - // create new callback object if a_Tok has one - m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0); - } - - //------------------------------------------------------------------------------ - /** @brief Assign a token type. - - Token may not be of type value, variable or function. Those have seperate set functions. - - \pre [assert] a_iType!=cmVAR - \pre [assert] a_iType!=cmVAL - \pre [assert] a_iType!=cmFUNC - @post m_fVal = 0 - @post m_pTok = 0 - */ - QmuParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString()) - { - // The following types cant be set this way, they have special Set functions - assert(a_iType!=cmVAR); - assert(a_iType!=cmVAL); - assert(a_iType!=cmFUNC); - - m_iCode = a_iType; - m_iType = tpVOID; - m_pTok = 0; - m_strTok = a_strTok; - m_iIdx = -1; - - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Set Callback type. */ - QmuParserToken& Set(const QmuParserCallback &a_pCallback, const TString &a_sTok) - { - assert(a_pCallback.GetAddr()); - - m_iCode = a_pCallback.GetCode(); - m_iType = tpVOID; - m_strTok = a_sTok; - m_pCallback.reset(new QmuParserCallback(a_pCallback)); - - m_pTok = 0; - m_iIdx = -1; - - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Make this token a value token. - - Member variables not necessary for value tokens will be invalidated. - @throw nothrow - */ - QmuParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString()) - { - m_iCode = cmVAL; - m_iType = tpDBL; - m_fVal = a_fVal; - m_strTok = a_strTok; - m_iIdx = -1; - - m_pTok = 0; - m_pCallback.reset(0); - - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief make this token a variable token. - - Member variables not necessary for variable tokens will be invalidated. - @throw nothrow - */ - QmuParserToken& SetVar(TBase *a_pVar, const TString &a_strTok) - { - m_iCode = cmVAR; - m_iType = tpDBL; - m_strTok = a_strTok; - m_iIdx = -1; - m_pTok = (void*)a_pVar; - m_pCallback.reset(0); - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Make this token a variable token. - - Member variables not necessary for variable tokens will be invalidated. - @throw nothrow - */ - QmuParserToken& SetString(const TString &a_strTok, std::size_t a_iSize) - { - m_iCode = cmSTRING; - m_iType = tpSTR; - m_strTok = a_strTok; - m_iIdx = static_cast(a_iSize); - - m_pTok = 0; - m_pCallback.reset(0); - return *this; - } - - //------------------------------------------------------------------------------ - /** @brief Set an index associated with the token related data. - - In cmSTRFUNC - This is the index to a string table in the main parser. - * @param a_iIdx The index the string function result will take in the bytecode parser. - @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING - */ - void SetIdx(int a_iIdx) - { - if (m_iCode!=cmSTRING || a_iIdx<0) - throw QmuParserError(ecINTERNAL_ERROR); - - m_iIdx = a_iIdx; - } - - //------------------------------------------------------------------------------ - /** @brief Return Index associated with the token related data. - - In cmSTRFUNC - This is the index to a string table in the main parser. - - @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING - * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). - */ - int GetIdx() const - { - if (m_iIdx<0 || m_iCode!=cmSTRING ) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_iIdx; - } - - //------------------------------------------------------------------------------ - /** @brief Return the token type. - - * @return #m_iType - @throw nothrow - */ - ECmdCode GetCode() const - { - if (m_pCallback.get()) - { - return m_pCallback->GetCode(); - } - else - { - return m_iCode; - } - } - - //------------------------------------------------------------------------------ - ETypeCode GetType() const - { - if (m_pCallback.get()) - { - return m_pCallback->GetType(); - } - else - { - return m_iType; - } - } - - //------------------------------------------------------------------------------ - int GetPri() const - { - if ( !m_pCallback.get()) - throw QmuParserError(ecINTERNAL_ERROR); - - if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_pCallback->GetPri(); - } - - //------------------------------------------------------------------------------ - EOprtAssociativity GetAssociativity() const - { - if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_pCallback->GetAssociativity(); - } - - //------------------------------------------------------------------------------ - /** @brief Return the address of the callback function assoziated with - function and operator tokens. - - * @return The pointer stored in #m_pTok. - @throw exception_type if token type is non of: -
      -
    • cmFUNC
    • -
    • cmSTRFUNC
    • -
    • cmPOSTOP
    • -
    • cmINFIXOP
    • -
    • cmOPRT_BIN
    • -
    - @sa ECmdCode - */ - generic_fun_type GetFuncAddr() const - { - return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0; - } - - //------------------------------------------------------------------------------ - /** \biref Get value of the token. - - Only applicable to variable and value tokens. - @throw exception_type if token is no value/variable token. - */ - TBase GetVal() const - { - switch (m_iCode) - { - case cmVAL: return m_fVal; - case cmVAR: return *((TBase*)m_pTok); - default: throw QmuParserError(ecVAL_EXPECTED); - } - } - - //------------------------------------------------------------------------------ - /** @brief Get address of a variable token. - - Valid only if m_iType==CmdVar. - @throw exception_type if token is no variable token. - */ - TBase* GetVar() const - { - if (m_iCode!=cmVAR) - throw QmuParserError(ecINTERNAL_ERROR); - - return (TBase*)m_pTok; - } - - //------------------------------------------------------------------------------ - /** @brief Return the number of function arguments. - - Valid only if m_iType==CmdFUNC. - */ - int GetArgCount() const - { - assert(m_pCallback.get()); - - if (!m_pCallback->GetAddr()) - throw QmuParserError(ecINTERNAL_ERROR); - - return m_pCallback->GetArgc(); - } - - //------------------------------------------------------------------------------ - /** @brief Return the token identifier. - - If #m_iType is cmSTRING the token identifier is the value of the string argument - for a string function. - * @return #m_strTok - @throw nothrow - @sa m_strTok - */ - const TString& GetAsString() const - { - return m_strTok; - } - }; -} // namespace qmu - -#endif +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTOKEN_H +#define QMUPARSERTOKEN_H + +#include +#include +#include +#include +#include + +#include "qmuparsererror.h" +#include "qmuparsercallback.h" + +/** @file + @brief This file contains the parser token definition. +*/ + +namespace qmu +{ +/** + * @brief Encapsulation of the data for a single formula token. + * + * Formula token implementation. Part of the Math Parser Package. + * Formula tokens can be either one of the following: + *
      + *
    • value
    • + *
    • variable
    • + *
    • function with numerical arguments
    • + *
    • functions with a string as argument
    • + *
    • prefix operators
    • + *
    • infix operators
    • + *
    • binary operator
    • + *
    + * + * @author (C) 2004-2013 Ingo Berg + */ +template +class QmuParserToken +{ +public: + //--------------------------------------------------------------------------- + /** + * @brief Constructor (default). + * + * Sets token to an neutral state of type cmUNKNOWN. + * @throw nothrow + * @sa ECmdCode + */ + QmuParserToken() + : m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(), + m_pCallback() + {} + + //------------------------------------------------------------------------------ + /** + * @brief Create token from another one. + * + * Implemented by calling Assign(...) + * @throw nothrow + * @post m_iType==cmUNKNOWN + * @sa #Assign + */ + QmuParserToken ( const QmuParserToken &a_Tok ) + : m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ), + m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback() + { + Assign ( a_Tok ); + } + + //------------------------------------------------------------------------------ + /** + * @brief Assignement operator. + * + * Copy token state from another token and return this. + * Implemented by calling Assign(...). + * @throw nothrow + */ + QmuParserToken& operator= ( const QmuParserToken &a_Tok ) + { + Assign ( a_Tok ); + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Copy token information from argument. + * + * @throw nothrow + */ + void Assign ( const QmuParserToken &a_Tok ) + { + m_iCode = a_Tok.m_iCode; + m_pTok = a_Tok.m_pTok; + m_strTok = a_Tok.m_strTok; + m_iIdx = a_Tok.m_iIdx; + m_strVal = a_Tok.m_strVal; + m_iType = a_Tok.m_iType; + m_fVal = a_Tok.m_fVal; + // create new callback object if a_Tok has one + m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 ); + } + + //------------------------------------------------------------------------------ + /** + * @brief Assign a token type. + * + * Token may not be of type value, variable or function. Those have seperate set functions. + * + * @pre [assert] a_iType!=cmVAR + * @pre [assert] a_iType!=cmVAL + * @pre [assert] a_iType!=cmFUNC + * @post m_fVal = 0 + * @post m_pTok = 0 + */ + QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() ) + { + // The following types cant be set this way, they have special Set functions + assert ( a_iType != cmVAR ); + assert ( a_iType != cmVAL ); + assert ( a_iType != cmFUNC ); + + m_iCode = a_iType; + m_iType = tpVOID; + m_pTok = 0; + m_strTok = a_strTok; + m_iIdx = -1; + + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Set Callback type. + */ + QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok ) + { + assert ( a_pCallback.GetAddr() ); + + m_iCode = a_pCallback.GetCode(); + m_iType = tpVOID; + m_strTok = a_sTok; + m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) ); + + m_pTok = 0; + m_iIdx = -1; + + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Make this token a value token. + * + * Member variables not necessary for value tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() ) + { + m_iCode = cmVAL; + m_iType = tpDBL; + m_fVal = a_fVal; + m_strTok = a_strTok; + m_iIdx = -1; + + m_pTok = 0; + m_pCallback.reset ( 0 ); + + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief make this token a variable token. + * + * Member variables not necessary for variable tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok ) + { + m_iCode = cmVAR; + m_iType = tpDBL; + m_strTok = a_strTok; + m_iIdx = -1; + m_pTok = reinterpret_cast ( a_pVar ); + m_pCallback.reset ( 0 ); + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Make this token a variable token. + * + * Member variables not necessary for variable tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize ) + { + m_iCode = cmSTRING; + m_iType = tpSTR; + m_strTok = a_strTok; + m_iIdx = static_cast ( a_iSize ); + + m_pTok = 0; + m_pCallback.reset ( 0 ); + return *this; + } + + //------------------------------------------------------------------------------ + /** + * @brief Set an index associated with the token related data. + * + * In cmSTRFUNC - This is the index to a string table in the main parser. + * @param a_iIdx The index the string function result will take in the bytecode parser. + * @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING + */ + void SetIdx ( int a_iIdx ) + { + if ( m_iCode != cmSTRING || a_iIdx < 0 ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + m_iIdx = a_iIdx; + } + + //------------------------------------------------------------------------------ + /** + * @brief Return Index associated with the token related data. + * + * In cmSTRFUNC - This is the index to a string table in the main parser. + * + * @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING + * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). + */ + int GetIdx() const + { + if ( m_iIdx < 0 || m_iCode != cmSTRING ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_iIdx; + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the token type. + * + * @return #m_iType + * @throw nothrow + */ + ECmdCode GetCode() const + { + if ( m_pCallback.get() ) + { + return m_pCallback->GetCode(); + } + else + { + return m_iCode; + } + } + + //------------------------------------------------------------------------------ + ETypeCode GetType() const + { + if ( m_pCallback.get() ) + { + return m_pCallback->GetType(); + } + else + { + return m_iType; + } + } + + //------------------------------------------------------------------------------ + int GetPri() const + { + if ( !m_pCallback.get() ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_pCallback->GetPri(); + } + + //------------------------------------------------------------------------------ + EOprtAssociativity GetAssociativity() const + { + if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_pCallback->GetAssociativity(); + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the address of the callback function assoziated with function and operator tokens. + * + * @return The pointer stored in #m_pTok. + * @throw exception_type if token type is non of: + *
      + *
    • cmFUNC
    • + *
    • cmSTRFUNC
    • + *
    • cmPOSTOP
    • + *
    • cmINFIXOP
    • + *
    • cmOPRT_BIN
    • + *
    + * @sa ECmdCode + */ + generic_fun_type GetFuncAddr() const + { + return ( m_pCallback.get() ) ? reinterpret_cast ( m_pCallback->GetAddr() ) : + reinterpret_cast (0); + } + + //------------------------------------------------------------------------------ + /** + * @brief Get value of the token. + * + * Only applicable to variable and value tokens. + * @throw exception_type if token is no value/variable token. + */ + TBase GetVal() const + { + switch ( m_iCode ) + { + case cmVAL: + return m_fVal; + case cmVAR: + return * ( reinterpret_cast(m_pTok) ); + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + throw QmuParserError ( ecVAL_EXPECTED ); + } + } + + //------------------------------------------------------------------------------ + /** + * @brief Get address of a variable token. + * + * Valid only if m_iType==CmdVar. + * @throw exception_type if token is no variable token. + */ + TBase* GetVar() const + { + if ( m_iCode != cmVAR ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } + + return reinterpret_cast( m_pTok ); + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the number of function arguments. + * + * Valid only if m_iType==CmdFUNC. + */ + int GetArgCount() const + { + assert ( m_pCallback.get() ); + + if ( !m_pCallback->GetAddr() ) + throw QmuParserError ( ecINTERNAL_ERROR ); + + return m_pCallback->GetArgc(); + } + + //------------------------------------------------------------------------------ + /** + * @brief Return the token identifier. + * + * If #m_iType is cmSTRING the token identifier is the value of the string argument + * for a string function. + * @return #m_strTok + * @throw nothrow + * @sa m_strTok + */ + const TString& GetAsString() const + { + return m_strTok; + } +private: + ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. + ETypeCode m_iType; + void *m_pTok; ///< Stores Token pointer; not applicable for all tokens + int m_iIdx; ///< An otional index to an external buffer storing the token data + TString m_strTok; ///< Token string + TString m_strVal; ///< Value for string variables + qreal m_fVal; ///< the value + std::unique_ptr m_pCallback; +}; +} // namespace qmu + +#endif diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index a87f87548..6ba7a541d 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -44,9 +44,15 @@ class QmuParserBase; * @throw nothrow */ QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader ) -{ - Assign ( a_Reader ); -} + :m_pParser( a_Reader.m_pParser ), m_strFormula( a_Reader.m_strFormula ), m_iPos( a_Reader.m_iPos ), + m_iSynFlags( a_Reader.m_iSynFlags ), m_bIgnoreUndefVar( a_Reader.m_bIgnoreUndefVar ), + m_pFunDef( a_Reader.m_pFunDef ), m_pPostOprtDef( a_Reader.m_pPostOprtDef ), + m_pInfixOprtDef( a_Reader.m_pInfixOprtDef ), m_pOprtDef( a_Reader.m_pOprtDef), + m_pConstDef( a_Reader.m_pConstDef ), m_pStrVarDef( a_Reader.m_pStrVarDef ), m_pVarDef( a_Reader.m_pVarDef ), + m_pFactory( a_Reader.m_pFactory ), m_pFactoryData( a_Reader.m_pFactoryData ), m_vIdentFun( a_Reader.m_vIdentFun ), + m_UsedVar( a_Reader.m_UsedVar ), m_fZero(0), m_iBrackets( a_Reader.m_iBrackets ), m_lastTok(), + m_cArgSep( a_Reader.m_cArgSep ) +{} //---------------------------------------------------------------------------------------------------------------------- /** @@ -128,7 +134,7 @@ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) */ QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const { - std::auto_ptr ptr ( new QmuParserTokenReader ( *this ) ); + std::unique_ptr ptr ( new QmuParserTokenReader ( *this ) ); ptr->SetParent ( a_pParent ); return ptr.release(); } @@ -330,11 +336,11 @@ int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_ const std::string a_szCharSetStd = a_szCharSet.toStdString(); #endif - int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos ); + int iEnd = static_cast(m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos )); - if ( iEnd == ( int ) string_type::npos ) + if ( iEnd == static_cast(string_type::npos) ) { - iEnd = ( int ) m_strFormulaStd.length(); + iEnd = static_cast(m_strFormulaStd.length()); } // Assign token string if there was something found @@ -367,10 +373,10 @@ int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) c const std::string m_strFormulaStd = m_strFormula.toStdString(); const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); #endif - int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ); - if ( iEnd == ( int ) string_type::npos ) + int iEnd = static_cast( m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ) ); + if ( iEnd == static_cast( string_type::npos ) ) { - iEnd = ( int ) m_strFormulaStd.length(); + iEnd = static_cast( m_strFormulaStd.length() ); } // Assign token string if there was something found @@ -492,7 +498,7 @@ bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok ) } // switch operator id m_iPos += len; - a_Tok.Set ( ( ECmdCode ) i, pOprtDef.at ( i ) ); + a_Tok.Set ( static_cast(i), pOprtDef.at ( i ) ); return true; } // if operator string found } // end of for all operator strings @@ -578,7 +584,7 @@ bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok ) continue; a_Tok.Set ( it->second, it->first ); - m_iPos += ( int ) it->first.length(); + m_iPos += static_cast(it->first.length()); if ( m_iSynFlags & noINFIXOP ) Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() ); @@ -628,7 +634,7 @@ bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok ) m_iPos = iEnd; if ( m_iSynFlags & noFUN ) - Error ( ecUNEXPECTED_FUN, m_iPos - ( int ) a_Tok.GetAsString().length(), a_Tok.GetAsString() ); + Error ( ecUNEXPECTED_FUN, m_iPos - static_cast(a_Tok.GetAsString().length()), a_Tok.GetAsString() ); m_iSynFlags = noANY ^ noBO; return true; @@ -690,7 +696,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) } - m_iPos += ( int ) sID.length(); + m_iPos += sID.length(); m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; return true; } @@ -828,7 +834,7 @@ bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok ) if ( m_iSynFlags & noVAR ) Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); - m_pParser->OnDetectVar ( &m_strFormula, m_iPos, iEnd ); + m_pParser->OnDetectVar ( m_strFormula, m_iPos, iEnd ); m_iPos = iEnd; a_Tok.SetVar ( item->second, strTok ); @@ -893,7 +899,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) // token identifier. // related bug report: // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 - Error ( ecUNEXPECTED_VAR, m_iPos - ( int ) a_Tok.GetAsString().length(), strTok ); + Error ( ecUNEXPECTED_VAR, m_iPos - a_Tok.GetAsString().length(), strTok ); } // If a factory is available implicitely create new variables @@ -913,7 +919,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) } else { - a_Tok.SetVar ( ( qreal* ) &m_fZero, strTok ); + a_Tok.SetVar ( &m_fZero, strTok ); m_UsedVar[strTok] = 0; // Add variable to used-var-list } @@ -960,7 +966,7 @@ bool QmuParserTokenReader::IsString ( token_type &a_Tok ) m_pParser->m_vStringBuf.push_back ( strTok ); // Store string in internal buffer a_Tok.SetString ( strTok, m_pParser->m_vStringBuf.size() ); - m_iPos += ( int ) strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iPos += strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); return true; From 362638066a7d17e6eb40fb3f4ae1516ae475cff5 Mon Sep 17 00:00:00 2001 From: dismine Date: Thu, 1 May 2014 14:33:40 +0300 Subject: [PATCH 17/26] Vera++. --HG-- branch : feature --- src/app/container/vmeasurement.cpp | 4 - src/app/container/vmeasurement.h | 34 +- src/app/dialogs/app/dialogincrements.cpp | 10 +- .../app/dialogindividualmeasurements.cpp | 6 +- .../app/dialogstandardmeasurements.cpp | 4 +- src/app/dialogs/tools/dialogdetail.cpp | 4 +- src/app/dialogs/tools/dialoguniondetails.h | 3 +- src/app/main.cpp | 3 +- src/app/mainwindow.cpp | 32 +- src/app/options.h | 2 +- src/app/tablewindow.cpp | 40 +- src/app/tools/drawTools/vtoolpoint.cpp | 2 +- src/app/tools/drawTools/vtooltriangle.cpp | 6 +- src/app/tools/nodeDetails/vnodearc.h | 5 +- src/app/tools/nodeDetails/vnodepoint.h | 28 +- src/app/tools/nodeDetails/vnodespline.h | 23 +- src/app/tools/nodeDetails/vnodesplinepath.cpp | 4 +- src/app/tools/nodeDetails/vnodesplinepath.h | 5 +- src/app/tools/vtooluniondetails.cpp | 2 +- src/app/widgets/vapplication.cpp | 2 +- src/app/xml/vdomdocument.cpp | 5 +- src/app/xml/vdomdocument.h | 10 +- src/app/xml/vpattern.cpp | 7 +- src/app/xml/vstandardmeasurements.cpp | 2 +- src/libs/qmuparser/qmuparser.cpp | 342 +- src/libs/qmuparser/qmuparser.h | 2 +- src/libs/qmuparser/qmuparserbase.cpp | 4988 ++++++++--------- src/libs/qmuparser/qmuparserbase.h | 523 +- src/libs/qmuparser/qmuparserbytecode.cpp | 1906 +++---- src/libs/qmuparser/qmuparserbytecode.h | 250 +- src/libs/qmuparser/qmuparsercallback.cpp | 222 +- src/libs/qmuparser/qmuparsercallback.h | 229 +- src/libs/qmuparser/qmuparserdef.h | 9 +- src/libs/qmuparser/qmuparsererror.cpp | 256 +- src/libs/qmuparser/qmuparsererror.h | 69 +- src/libs/qmuparser/qmuparserfixes.h | 116 +- src/libs/qmuparser/qmuparsertest.cpp | 2264 ++++---- src/libs/qmuparser/qmuparsertest.h | 396 +- src/libs/qmuparser/qmuparsertoken.h | 846 +-- src/libs/qmuparser/qmuparsertokenreader.cpp | 1223 ++-- src/libs/qmuparser/qmuparsertokenreader.h | 310 +- 41 files changed, 7158 insertions(+), 7036 deletions(-) diff --git a/src/app/container/vmeasurement.cpp b/src/app/container/vmeasurement.cpp index 248181a7f..2200c5cad 100644 --- a/src/app/container/vmeasurement.cpp +++ b/src/app/container/vmeasurement.cpp @@ -61,7 +61,3 @@ qreal VMeasurement::GetValue(const qreal &size, const qreal &height) const const qreal k_height = ( height - 176.0 ) / 6.0; return base + k_size * ksize + k_height * kheight; } - - - - diff --git a/src/app/container/vmeasurement.h b/src/app/container/vmeasurement.h index 8e2138f05..c4071a086 100644 --- a/src/app/container/vmeasurement.h +++ b/src/app/container/vmeasurement.h @@ -37,23 +37,23 @@ class VMeasurement { public: - /** - * @brief VStandardTableRow create empty row - */ - VMeasurement(); - /** - * @brief VStandardTableRow create row - * @param base value in base size and growth - * @param ksize increment in sizes - * @param kgrowth increment in growths - * @param description description of increment - */ - VMeasurement(const qreal &base, const qreal &ksize, const qreal &kheight, - const QString &gui_text = QString(), const QString &number = QString(), - const QString &TagName = QString()); - VMeasurement(const qreal &base, const QString &gui_text = QString(), - const QString &number = QString(), const QString &TagName = QString()); - ~VMeasurement(){} + /** + * @brief VStandardTableRow create empty row + */ + VMeasurement(); + /** + * @brief VStandardTableRow create row + * @param base value in base size and growth + * @param ksize increment in sizes + * @param kgrowth increment in growths + * @param description description of increment + */ + VMeasurement(const qreal &base, const qreal &ksize, const qreal &kheight, + const QString &gui_text = QString(), const QString &number = QString(), + const QString &TagName = QString()); + VMeasurement(const qreal &base, const QString &gui_text = QString(), + const QString &number = QString(), const QString &TagName = QString()); + ~VMeasurement(){} /** * @brief GetBase return value in base size and growth * @return value diff --git a/src/app/dialogs/app/dialogincrements.cpp b/src/app/dialogs/app/dialogincrements.cpp index 560a21f1a..4b0552647 100644 --- a/src/app/dialogs/app/dialogincrements.cpp +++ b/src/app/dialogs/app/dialogincrements.cpp @@ -54,7 +54,7 @@ DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *par m = new VIndividualMeasurements(data); m->setContent(filePath); } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("File error."), this); emit DialogClosed(QDialog::Rejected); @@ -101,8 +101,8 @@ DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *par ui->lineEditGivenName->setText(m->GivenName()); ui->lineEditFamilyName->setText(m->FamilyName()); - ui->comboBoxSex->addItem(tr("male"),QVariant(m->GenderToStr(VIndividualMeasurements::Male))); - ui->comboBoxSex->addItem(tr("female"),QVariant(m->GenderToStr(VIndividualMeasurements::Female))); + ui->comboBoxSex->addItem(tr("male"), QVariant(m->GenderToStr(VIndividualMeasurements::Male))); + ui->comboBoxSex->addItem(tr("female"), QVariant(m->GenderToStr(VIndividualMeasurements::Female))); qint32 index = ui->comboBoxSex->findData(m->GenderToStr(m->Sex())); if (index != -1) { @@ -473,7 +473,7 @@ void DialogIncrements::OpenTable() m1 = new VIndividualMeasurements(data); m1->setContent(filePath); } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("File error."), this); delete m1; @@ -529,7 +529,7 @@ void DialogIncrements::OpenTable() doc->SetPath(filePath); emit haveLiteChange(); } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("File error."), this); delete m1; diff --git a/src/app/dialogs/app/dialogindividualmeasurements.cpp b/src/app/dialogs/app/dialogindividualmeasurements.cpp index 9b8337cf4..e112a3012 100644 --- a/src/app/dialogs/app/dialogindividualmeasurements.cpp +++ b/src/app/dialogs/app/dialogindividualmeasurements.cpp @@ -116,7 +116,7 @@ void DialogIndividualMeasurements::DialogAccepted() iMeasur.close(); } } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("File error."), this); qDebug()<<"File error."<comboBoxLang->addItem(lang, QVariant(fi.absoluteFilePath())); } - catch(VException &e) + catch (VException &e) { qDebug()<<"File error."<setPatternUnit(m.Unit()); } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("File error."), this); qDebug()<<"File error."<comboBoxTables->addItem(m.Description(), QVariant(fi.absoluteFilePath())); } - catch(VException &e) + catch (VException &e) { qDebug()<<"File error."<ClearGObjects(); //Create single point - const quint32 id = pattern->AddGObject(new VPointF(qApp->toPixel((10+comboBoxDraws->count()*5)), qApp->toPixel(10), "А", 5, - 10)); + const quint32 id = pattern->AddGObject(new VPointF(qApp->toPixel((10+comboBoxDraws->count()*5)), qApp->toPixel(10), + "А", 5, 10)); VToolSinglePoint *spoint = new VToolSinglePoint(doc, pattern, id, Valentina::FromGui); sceneDraw->addItem(spoint); connect(spoint, &VToolPoint::ChoosedTool, sceneDraw, &VMainGraphicsScene::ChoosedItem); @@ -261,8 +261,8 @@ void MainWindow::ClosedDialogLine(int result) void MainWindow::ToolAlongLine(bool checked) { - SetToolButton(checked, Valentina::AlongLineTool, ":/cursor/alongline_cursor.png", tr("Select point"), - &MainWindow::ClosedDialogAlongLine); + SetToolButton(checked, Valentina::AlongLineTool, ":/cursor/alongline_cursor.png", + tr("Select point"), &MainWindow::ClosedDialogAlongLine); } void MainWindow::ClosedDialogAlongLine(int result) @@ -360,8 +360,9 @@ void MainWindow::ClosedDialogSplinePath(int result) void MainWindow::ToolCutSplinePath(bool checked) { - SetToolButton(checked, Valentina::CutSplinePathTool, ":/cursor/splinepath_cut_point_cursor.png", - tr("Select curve path"), &MainWindow::ClosedDialogCutSplinePath); + SetToolButton(checked, Valentina::CutSplinePathTool, + ":/cursor/splinepath_cut_point_cursor.png", tr("Select curve path"), + &MainWindow::ClosedDialogCutSplinePath); } void MainWindow::ClosedDialogCutSplinePath(int result) @@ -420,8 +421,9 @@ void MainWindow::ClosedDialogTriangle(int result) void MainWindow::ToolPointOfIntersection(bool checked) { - SetToolButton(checked, Valentina::PointOfIntersection, ":/cursor/pointofintersect_cursor.png", - tr("Select point vertically"), &MainWindow::ClosedDialogPointOfIntersection); + SetToolButton(checked, Valentina::PointOfIntersection, + ":/cursor/pointofintersect_cursor.png", tr("Select point vertically"), + &MainWindow::ClosedDialogPointOfIntersection); } void MainWindow::ClosedDialogPointOfIntersection(int result) @@ -431,8 +433,8 @@ void MainWindow::ClosedDialogPointOfIntersection(int result) void MainWindow::ToolUnionDetails(bool checked) { - SetToolButton(checked, Valentina::UnionDetails, ":/cursor/union_cursor.png", tr("Select detail"), - &MainWindow::ClosedDialogUnionDetails); + SetToolButton(checked, Valentina::UnionDetails, ":/cursor/union_cursor.png", + tr("Select detail"), &MainWindow::ClosedDialogUnionDetails); //Must disconnect this signal here. disconnect(doc, &VPattern::FullUpdateFromFile, dialogTool, &DialogTool::UpdateList); } @@ -1358,7 +1360,7 @@ void MainWindow::LoadPattern(const QString &fileName) QString path = doc->MPath(); path = CheckPathToMeasurements(path, qApp->patternType()); - if(path.isEmpty()) + if (path.isEmpty()) { Clear(); return; @@ -1394,7 +1396,7 @@ void MainWindow::LoadPattern(const QString &fileName) } } } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("File error."), this); Clear(); @@ -1440,7 +1442,7 @@ void MainWindow::LoadPattern(const QString &fileName) Clear(); return; } - catch(VException &e) + catch (VException &e) { e.CriticalMessageBox(tr("Error parsing file."), this); Clear(); @@ -1478,7 +1480,7 @@ QString MainWindow::CheckPathToMeasurements(const QString &path, const Pattern:: QMessageBox::StandardButton res = QMessageBox::question(this, "Loading measurements file", text, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - if(res == QMessageBox::No) + if (res == QMessageBox::No) { return QString(); } @@ -1495,7 +1497,7 @@ QString MainWindow::CheckPathToMeasurements(const QString &path, const Pattern:: } QString mPath = QFileDialog::getOpenFileName(this, tr("Open file"), QDir::homePath(), filter); - if(mPath.isEmpty()) + if (mPath.isEmpty()) { return mPath; } diff --git a/src/app/options.h b/src/app/options.h index cff42b632..90caecb8a 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -111,6 +111,6 @@ namespace Pattern enum Measurement { Standard, Individual }; Q_DECLARE_FLAGS(Measurements, Measurement) } -Q_DECLARE_OPERATORS_FOR_FLAGS( Pattern::Measurements ) +Q_DECLARE_OPERATORS_FOR_FLAGS( Pattern::Measurements ) #endif // OPTIONS_H diff --git a/src/app/tablewindow.cpp b/src/app/tablewindow.cpp index 23ff21da2..1c88edb4f 100644 --- a/src/app/tablewindow.cpp +++ b/src/app/tablewindow.cpp @@ -222,26 +222,26 @@ void TableWindow::saveScene() suffix << "svg" << "png" << "pdf" << "eps" << "ps"; switch (suffix.indexOf(fi.suffix())) { - case 0: //svg - paper->setVisible(false); - SvgFile(name); - paper->setVisible(true); - break; - case 1: //png - PngFile(name); - break; - case 2: //pdf - PdfFile(name); - break; - case 3: //eps - EpsFile(name); - break; - case 4: //ps - PsFile(name); - break; - default: - qDebug() << "Bad file suffix"<setVisible(false); + SvgFile(name); + paper->setVisible(true); + break; + case 1: //png + PngFile(name); + break; + case 2: //pdf + PdfFile(name); + break; + case 3: //eps + EpsFile(name); + break; + case 4: //ps + PsFile(name); + break; + default: + qDebug() << "Bad file suffix"<setPen(QPen(Qt::black, qApp->toPixel(qApp->widthMainLine()))); brush->setColor( QColor( Qt::gray ) ); diff --git a/src/app/tools/drawTools/vtoolpoint.cpp b/src/app/tools/drawTools/vtoolpoint.cpp index 0c03e937c..a6ab0578b 100644 --- a/src/app/tools/drawTools/vtoolpoint.cpp +++ b/src/app/tools/drawTools/vtoolpoint.cpp @@ -36,7 +36,7 @@ const QString VToolPoint::TagName = QStringLiteral("point"); VToolPoint::VToolPoint(VPattern *doc, VContainer *data, quint32 id, QGraphicsItem *parent):VDrawTool(doc, data, id), QGraphicsEllipseItem(parent), radius(DefRadius), namePoint(0), lineName(0) { - switch(qApp->patternUnit()) + switch (qApp->patternUnit()) { case Valentina::Mm: radius = qApp->toPixel(DefRadius); diff --git a/src/app/tools/drawTools/vtooltriangle.cpp b/src/app/tools/drawTools/vtooltriangle.cpp index c88450982..542092d75 100644 --- a/src/app/tools/drawTools/vtooltriangle.cpp +++ b/src/app/tools/drawTools/vtooltriangle.cpp @@ -31,9 +31,9 @@ const QString VToolTriangle::ToolType = QStringLiteral("triangle"); -VToolTriangle::VToolTriangle(VPattern *doc, VContainer *data, const quint32 &id, - const quint32 &axisP1Id, const quint32 &axisP2Id, const quint32 &firstPointId, - const quint32 &secondPointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent) +VToolTriangle::VToolTriangle(VPattern *doc, VContainer *data, const quint32 &id, const quint32 &axisP1Id, + const quint32 &axisP2Id, const quint32 &firstPointId, const quint32 &secondPointId, + const Valentina::Sources &typeCreation, QGraphicsItem *parent) :VToolPoint(doc, data, id, parent), axisP1Id(axisP1Id), axisP2Id(axisP2Id), firstPointId(firstPointId), secondPointId(secondPointId) { diff --git a/src/app/tools/nodeDetails/vnodearc.h b/src/app/tools/nodeDetails/vnodearc.h index a73e6c517..48e2d5a96 100644 --- a/src/app/tools/nodeDetails/vnodearc.h +++ b/src/app/tools/nodeDetails/vnodearc.h @@ -48,8 +48,9 @@ public: * @param typeCreation way we create this tool. * @param parent parent object. */ - VNodeArc(VPattern *doc, VContainer *data, quint32 id, quint32 idArc, const Valentina::Sources &typeCreation, - const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr); + VNodeArc(VPattern *doc, VContainer *data, quint32 id, quint32 idArc, + const Valentina::Sources &typeCreation, const quint32 &idTool = 0, + QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr); /** * @brief Create help create tool. * @param doc dom document container. diff --git a/src/app/tools/nodeDetails/vnodepoint.h b/src/app/tools/nodeDetails/vnodepoint.h index 46c643771..762d0cf3e 100644 --- a/src/app/tools/nodeDetails/vnodepoint.h +++ b/src/app/tools/nodeDetails/vnodepoint.h @@ -39,18 +39,17 @@ class VNodePoint: public VAbstractNode, public QGraphicsEllipseItem { Q_OBJECT public: - /** - * @brief VNodePoint constructor. - * @param doc dom document container. - * @param data container with variables. - * @param id object id in container. - * @param id object id in containerPoint. - * @param typeCreation way we create this tool. - * @param parent parent object. - */ - VNodePoint(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, - const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *qoParent = nullptr, - QGraphicsItem * parent = nullptr ); + /** + * @brief VNodePoint constructor. + * @param doc dom document container. + * @param data container with variables. + * @param id object id in container. + * @param id object id in containerPoint. + * @param typeCreation way we create this tool. + * @param parent parent object. + */ + VNodePoint(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, const Valentina::Sources &typeCreation, + const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr ); /** * @brief Create help create tool. * @param doc dom document container. @@ -60,9 +59,8 @@ public: * @param parse parser file mode. * @param typeCreation way we create this tool. */ - static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, - const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool = 0, - QObject *parent = nullptr); + static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, const Document::Documents &parse, + const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *parent = nullptr); static const QString TagName; static const QString ToolType; /** diff --git a/src/app/tools/nodeDetails/vnodespline.h b/src/app/tools/nodeDetails/vnodespline.h index a21b44842..b83a969a9 100644 --- a/src/app/tools/nodeDetails/vnodespline.h +++ b/src/app/tools/nodeDetails/vnodespline.h @@ -39,18 +39,17 @@ class VNodeSpline:public VAbstractNode, public QGraphicsPathItem { Q_OBJECT public: - /** - * @brief VNodeSpline constructor. - * @param doc dom document container. - * @param data container with variables. - * @param id object id in container. - * @param id object id in containerSpline. - * @param typeCreation way we create this tool. - * @param parent parent object. - */ - VNodeSpline(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, - const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *qoParent = nullptr, - QGraphicsItem * parent = nullptr); + /** + * @brief VNodeSpline constructor. + * @param doc dom document container. + * @param data container with variables. + * @param id object id in container. + * @param id object id in containerSpline. + * @param typeCreation way we create this tool. + * @param parent parent object. + */ + VNodeSpline(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Valentina::Sources &typeCreation, + const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr); /** * @brief Create help create tool. * @param doc dom document container. diff --git a/src/app/tools/nodeDetails/vnodesplinepath.cpp b/src/app/tools/nodeDetails/vnodesplinepath.cpp index 35a02aee4..49008ceee 100644 --- a/src/app/tools/nodeDetails/vnodesplinepath.cpp +++ b/src/app/tools/nodeDetails/vnodesplinepath.cpp @@ -53,8 +53,8 @@ VNodeSplinePath::VNodeSplinePath(VPattern *doc, VContainer *data, quint32 id, qu } void VNodeSplinePath::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, - const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool, - QObject *parent) + const Document::Documents &parse, const Valentina::Sources &typeCreation, + const quint32 &idTool, QObject *parent) { VAbstractTool::AddRecord(id, Valentina::NodeSplinePath, doc); if (parse == Document::FullParse) diff --git a/src/app/tools/nodeDetails/vnodesplinepath.h b/src/app/tools/nodeDetails/vnodesplinepath.h index 843c4038c..4e9facca4 100644 --- a/src/app/tools/nodeDetails/vnodesplinepath.h +++ b/src/app/tools/nodeDetails/vnodesplinepath.h @@ -60,9 +60,8 @@ public: * @param parse parser file mode. * @param typeCreation way we create this tool. */ - static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, - const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool = 0, - QObject *parent = 0); + static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Document::Documents &parse, + const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *parent = 0); static const QString TagName; static const QString ToolType; /** diff --git a/src/app/tools/vtooluniondetails.cpp b/src/app/tools/vtooluniondetails.cpp index 006403c9e..7281ac086 100644 --- a/src/app/tools/vtooluniondetails.cpp +++ b/src/app/tools/vtooluniondetails.cpp @@ -481,7 +481,7 @@ void VToolUnionDetails::Create(const quint32 _id, const VDetail &d1, const VDeta ++j; } while (pointsD2 < d2.RemoveEdge(indexD2).CountNode()); } - } while(i < d1.RemoveEdge(indexD1).CountNode()); + } while (i < d1.RemoveEdge(indexD1).CountNode()); newDetail.setName("Detail"); VToolDetail::Create(0, newDetail, scene, doc, data, parse, Valentina::FromTool); diff --git a/src/app/widgets/vapplication.cpp b/src/app/widgets/vapplication.cpp index e754ffc63..061ca841c 100644 --- a/src/app/widgets/vapplication.cpp +++ b/src/app/widgets/vapplication.cpp @@ -174,7 +174,7 @@ QString VApplication::translationsPath() const void VApplication::InitLineWidth() { - switch(_patternUnit) + switch (_patternUnit) { case Valentina::Mm: _widthMainLine = DefWidth; diff --git a/src/app/xml/vdomdocument.cpp b/src/app/xml/vdomdocument.cpp index 0cb27e2eb..d0fd35ae9 100644 --- a/src/app/xml/vdomdocument.cpp +++ b/src/app/xml/vdomdocument.cpp @@ -293,7 +293,8 @@ void VDomDocument::ValidateXML(const QString &schema, const QString &fileName) pattern.close(); fileSchema.close(); VException e(messageHandler.statusMessage()); - e.AddMoreInformation(tr("Validation error in line %1 column %2").arg(messageHandler.line()).arg(messageHandler.column())); + e.AddMoreInformation(tr("Validation error in line %1 column %2").arg(messageHandler.line()) + .arg(messageHandler.column())); throw e; } pattern.close(); @@ -347,7 +348,7 @@ Valentina::Units VDomDocument::StrToUnits(const QString &unit) QString VDomDocument::UnitsToStr(const Valentina::Units &unit) { QString result; - switch(unit) + switch (unit) { case Valentina::Mm: result = "mm"; diff --git a/src/app/xml/vdomdocument.h b/src/app/xml/vdomdocument.h index c2765254d..a0369050e 100644 --- a/src/app/xml/vdomdocument.h +++ b/src/app/xml/vdomdocument.h @@ -42,21 +42,21 @@ /** * @brief The VDomDocument class represents a Valentina document (.val file). - * - * A Valentina document describes the construction of a sewing pattern. The + * + * A Valentina document describes the construction of a sewing pattern. The * information is stored in XML format. By parsing a VDomDocument, the contained * pattern is rendered to a Valentina graphics scene (VMainGraphicsScene). * - * A sewing pattern consists of zero or more increments and one + * A sewing pattern consists of zero or more increments and one * or more pattern pieces. * * An increment is an auxiliary variable that is calculated from regular measurement * variables (that belong to the standard measurements table). Increments are used to * create a graduation schema for the sewing pattern. * - * A pattern piece contains + * A pattern piece contains * 1) auxiliary pattern construction elements (calculation), - * 2) pattern construction elements (modeling), and + * 2) pattern construction elements (modeling), and * 3) special markers, e.g. seam allowances (details). * Of these, 2) and 3) are visible in the final pattern (draw mode 'Modeling'), * 1) is only displayed when editing (draw mode 'Calculation') the pattern. diff --git a/src/app/xml/vpattern.cpp b/src/app/xml/vpattern.cpp index ec8f0db9e..56ca2737b 100644 --- a/src/app/xml/vpattern.cpp +++ b/src/app/xml/vpattern.cpp @@ -460,7 +460,7 @@ Valentina::Units VPattern::MUnit() const QStringList units; units << "mm" << "cm" << "inch"; QString unit = GetParametrString(element, AttrUnit); - switch(units.indexOf(unit)) + switch (units.indexOf(unit)) { case 0:// mm return Valentina::Mm; @@ -491,7 +491,7 @@ Pattern::Measurements VPattern::MType() const QString type = GetParametrString(element, AttrType); QStringList types; types << "standard" << "individual"; - switch(types.indexOf(type)) + switch (types.indexOf(type)) { case 0:// standard return Pattern::Standard; @@ -1049,7 +1049,8 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, const QDomElement &d const QString formula = GetParametrString(domElement, VAbstractTool::AttrLength, "0"); const quint32 splineId = GetParametrUInt(domElement, VToolCutSpline::AttrSpline, "0"); - VToolCutSpline::Create(id, name, formula, splineId, mx, my, scene, this, data, parse, Valentina::FromFile); + VToolCutSpline::Create(id, name, formula, splineId, mx, my, scene, this, data, parse, + Valentina::FromFile); } catch (const VExceptionBadId &e) { diff --git a/src/app/xml/vstandardmeasurements.cpp b/src/app/xml/vstandardmeasurements.cpp index cb96b7908..354b6c1a6 100644 --- a/src/app/xml/vstandardmeasurements.cpp +++ b/src/app/xml/vstandardmeasurements.cpp @@ -70,7 +70,7 @@ void VStandardMeasurements::Measurements() } else { - for(qint32 i = 0; i < nodeList.size(); ++i) + for (qint32 i = 0; i < nodeList.size(); ++i) { const QDomNode domNode = nodeList.at(i); if (domNode.isNull() == false && domNode.isElement()) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 0c7d38ea0..09919f9c4 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -39,78 +39,78 @@ namespace qmu // Trigonometric function qreal QmuParser::Sinh(qreal v) { - return sinh(v); + return sinh(v); } qreal QmuParser::Cosh(qreal v) { - return cosh(v); + return cosh(v); } qreal QmuParser::Tanh(qreal v) { - return tanh(v); + return tanh(v); } qreal QmuParser::ASinh(qreal v) { - return log(v + qSqrt(v * v + 1)); + return log(v + qSqrt(v * v + 1)); } qreal QmuParser::ACosh(qreal v) { - return log(v + qSqrt(v * v - 1)); + return log(v + qSqrt(v * v - 1)); } qreal QmuParser::ATanh(qreal v) { - return (0.5 * log((1 + v) / (1 - v))); + return (0.5 * log((1 + v) / (1 - v))); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- // Logarithm functions // Logarithm base 2 qreal QmuParser::Log2(qreal v) { #ifdef MUP_MATH_EXCEPTIONS - if (v<=0) - { - throw QmuParserError(ecDOMAIN_ERROR, "Log2"); - } + if (v<=0) + { + throw QmuParserError(ecDOMAIN_ERROR, "Log2"); + } #endif - return log(v)/log(2.0); + return log(v)/log(2.0); } // Logarithm base 10 qreal QmuParser::Log10(qreal v) { #ifdef MUP_MATH_EXCEPTIONS - if (v<=0) - { - throw QmuParserError(ecDOMAIN_ERROR, "Log10"); - } + if (v<=0) + { + throw QmuParserError(ecDOMAIN_ERROR, "Log10"); + } #endif - return log10(v); + return log10(v); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- // misc qreal QmuParser::Abs(qreal v) { - return qAbs(v); + return qAbs(v); } qreal QmuParser::Rint(qreal v) { - return qFloor(v + 0.5); + return qFloor(v + 0.5); } qreal QmuParser::Sign(qreal v) { - return ((v<0) ? -1 : (v>0) ? 1 : 0); + return ((v<0) ? -1 : (v>0) ? 1 : 0); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Callback for the unary minus operator. * @param v The value to negate @@ -118,10 +118,10 @@ qreal QmuParser::Sign(qreal v) */ qreal QmuParser::UnaryMinus(qreal v) { - return -v; + return -v; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Callback for adding multiple values. * @param [in] a_afArg Vector with the function arguments @@ -129,16 +129,19 @@ qreal QmuParser::UnaryMinus(qreal v) */ qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc) { - if (!a_iArgc) - { - throw exception_type("too few arguments for function sum."); - } - qreal fRes=0; - for (int i=0; i(a_iArgc); + if (a_iArgc == false) + { + throw exception_type("too few arguments for function sum."); + } + qreal fRes=0; + for (int i=0; i(a_iArgc); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Callback for determining the minimum value out of a vector. * @param [in] a_afArg Vector with the function arguments @@ -163,19 +169,19 @@ qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc) */ qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc) { - if (!a_iArgc) - { - throw exception_type("too few arguments for function min."); - } - qreal fRes=a_afArg[0]; - for (int i=0; i> fVal; - stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading + #if defined(_UNICODE) + std::wstring a_szExprStd = a_szExpr.toStdWString(); + #else + std::string a_szExprStd = a_szExpr.toStdString(); + #endif + stringstream_type stream(a_szExprStd); + stream.seekg(0); // todo: check if this really is necessary + stream.imbue(QmuParser::s_locale); + stream >> fVal; + stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading - if (iEnd==static_cast(-1)) - { - return 0; - } + if (iEnd==static_cast(-1)) + { + return 0; + } - *a_iPos += static_cast(iEnd); - *a_fVal = fVal; - return 1; + *a_iPos += static_cast(iEnd); + *a_fVal = fVal; + return 1; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Constructor. * @@ -236,15 +242,15 @@ int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal) */ QmuParser::QmuParser():QmuParserBase() { - AddValIdent(IsVal); + AddValIdent(IsVal); - InitCharSets(); - InitFun(); - InitConst(); - InitOprt(); + InitCharSets(); + InitFun(); + InitConst(); + InitOprt(); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Define the character sets. * @sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars @@ -254,53 +260,53 @@ QmuParser::QmuParser():QmuParserBase() */ void QmuParser::InitCharSets() { - DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); - DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" ); - DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" ); + DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ); + DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" ); + DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Initialize the default functions. */ void QmuParser::InitFun() { - // trigonometric functions - DefineFun("sin", qSin); - DefineFun("cos", qCos); - DefineFun("tan", qTan); - // arcus functions - DefineFun("asin", qAsin); - DefineFun("acos", qAcos); - DefineFun("atan", qAtan); - DefineFun("atan2", qAtan2); - // hyperbolic functions - DefineFun("sinh", Sinh); - DefineFun("cosh", Cosh); - DefineFun("tanh", Tanh); - // arcus hyperbolic functions - DefineFun("asinh", ASinh); - DefineFun("acosh", ACosh); - DefineFun("atanh", ATanh); - // Logarithm functions - DefineFun("log2", Log2); - DefineFun("log10", Log10); - DefineFun("log", Log10); - DefineFun("ln", qLn); - // misc - DefineFun("exp", qExp); - DefineFun("sqrt", qSqrt); - DefineFun("sign", Sign); - DefineFun("rint", Rint); - DefineFun("abs", Abs); - // Functions with variable number of arguments - DefineFun("sum", Sum); - DefineFun("avg", Avg); - DefineFun("min", Min); - DefineFun("max", Max); + // trigonometric functions + DefineFun("sin", qSin); + DefineFun("cos", qCos); + DefineFun("tan", qTan); + // arcus functions + DefineFun("asin", qAsin); + DefineFun("acos", qAcos); + DefineFun("atan", qAtan); + DefineFun("atan2", qAtan2); + // hyperbolic functions + DefineFun("sinh", Sinh); + DefineFun("cosh", Cosh); + DefineFun("tanh", Tanh); + // arcus hyperbolic functions + DefineFun("asinh", ASinh); + DefineFun("acosh", ACosh); + DefineFun("atanh", ATanh); + // Logarithm functions + DefineFun("log2", Log2); + DefineFun("log10", Log10); + DefineFun("log", Log10); + DefineFun("ln", qLn); + // misc + DefineFun("exp", qExp); + DefineFun("sqrt", qSqrt); + DefineFun("sign", Sign); + DefineFun("rint", Rint); + DefineFun("abs", Abs); + // Functions with variable number of arguments + DefineFun("sum", Sum); + DefineFun("avg", Avg); + DefineFun("min", Min); + DefineFun("max", Max); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Initialize constants. * @@ -309,11 +315,11 @@ void QmuParser::InitFun() */ void QmuParser::InitConst() { - DefineConst("_pi", (qreal)M_PI); - DefineConst("_e", (qreal)M_E); + DefineConst("_pi", (qreal)M_PI); + DefineConst("_e", (qreal)M_E); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Initialize operators. * @@ -321,38 +327,38 @@ void QmuParser::InitConst() */ void QmuParser::InitOprt() { - DefineInfixOprt("-", UnaryMinus); + DefineInfixOprt("-", UnaryMinus); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) { - Q_UNUSED(pExpr); - Q_UNUSED(nStart); - Q_UNUSED(nEnd); - // this is just sample code to illustrate modifying variable names on the fly. - // I'm not sure anyone really needs such a feature... - /* + Q_UNUSED(pExpr); + Q_UNUSED(nStart); + Q_UNUSED(nEnd); + // this is just sample code to illustrate modifying variable names on the fly. + // I'm not sure anyone really needs such a feature... + /* - string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd); - string sRepl = std::string("_") + sVar + "_"; + string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd); + string sRepl = std::string("_") + sVar + "_"; - int nOrigVarEnd = nEnd; - cout << "variable detected!\n"; - cout << " Expr: " << *pExpr << "\n"; - cout << " Start: " << nStart << "\n"; - cout << " End: " << nEnd << "\n"; - cout << " Var: \"" << sVar << "\"\n"; - cout << " Repl: \"" << sRepl << "\"\n"; - nEnd = nStart + sRepl.length(); - cout << " End: " << nEnd << "\n"; - pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl); - cout << " New expr: " << *pExpr << "\n"; - */ + int nOrigVarEnd = nEnd; + cout << "variable detected!\n"; + cout << " Expr: " << *pExpr << "\n"; + cout << " Start: " << nStart << "\n"; + cout << " End: " << nEnd << "\n"; + cout << " Var: \"" << sVar << "\"\n"; + cout << " Repl: \"" << sRepl << "\"\n"; + nEnd = nStart + sRepl.length(); + cout << " End: " << nEnd << "\n"; + pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl); + cout << " New expr: " << *pExpr << "\n"; + */ } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Numerically differentiate with regard to a variable. * @param [in] a_Var Pointer to the differentiation variable. @@ -368,25 +374,25 @@ void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) */ qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const { - qreal fRes(0), - fBuf(*a_Var), - f[4] = {0,0,0,0}, - fEpsilon(a_fEpsilon); + qreal fRes(0), + fBuf(*a_Var), + f[4] = {0, 0, 0, 0}, + fEpsilon(a_fEpsilon); - // Backwards compatible calculation of epsilon inc case the user doesnt provide - // his own epsilon - if (qFuzzyCompare(fEpsilon + 1, 1 + 0)) - { - fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast(1e-10) : static_cast(1e-7) * a_fPos; - } + // Backwards compatible calculation of epsilon inc case the user doesnt provide + // his own epsilon + if (qFuzzyCompare(fEpsilon + 1, 1 + 0)) + { + fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast(1e-10) : static_cast(1e-7) * a_fPos; + } - *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); - *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); - *a_Var = a_fPos-1 * fEpsilon; f[2] = Eval(); - *a_Var = a_fPos-2 * fEpsilon; f[3] = Eval(); - *a_Var = fBuf; // restore variable + *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); + *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); + *a_Var = a_fPos-1 * fEpsilon; f[2] = Eval(); + *a_Var = a_fPos-2 * fEpsilon; f[3] = Eval(); + *a_Var = fBuf; // restore variable - fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon); - return fRes; + fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon); + return fRes; } } // namespace qmu diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index bb713ed76..e64178122 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -51,7 +51,7 @@ namespace qmu virtual void InitFun(); virtual void InitConst(); virtual void InitOprt(); - virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); + virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const; protected: static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal); diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 07ecfea7a..3b29c6396 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -1,2494 +1,2494 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include "qmuparserbase.h" -#include -#include -#ifdef QMUP_USE_OPENMP - #include -#endif - -using namespace std; - -/** - * @file - * @brief This file contains the basic implementation of the muparser engine. - */ - -namespace qmu -{ -std::locale QmuParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep('.')); - -bool QmuParserBase::g_DbgDumpCmdCode = false; -bool QmuParserBase::g_DbgDumpStack = false; - -/** - * @brief Identifiers for built in binary operators. - * - * When defining custom binary operators with #AddOprt(...) make sure not to choose - * names conflicting with these definitions. - */ -const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" - << "+" << "-" << "*" << "/" << "^" << "&&" - << "||" << "=" << "(" << ")" << "?" << ":"; - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Constructor. - * @param a_szFormula the formula to interpret. - * @throw ParserException if a_szFormula is null. - */ -QmuParserBase::QmuParserBase() - :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), - m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), - m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), - m_nFinalResultIdx(0) -{ - InitTokenReader(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Copy constructor. - * - * Tha parser can be safely copy constructed but the bytecode is reset during copy construction. - */ -QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) - :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), - m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), - m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), - m_nFinalResultIdx(0) -{ - m_pTokenReader.reset(new token_reader_type(this)); - Assign(a_Parser); -} - -//---------------------------------------------------------------------------------------------------------------------- -QmuParserBase::~QmuParserBase() -{} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Assignement operator. - * - * Implemented by calling Assign(a_Parser). Self assignement is suppressed. - * @param a_Parser Object to copy to this. - * @return *this - * @throw nothrow - */ -QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) -{ - Assign(a_Parser); - return *this; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Copy state of a parser object to this. - * - * Clears Variables and Functions of this parser. - * Copies the states of all internal variables. - * Resets parse function to string parse mode. - * - * @param a_Parser the source object. - */ -void QmuParserBase::Assign(const QmuParserBase &a_Parser) -{ - if (&a_Parser==this) - { - return; - } - - // Don't copy bytecode instead cause the parser to create new bytecode - // by resetting the parse function. - ReInit(); - - m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants - m_VarDef = a_Parser.m_VarDef; // Copy user defined variables - m_bBuiltInOp = a_Parser.m_bBuiltInOp; - m_vStringBuf = a_Parser.m_vStringBuf; - m_vStackBuffer = a_Parser.m_vStackBuffer; - m_nFinalResultIdx = a_Parser.m_nFinalResultIdx; - m_StrVarDef = a_Parser.m_StrVarDef; - m_vStringVarBuf = a_Parser.m_vStringVarBuf; - m_nIfElseCounter = a_Parser.m_nIfElseCounter; - m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this)); - - // Copy function and operator callbacks - m_FunDef = a_Parser.m_FunDef; // Copy function definitions - m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators - m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation - m_OprtDef = a_Parser.m_OprtDef; // binary operators - - m_sNameChars = a_Parser.m_sNameChars; - m_sOprtChars = a_Parser.m_sOprtChars; - m_sInfixOprtChars = a_Parser.m_sInfixOprtChars; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Set the decimal separator. - * @param cDecSep Decimal separator as a character value. - * @sa SetThousandsSep - * - * By default muparser uses the "C" locale. The decimal separator of this - * locale is overwritten by the one provided here. - */ -void QmuParserBase::SetDecSep(char_type cDecSep) -{ - char_type cThousandsSep = std::use_facet< change_dec_sep >(s_locale).thousands_sep(); - s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Sets the thousands operator. - * @param cThousandsSep The thousands separator as a character - * @sa SetDecSep - * - * By default muparser uses the "C" locale. The thousands separator of this - * locale is overwritten by the one provided here. - */ -void QmuParserBase::SetThousandsSep(char_type cThousandsSep) -{ - char_type cDecSep = std::use_facet< change_dec_sep >(s_locale).decimal_point(); - s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Resets the locale. - * - * The default locale used "." as decimal separator, no thousands separator and "," as function argument separator. - */ -void QmuParserBase::ResetLocale() -{ - s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); - SetArgSep(','); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Initialize the token reader. - * - * Create new token reader object and submit pointers to function, operator, constant and variable definitions. - * - * @post m_pTokenReader.get()!=0 - * @throw nothrow - */ -void QmuParserBase::InitTokenReader() -{ - m_pTokenReader.reset(new token_reader_type(this)); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Reset parser to string parsing mode and clear internal buffers. - * - * Clear bytecode, reset the token reader. - * @throw nothrow - */ -void QmuParserBase::ReInit() const -{ - m_pParseFormula = &QmuParserBase::ParseString; - m_vStringBuf.clear(); - m_vRPN.clear(); - m_pTokenReader->ReInit(); - m_nIfElseCounter = 0; -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) -{ - Q_UNUSED(pExpr); - Q_UNUSED(nStart); - Q_UNUSED(nEnd); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Returns the version of muparser. - * @param eInfo A flag indicating whether the full version info should be returned or not. - * - * Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS are returned only if eInfo==pviFULL. - */ -QString QmuParserBase::GetVersion(EParserVersionInfo eInfo) const -{ - QString versionInfo; - QTextStream ss(&versionInfo); - - ss << QMUP_VERSION; - - if (eInfo==pviFULL) - { - ss << " (" << QMUP_VERSION_DATE; - ss << "; " << sizeof(void*)*8 << "BIT"; - - #ifdef _DEBUG - ss << "; DEBUG"; - #else - ss << "; RELEASE"; - #endif - - #ifdef _UNICODE - ss << "; UNICODE"; - #else - #ifdef _MBCS - ss << "; MBCS"; - #else - ss << "; ASCII"; - #endif - #endif - - #ifdef QMUP_USE_OPENMP - ss << "; OPENMP"; - //#else - // ss << "; NO_OPENMP"; - #endif - - #if defined(MUP_MATH_EXCEPTIONS) - ss << "; MATHEXC"; - //#else - // ss << "; NO_MATHEXC"; - #endif - - ss << ")"; - } - return versionInfo; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a value parsing function. - * - * When parsing an expression muParser tries to detect values in the expression string using different valident - * callbacks. Thuis it's possible to parse for hex values, binary values and floating point values. - */ -void QmuParserBase::AddValIdent(identfun_type a_pCallback) -{ - m_pTokenReader->AddValIdent(a_pCallback); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Set a function that can create variable pointer for unknown expression variables. - * @param a_pFactory A pointer to the variable factory. - * @param pUserData A user defined context pointer. - */ -void QmuParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData) -{ - m_pTokenReader->SetVarCreator(a_pFactory, pUserData); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a function or operator callback to the parser. - */ -void QmuParserBase::AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, - funmap_type &a_Storage, const QString &a_szCharSet ) -{ - if (a_Callback.GetAddr()==0) - { - Error(ecINVALID_FUN_PTR); - } - - const funmap_type *pFunMap = &a_Storage; - - // Check for conflicting operator or function names - if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() ) - { - Error(ecNAME_CONFLICT, -1, a_strName); - } - - if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() ) - { - Error(ecNAME_CONFLICT, -1, a_strName); - } - - if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() ) - { - Error(ecNAME_CONFLICT, -1, a_strName); - } - - if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() ) - { - Error(ecNAME_CONFLICT, -1, a_strName); - } - - CheckOprt(a_strName, a_Callback, a_szCharSet); - a_Storage[a_strName] = a_Callback; - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Check if a name contains invalid characters. - * - * @throw ParserException if the name contains invalid charakters. - */ -void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const QString &a_szCharSet) const -{ -#if defined(_UNICODE) - const std::wstring a_sNameStd = a_sName.toStdWString(); - const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); -#else - const std::string a_sNameStd = a_sName.toStdString(); - const std::string a_szCharSetStd = a_szCharSet.toStdString(); -#endif - if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || - (a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9')) - { - switch(a_Callback.GetCode()) - { - case cmOPRT_POSTFIX: - Error(ecINVALID_POSTFIX_IDENT, -1, a_sName); - break; - case cmOPRT_INFIX: - Error(ecINVALID_INFIX_IDENT, -1, a_sName); - break; - case cmLE: - Q_UNREACHABLE(); - break; - case cmGE: - Q_UNREACHABLE(); - break; - case cmNEQ: - Q_UNREACHABLE(); - break; - case cmEQ: - Q_UNREACHABLE(); - break; - case cmLT: - Q_UNREACHABLE(); - break; - case cmGT: - Q_UNREACHABLE(); - break; - case cmADD: - Q_UNREACHABLE(); - break; - case cmSUB: - Q_UNREACHABLE(); - break; - case cmMUL: - Q_UNREACHABLE(); - break; - case cmDIV: - Q_UNREACHABLE(); - break; - case cmPOW: - Q_UNREACHABLE(); - break; - case cmLAND: - Q_UNREACHABLE(); - break; - case cmLOR: - Q_UNREACHABLE(); - break; - case cmASSIGN: - Q_UNREACHABLE(); - break; - case cmBO: - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - case cmIF: - Q_UNREACHABLE(); - break; - case cmELSE: - Q_UNREACHABLE(); - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVAR: - Q_UNREACHABLE(); - break; - case cmVAL: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmFUNC: - Q_UNREACHABLE(); - break; - case cmFUNC_STR: - Q_UNREACHABLE(); - break; - case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_BIN: - Q_UNREACHABLE(); - break; - case cmEND: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - Error(ecINVALID_NAME, -1, a_sName); - break; - } - } -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Check if a name contains invalid characters. - * - * @throw ParserException if the name contains invalid charakters. - */ -void QmuParserBase::CheckName(const QString &a_sName, const QString &a_szCharSet) const -{ -#if defined(_UNICODE) - std::wstring a_sNameStd = a_sName.toStdWString(); - std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); -#else - std::string a_sNameStd = a_sName.toStdString(); - std::string a_szCharSetStd = a_szCharSet.toStdString(); -#endif - if ( !a_sNameStd.length() || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || - (a_sNameStd[0]>='0' && a_sNameStd[0]<='9')) - { - Error(ecINVALID_NAME); - } -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Set the formula. - * @param a_strFormula Formula as string_type - * @throw ParserException in case of syntax errors. - * - * Triggers first time calculation thus the creation of the bytecode and scanning of used variables. - */ -void QmuParserBase::SetExpr(const QString &a_sExpr) -{ - // Check locale compatibility - std::locale loc; - if (m_pTokenReader->GetArgSep()==std::use_facet >(loc).decimal_point()) - { - Error(ecLOCALE); - } - - // 20060222: Bugfix for Borland-Kylix: - // adding a space to the expression will keep Borlands KYLIX from going wild - // when calling tellg on a stringstream created from the expression after - // reading a value at the end of an expression. (qmu::QmuParser::IsVal function) - // (tellg returns -1 otherwise causing the parser to ignore the value) - QString sBuf(a_sExpr + " " ); - m_pTokenReader->SetFormula(sBuf); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Get the default symbols used for the built in operators. - * @sa c_DefaultOprt - */ -const QStringList &QmuParserBase::GetOprtDef() const -{ - return c_DefaultOprt; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Define the set of valid characters to be used in names of functions, variables, constants. - */ -void QmuParserBase::DefineNameChars(const QString &a_szCharset) -{ - m_sNameChars = a_szCharset; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Define the set of valid characters to be used in names of binary operators and postfix operators. - */ -void QmuParserBase::DefineOprtChars(const QString &a_szCharset) -{ - m_sOprtChars = a_szCharset; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Define the set of valid characters to be used in names of infix operators. - */ -void QmuParserBase::DefineInfixOprtChars(const QString &a_szCharset) -{ - m_sInfixOprtChars = a_szCharset; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Virtual function that defines the characters allowed in name identifiers. - * @sa #ValidOprtChars, #ValidPrefixOprtChars - */ -const QString& QmuParserBase::ValidNameChars() const -{ - assert(m_sNameChars.size()); - return m_sNameChars; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Virtual function that defines the characters allowed in operator definitions. - * @sa #ValidNameChars, #ValidPrefixOprtChars - */ -const QString &QmuParserBase::ValidOprtChars() const -{ - assert(m_sOprtChars.size()); - return m_sOprtChars; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Virtual function that defines the characters allowed in infix operator definitions. - * @sa #ValidNameChars, #ValidOprtChars - */ -const QString &QmuParserBase::ValidInfixOprtChars() const -{ - assert(m_sInfixOprtChars.size()); - return m_sInfixOprtChars; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a user defined operator. - * @post Will reset the Parser to string parsing mode. - */ -void QmuParserBase::DefinePostfixOprt(const QString &a_sName, fun_type1 a_pFun, bool a_bAllowOpt) -{ - AddCallback(a_sName, QmuParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX), m_PostOprtDef, - ValidOprtChars() ); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Initialize user defined functions. - * - * Calls the virtual functions InitFun(), InitConst() and InitOprt(). - */ -void QmuParserBase::Init() -{ - InitCharSets(); - InitFun(); - InitConst(); - InitOprt(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a user defined operator. - * @post Will reset the Parser to string parsing mode. - * @param [in] a_sName operator Identifier - * @param [in] a_pFun Operator callback function - * @param [in] a_iPrec Operator Precedence (default=prSIGN) - * @param [in] a_bAllowOpt True if operator is volatile (default=false) - * @sa EPrec - */ -void QmuParserBase::DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec, bool a_bAllowOpt) -{ - AddCallback(a_sName, QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), m_InfixOprtDef, - ValidInfixOprtChars() ); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Define a binary operator. - * @param [in] a_sName The identifier of the operator. - * @param [in] a_pFun Pointer to the callback function. - * @param [in] a_iPrec Precedence of the operator. - * @param [in] a_eAssociativity The associativity of the operator. - * @param [in] a_bAllowOpt If this is true the operator may be optimized away. - * - * Adds a new Binary operator the the parser instance. - */ -void QmuParserBase::DefineOprt( const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec, - EOprtAssociativity a_eAssociativity, bool a_bAllowOpt ) -{ - // Check for conflicts with built in operator names - for (int i=0; m_bBuiltInOp && iIgnoreUndefVar(true); - CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it - // may contain references to nonexisting variables. - m_pParseFormula = &QmuParserBase::ParseString; - m_pTokenReader->IgnoreUndefVar(false); - } - catch(exception_type &e) - { - // Make sure to stay in string parse mode, dont call ReInit() - // because it deletes the array with the used variables - m_pParseFormula = &QmuParserBase::ParseString; - m_pTokenReader->IgnoreUndefVar(false); - throw e; - } - return m_pTokenReader->GetUsedVar(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Return a map containing the used variables only. - */ -const varmap_type& QmuParserBase::GetVar() const -{ - return m_VarDef; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Return a map containing all parser constants. - */ -const valmap_type& QmuParserBase::GetConst() const -{ - return m_ConstDef; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Return prototypes of all parser functions. - * @return #m_FunDef - * @sa FunProt - * @throw nothrow - * - * The return type is a map of the public type #funmap_type containing the prototype definitions for all numerical - * parser functions. String functions are not part of this map. The Prototype definition is encapsulated in objects - * of the class FunProt one per parser function each associated with function names via a map construct. - */ -const funmap_type& QmuParserBase::GetFunDef() const -{ - return m_FunDef; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Retrieve the formula. - */ -const QString& QmuParserBase::GetExpr() const -{ - return m_pTokenReader->GetExpr(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Execute a function that takes a single string argument. - * @param a_FunTok Function token. - * @throw exception_type If the function token is not a string function - */ -QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, - const QVector &a_vArg) const -{ - if (a_vArg.back().GetCode()!=cmSTRING) - { - Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); - } - - token_type valTok; - generic_fun_type pFunc = a_FunTok.GetFuncAddr(); - assert(pFunc); - - try - { - // Check function arguments; write dummy value into valtok to represent the result - switch(a_FunTok.GetArgCount()) - { - case 0: - valTok.SetVal(1); - a_vArg[0].GetAsString(); - break; - case 1: - valTok.SetVal(1); - a_vArg[1].GetAsString(); - a_vArg[0].GetVal(); - break; - case 2: - valTok.SetVal(1); - a_vArg[2].GetAsString(); - a_vArg[1].GetVal(); - a_vArg[0].GetVal(); - break; - default: - Error(ecINTERNAL_ERROR); - break; - } - } - catch(QmuParserError& ) - { - Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); - } - - // string functions won't be optimized - m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx()); - - // Push dummy value representing the function result to the stack - return valTok; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Apply a function token. - * @param iArgCount Number of Arguments actually gathered used only for multiarg functions. - * @post The result is pushed to the value stack - * @post The function token is removed from the stack - * @throw exception_type if Argument count does not mach function requirements. - */ -void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const -{ - assert(m_pTokenReader.get()); - - // Operator stack empty or does not contain tokens with callback functions - if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 ) - { - return; - } - - token_type funTok = a_stOpt.pop(); - assert(funTok.GetFuncAddr()); - - // Binary operators must rely on their internal operator number - // since counting of operators relies on commas for function arguments - // binary operators do not have commas in their expression - int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount; - - // determine how many parameters the function needs. To remember iArgCount includes the - // string parameter whilst GetArgCount() counts only numeric parameters. - int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0); - - // Thats the number of numerical parameters - int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0); - - if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1) - { - Error(ecINTERNAL_ERROR); - } - - if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) - { - Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); - } - - if (funTok.GetCode()!=cmOPRT_BIN && iArgCountGetPos()-1, funTok.GetAsString()); - } - - if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired ) - { - Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); - } - - // Collect the numeric function arguments from the value stack and store them - // in a vector - QVector stArg; - for (int i=0; iGetPos(), funTok.GetAsString()); - } - } - - switch(funTok.GetCode()) - { - case cmFUNC_STR: - stArg.push_back(a_stVal.pop()); - - if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) - { - Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); - } - - ApplyStrFunc(funTok, stArg); - break; - case cmFUNC_BULK: - m_vRPN.AddBulkFun(funTok.GetFuncAddr(), stArg.size()); - break; - case cmOPRT_BIN: - case cmOPRT_POSTFIX: - case cmOPRT_INFIX: - case cmFUNC: - if (funTok.GetArgCount()==-1 && iArgCount==0) - { - Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); - } - - m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); - break; - case cmLE: - Q_UNREACHABLE(); - break; - case cmGE: - Q_UNREACHABLE(); - break; - case cmNEQ: - Q_UNREACHABLE(); - break; - case cmEQ: - Q_UNREACHABLE(); - break; - case cmLT: - Q_UNREACHABLE(); - break; - case cmGT: - Q_UNREACHABLE(); - break; - case cmADD: - Q_UNREACHABLE(); - break; - case cmSUB: - Q_UNREACHABLE(); - break; - case cmMUL: - Q_UNREACHABLE(); - break; - case cmDIV: - Q_UNREACHABLE(); - break; - case cmPOW: - Q_UNREACHABLE(); - break; - case cmLAND: - Q_UNREACHABLE(); - break; - case cmLOR: - Q_UNREACHABLE(); - break; - case cmASSIGN: - Q_UNREACHABLE(); - break; - case cmBO: - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - case cmIF: - Q_UNREACHABLE(); - break; - case cmELSE: - Q_UNREACHABLE(); - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVAR: - Q_UNREACHABLE(); - break; - case cmVAL: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmEND: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - break; - } - // Push dummy value representing the function result to the stack - token_type token; - token.SetVal(1); - a_stVal.push(token); -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const -{ - // Check if there is an if Else clause to be calculated - while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) - { - token_type opElse = a_stOpt.pop(); - Q_ASSERT(a_stOpt.size()>0); - - // Take the value associated with the else branch from the value stack - token_type vVal2 = a_stVal.pop(); - - Q_ASSERT(a_stOpt.size()>0); - Q_ASSERT(a_stVal.size()>=2); - - // it then else is a ternary operator Pop all three values from the value s - // tack and just return the right value - token_type vVal1 = a_stVal.pop(); - token_type vExpr = a_stVal.pop(); - - a_stVal.push( (qFuzzyCompare(vExpr.GetVal()+1, 1+0)==false) ? vVal1 : vVal2); - - token_type opIf = a_stOpt.pop(); - Q_ASSERT(opElse.GetCode()==cmELSE); - Q_ASSERT(opIf.GetCode()==cmIF); - - m_vRPN.AddIfElse(cmENDIF); - } // while pending if-else-clause found -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Performs the necessary steps to write code for the execution of binary operators into the bytecode. - */ -void QmuParserBase::ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const -{ - // is it a user defined binary operator? - if (a_stOpt.top().GetCode()==cmOPRT_BIN) - { - ApplyFunc(a_stOpt, a_stVal, 2); - } - else - { - Q_ASSERT(a_stVal.size()>=2); - token_type valTok1 = a_stVal.pop(), - valTok2 = a_stVal.pop(), - optTok = a_stOpt.pop(), - resTok; - - if ( valTok1.GetType()!=valTok2.GetType() || (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) ) - { - Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString()); - } - - if (optTok.GetCode()==cmASSIGN) - { - if (valTok2.GetCode()!=cmVAR) - { - Error(ecUNEXPECTED_OPERATOR, -1, "="); - } - m_vRPN.AddAssignOp(valTok2.GetVar()); - } - else - { - m_vRPN.AddOp(optTok.GetCode()); - } - resTok.SetVal(1); - a_stVal.push(resTok); - } -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Apply a binary operator. - * @param a_stOpt The operator stack - * @param a_stVal The value stack - */ -void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStack &stVal) const -{ - while (stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmIF) - { - token_type tok = stOpt.top(); - switch (tok.GetCode()) - { - case cmOPRT_INFIX: - case cmOPRT_BIN: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmLT: - case cmGT: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: - case cmPOW: - case cmLAND: - case cmLOR: - case cmASSIGN: - if (stOpt.top().GetCode()==cmOPRT_INFIX) - { - ApplyFunc(stOpt, stVal, 1); - } - else - { - ApplyBinOprt(stOpt, stVal); - } - break; - case cmELSE: - ApplyIfElse(stOpt, stVal); - break; - case cmBO: - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - case cmIF: - Q_UNREACHABLE(); - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVAR: - Q_UNREACHABLE(); - break; - case cmVAL: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmFUNC: - Q_UNREACHABLE(); - break; - case cmFUNC_STR: - Q_UNREACHABLE(); - break; - case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; - case cmEND: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - Error(ecINTERNAL_ERROR); - break; - } - } -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Parse the command code. - * @sa ParseString(...) - * - * Command code contains precalculated stack positions of the values and the associated operators. The Stack is - * filled beginning from index one the value at index zero is not used at all. - */ -qreal QmuParserBase::ParseCmdCode() const -{ - return ParseCmdCodeBulk(0, 0); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Evaluate the RPN. - * @param nOffset The offset added to variable addresses (for bulk mode) - * @param nThreadID OpenMP Thread id of the calling thread - */ -qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const -{ - assert(nThreadID<=s_MaxNumOpenMPThreads); - - // Note: The check for nOffset==0 and nThreadID here is not necessary but - // brings a minor performance gain when not in bulk mode. - qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * - (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; - qreal buf; - int sidx(0); - for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) - { - switch (pTok->Cmd) - { - // built in binary operators - case cmLE: - --sidx; - Stack[sidx] = Stack[sidx] <= Stack[sidx+1]; - continue; - case cmGE: - --sidx; - Stack[sidx] = Stack[sidx] >= Stack[sidx+1]; - continue; - case cmNEQ: - --sidx; - Stack[sidx] = (qFuzzyCompare(Stack[sidx], Stack[sidx+1])==false); - continue; - case cmEQ: - --sidx; - Stack[sidx] = qFuzzyCompare(Stack[sidx], Stack[sidx+1]); - continue; - case cmLT: - --sidx; - Stack[sidx] = Stack[sidx] < Stack[sidx+1]; - continue; - case cmGT: - --sidx; - Stack[sidx] = Stack[sidx] > Stack[sidx+1]; - continue; - case cmADD: - --sidx; - Stack[sidx] += Stack[1+sidx]; - continue; - case cmSUB: - --sidx; - Stack[sidx] -= Stack[1+sidx]; - continue; - case cmMUL: - --sidx; - Stack[sidx] *= Stack[1+sidx]; - continue; - case cmDIV: - --sidx; - #if defined(MUP_MATH_EXCEPTIONS) - if (Stack[1+sidx]==0) - { - Error(ecDIV_BY_ZERO); - } - #endif - Stack[sidx] /= Stack[1+sidx]; - continue; - case cmPOW: - --sidx; - Stack[sidx] = qPow(Stack[sidx], Stack[1+sidx]); - continue; - case cmLAND: - --sidx; -#ifdef Q_CC_GNU - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - Stack[sidx] = Stack[sidx] && Stack[sidx+1]; -#ifdef Q_CC_GNU - #pragma GCC diagnostic pop -#endif - continue; - case cmLOR: - --sidx; -#ifdef Q_CC_GNU - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - Stack[sidx] = Stack[sidx] || Stack[sidx+1]; -#ifdef Q_CC_GNU - #pragma GCC diagnostic pop -#endif - continue; - case cmASSIGN: - --sidx; - Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; - continue; - case cmBO: // unused, listed for compiler optimization purposes - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; - case cmIF: - if (qFuzzyCompare(Stack[sidx--]+1, 1+0)) - { - pTok += pTok->Oprt.offset; - } - continue; - case cmELSE: - pTok += pTok->Oprt.offset; - continue; - case cmENDIF: - continue; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; - - // value and variable tokens - case cmVAR: - Stack[++sidx] = *(pTok->Val.ptr + nOffset); - continue; - case cmVAL: - Stack[++sidx] = pTok->Val.data2; - continue; - case cmVARPOW2: - buf = *(pTok->Val.ptr + nOffset); - Stack[++sidx] = buf*buf; - continue; - case cmVARPOW3: - buf = *(pTok->Val.ptr + nOffset); - Stack[++sidx] = buf*buf*buf; - continue; - case cmVARPOW4: - buf = *(pTok->Val.ptr + nOffset); - Stack[++sidx] = buf*buf*buf*buf; - continue; - case cmVARMUL: - Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2; - continue; - // Next is treatment of numeric functions - case cmFUNC: - { - int iArgCount = pTok->Fun.argc; - - // switch according to argument count - switch(iArgCount) - { - case 0: - sidx += 1; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(); - continue; - case 1: - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx]); - continue; - case 2: - sidx -= 1; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1]); - continue; - case 3: - sidx -= 2; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2]); - continue; - case 4: - sidx -= 3; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3]); - continue; - case 5: - sidx -= 4; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); - continue; - case 6: - sidx -= 5; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); - continue; - case 7: - sidx -= 6; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); - continue; - case 8: - sidx -= 7; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], - Stack[sidx+7]); - continue; - case 9: - sidx -= 8; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], - Stack[sidx+7], Stack[sidx+8]); - continue; - case 10: - sidx -= 9; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], - Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], - Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); - continue; - default: - if (iArgCount>0) // function with variable arguments store the number as a negative value - { - Error(ecINTERNAL_ERROR, 1); - } - - sidx -= -iArgCount - 1; - Stack[sidx] =(*reinterpret_cast(pTok->Fun.ptr))(&Stack[sidx], -iArgCount); - continue; - } - } - // Next is treatment of string functions - case cmFUNC_STR: - { - sidx -= pTok->Fun.argc -1; - - // The index of the string argument in the string table - int iIdxStack = pTok->Fun.idx; - Q_ASSERT( iIdxStack>=0 && iIdxStackFun.argc) // switch according to argument count - { - case 0: - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack)); - continue; - case 1: - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), - Stack[sidx]); - continue; - case 2: - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), - Stack[sidx], Stack[sidx+1]); - continue; - default: - break; - } - - continue; - } - case cmFUNC_BULK: - { - int iArgCount = pTok->Fun.argc; - - // switch according to argument count - switch(iArgCount) - { - case 0: - sidx += 1; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID); - continue; - case 1: - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, - Stack[sidx]); - continue; - case 2: - sidx -= 1; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1]); - continue; - case 3: - sidx -= 2; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2]); - continue; - case 4: - sidx -= 3; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); - continue; - case 5: - sidx -= 4; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], - Stack[sidx+4]); - continue; - case 6: - sidx -= 5; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2], - Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); - continue; - case 7: - sidx -= 6; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], - Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); - continue; - case 8: - sidx -= 7; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], - Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); - continue; - case 9: - sidx -= 8; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], - Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], - Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); - continue; - case 10: - sidx -= 9; - Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, - Stack[sidx], - Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], - Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], - Stack[sidx+9]); - continue; - default: - Error(ecINTERNAL_ERROR, 2); - continue; - } - } - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_BIN: - Q_UNREACHABLE(); - break; - case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; - case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; - case cmEND: - Q_UNREACHABLE(); - break; - // return Stack[m_nFinalResultIdx]; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - Error(ecINTERNAL_ERROR, 3); - return 0; - } // switch CmdCode - } // for all bytecode tokens - - return Stack[m_nFinalResultIdx]; -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::CreateRPN() const -{ - if (!m_pTokenReader->GetExpr().length()) - { - Error(ecUNEXPECTED_EOF, 0); - } - - QStack stOpt, stVal; - QStack stArgCount; - token_type opta, opt; // for storing operators - token_type val, tval; // for storing value - string_type strBuf; // buffer for string function arguments - - ReInit(); - - // The outermost counter counts the number of seperated items - // such as in "a=10,b=20,c=c+a" - stArgCount.push(1); - - for(;;) - { - opt = m_pTokenReader->ReadNextToken(); - - switch (opt.GetCode()) - { - // - // Next three are different kind of value entries - // - case cmSTRING: - opt.SetIdx(m_vStringBuf.size()); // Assign buffer index to token - stVal.push(opt); - m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer - break; - case cmVAR: - stVal.push(opt); - m_vRPN.AddVar( static_cast(opt.GetVar()) ); - break; - case cmVAL: - stVal.push(opt); - m_vRPN.AddVal( opt.GetVal() ); - break; - case cmELSE: - m_nIfElseCounter--; - if (m_nIfElseCounter<0) - { - Error(ecMISPLACED_COLON, m_pTokenReader->GetPos()); - } - ApplyRemainingOprt(stOpt, stVal); - m_vRPN.AddIfElse(cmELSE); - stOpt.push(opt); - break; - case cmARG_SEP: - if (stArgCount.empty()) - { - Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); - } - ++stArgCount.top(); - // fallthrough intentional (no break!) - case cmEND: - ApplyRemainingOprt(stOpt, stVal); - break; - case cmBC: - { - // The argument count for parameterless functions is zero - // by default an opening bracket sets parameter count to 1 - // in preparation of arguments to come. If the last token - // was an opening bracket we know better... - if (opta.GetCode()==cmBO) - { - --stArgCount.top(); - } - - ApplyRemainingOprt(stOpt, stVal); - - // Check if the bracket content has been evaluated completely - if (stOpt.size() && stOpt.top().GetCode()==cmBO) - { - // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check - // if there is either a function or a sign pending - // neither the opening nor the closing bracket will be pushed back to - // the operator stack - // Check if a function is standing in front of the opening bracket, - // if yes evaluate it afterwards check for infix operators - assert(stArgCount.size()); - int iArgCount = stArgCount.pop(); - - stOpt.pop(); // Take opening bracket from stack - - if (iArgCount>1 && ( stOpt.size()==0 || (stOpt.top().GetCode()!=cmFUNC && - stOpt.top().GetCode()!=cmFUNC_BULK && - stOpt.top().GetCode()!=cmFUNC_STR) ) ) - { - Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos()); - } - - // The opening bracket was popped from the stack now check if there - // was a function before this bracket - if (stOpt.size() && stOpt.top().GetCode()!=cmOPRT_INFIX && stOpt.top().GetCode()!=cmOPRT_BIN && - stOpt.top().GetFuncAddr()!=0) - { - ApplyFunc(stOpt, stVal, iArgCount); - } - } - } // if bracket content is evaluated - break; - // - // Next are the binary operator entries - // - //case cmAND: // built in binary operators - //case cmOR: - //case cmXOR: - case cmIF: - m_nIfElseCounter++; - // fallthrough intentional (no break!) - case cmLAND: - case cmLOR: - case cmLT: - case cmGT: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: - case cmPOW: - case cmASSIGN: - case cmOPRT_BIN: - // A binary operator (user defined or built in) has been found. - while ( stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmELSE && - stOpt.top().GetCode() != cmIF) - { - int nPrec1 = GetOprtPrecedence(stOpt.top()), - nPrec2 = GetOprtPrecedence(opt); - - if (stOpt.top().GetCode()==opt.GetCode()) - { - // Deal with operator associativity - EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt); - if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || - (eOprtAsct==oaLEFT && (nPrec1 < nPrec2)) ) - { - break; - } - } - else if (nPrec1 < nPrec2) - { - // In case the operators are not equal the precedence decides alone... - break; - } - if (stOpt.top().GetCode()==cmOPRT_INFIX) - { - ApplyFunc(stOpt, stVal, 1); - } - else - { - ApplyBinOprt(stOpt, stVal); - } - } // while ( ... ) - - if (opt.GetCode()==cmIF) - { - m_vRPN.AddIfElse(opt.GetCode()); - } - - // The operator can't be evaluated right now, push back to the operator stack - stOpt.push(opt); - break; - // - // Last section contains functions and operators implicitely mapped to functions - // - case cmBO: - stArgCount.push(1); - stOpt.push(opt); - break; - case cmOPRT_INFIX: - case cmFUNC: - case cmFUNC_BULK: - case cmFUNC_STR: - stOpt.push(opt); - break; - case cmOPRT_POSTFIX: - stOpt.push(opt); - ApplyFunc(stOpt, stVal, 1); // this is the postfix operator - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - Error(ecINTERNAL_ERROR, 3); - } // end of switch operator-token - - opta = opt; - - if ( opt.GetCode() == cmEND ) - { - m_vRPN.Finalize(); - break; - } - - if (QmuParserBase::g_DbgDumpStack) - { - StackDump(stVal, stOpt); - m_vRPN.AsciiDump(); - } - } // while (true) - - if (QmuParserBase::g_DbgDumpCmdCode) - { - m_vRPN.AsciiDump(); - } - - if (m_nIfElseCounter>0) - { - Error(ecMISSING_ELSE_CLAUSE); - } - - // get the last value (= final result) from the stack - Q_ASSERT(stArgCount.size()==1); - m_nFinalResultIdx = stArgCount.top(); - if (m_nFinalResultIdx==0) - { - Error(ecINTERNAL_ERROR, 9); - } - - if (stVal.size()==0) - { - Error(ecEMPTY_EXPRESSION); - } - - if (stVal.top().GetType()!=tpDBL) - { - Error(ecSTR_RESULT); - } - - m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief One of the two main parse functions. - * @sa ParseCmdCode(...) - * - * Parse expression from input string. Perform syntax checking and create bytecode. After parsing the string and - * creating the bytecode the function pointer #m_pParseFormula will be changed to the second parse routine the - * uses bytecode instead of string parsing. - */ -qreal QmuParserBase::ParseString() const -{ - try - { - CreateRPN(); - m_pParseFormula = &QmuParserBase::ParseCmdCode; - return (this->*m_pParseFormula)(); - } - catch(QmuParserError &exc) - { - exc.SetFormula(m_pTokenReader->GetExpr()); - throw; - } -} - -//---------------------------------------------------------------------------------------------------------------------- -/** -* @brief Create an error containing the parse error position. -* -* This function will create an Parser Exception object containing the error text and its position. -* -* @param a_iErrc [in] The error code of type #EErrorCodes. -* @param a_iPos [in] The position where the error was detected. -* @param a_strTok [in] The token string representation associated with the error. -* @throw ParserException always throws thats the only purpose of this function. -*/ -void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const -{ - throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear all user defined variables. - * @throw nothrow - * - * Resets the parser to string parsing mode by calling #ReInit. - */ -void QmuParserBase::ClearVar() -{ - m_VarDef.clear(); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Remove a variable from internal storage. - * @throw nothrow - * - * Removes a variable if it exists. If the Variable does not exist nothing will be done. - */ -void QmuParserBase::RemoveVar(const QString &a_strVarName) -{ - varmap_type::iterator item = m_VarDef.find(a_strVarName); - if (item!=m_VarDef.end()) - { - m_VarDef.erase(item); - ReInit(); - } -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear all functions. - * @post Resets the parser to string parsing mode. - * @throw nothrow - */ -void QmuParserBase::ClearFun() -{ - m_FunDef.clear(); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear all user defined constants. - * - * Both numeric and string constants will be removed from the internal storage. - * @post Resets the parser to string parsing mode. - * @throw nothrow - */ -void QmuParserBase::ClearConst() -{ - m_ConstDef.clear(); - m_StrVarDef.clear(); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear all user defined postfix operators. - * @post Resets the parser to string parsing mode. - * @throw nothrow - */ -void QmuParserBase::ClearPostfixOprt() -{ - m_PostOprtDef.clear(); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear all user defined binary operators. - * @post Resets the parser to string parsing mode. - * @throw nothrow - */ -void QmuParserBase::ClearOprt() -{ - m_OprtDef.clear(); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Clear the user defined Prefix operators. - * @post Resets the parser to string parser mode. - * @throw nothrow - */ -void QmuParserBase::ClearInfixOprt() -{ - m_InfixOprtDef.clear(); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Enable or disable the formula optimization feature. - * @post Resets the parser to string parser mode. - * @throw nothrow - */ -void QmuParserBase::EnableOptimizer(bool a_bIsOn) -{ - m_vRPN.EnableOptimizer(a_bIsOn); - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Enable the dumping of bytecode amd stack content on the console. - * @param bDumpCmd Flag to enable dumping of the current bytecode to the console. - * @param bDumpStack Flag to enable dumping of the stack content is written to the console. - * - * This function is for debug purposes only! - */ -void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) -{ - QmuParserBase::g_DbgDumpCmdCode = bDumpCmd; - QmuParserBase::g_DbgDumpStack = bDumpStack; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Enable or disable the built in binary operators. - * @throw nothrow - * @sa m_bBuiltInOp, ReInit() - * - * If you disable the built in binary operators there will be no binary operators defined. Thus you must add them - * manually one by one. It is not possible to disable built in operators selectively. This function will Reinitialize - * the parser by calling ReInit(). - */ -void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) -{ - m_bBuiltInOp = a_bIsOn; - ReInit(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Query status of built in variables. - * @return #m_bBuiltInOp; true if built in operators are enabled. - * @throw nothrow - */ -bool QmuParserBase::HasBuiltInOprt() const -{ - return m_bBuiltInOp; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Get the argument separator character. - */ -QChar QmuParserBase::GetArgSep() const -{ - return m_pTokenReader->GetArgSep(); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Set argument separator. - * @param cArgSep the argument separator character. - */ -void QmuParserBase::SetArgSep(char_type cArgSep) -{ - m_pTokenReader->SetArgSep(cArgSep); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Dump stack content. - * - * This function is used for debugging only. - */ -void QmuParserBase::StackDump(const QStack &a_stVal, const QStack &a_stOprt) const -{ - QStack stOprt(a_stOprt), - stVal(a_stVal); - - qDebug() << "\nValue stack:\n"; - while ( !stVal.empty() ) - { - token_type val = stVal.pop(); - if (val.GetType()==tpSTR) - { - qDebug() << " \"" << val.GetAsString() << "\" "; - } - else - { - qDebug() << " " << val.GetVal() << " "; - } - } - qDebug() << "\nOperator stack:\n"; - - while ( !stOprt.empty() ) - { - if (stOprt.top().GetCode()<=cmASSIGN) - { - qDebug() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << "\" \n"; - } - else - { - switch(stOprt.top().GetCode()) - { - case cmVAR: - qDebug() << "VAR\n"; - break; - case cmVAL: - qDebug() << "VAL\n"; - break; - case cmFUNC: - qDebug() << "FUNC \"" << stOprt.top().GetAsString() << "\"\n"; - break; - case cmFUNC_BULK: - qDebug() << "FUNC_BULK \"" << stOprt.top().GetAsString() << "\"\n"; - break; - case cmOPRT_INFIX: - qDebug() << "OPRT_INFIX \"" << stOprt.top().GetAsString() << "\"\n"; - break; - case cmOPRT_BIN: - qDebug() << "OPRT_BIN \"" << stOprt.top().GetAsString() << "\"\n"; - break; - case cmFUNC_STR: - qDebug() << "FUNC_STR\n"; - break; - case cmEND: - qDebug() << "END\n"; - break; - case cmUNKNOWN: - qDebug() << "UNKNOWN\n"; - break; - case cmBO: - qDebug() << "BRACKET \"(\"\n"; - break; - case cmBC: - qDebug() << "BRACKET \")\"\n"; - break; - case cmIF: - qDebug() << "IF\n"; - break; - case cmELSE: - qDebug() << "ELSE\n"; - break; - case cmENDIF: - qDebug() << "ENDIF\n"; - break; - case cmLE: - Q_UNREACHABLE(); - break; - case cmGE: - Q_UNREACHABLE(); - break; - case cmNEQ: - Q_UNREACHABLE(); - break; - case cmEQ: - Q_UNREACHABLE(); - break; - case cmLT: - Q_UNREACHABLE(); - break; - case cmGT: - Q_UNREACHABLE(); - break; - case cmADD: - Q_UNREACHABLE(); - break; - case cmSUB: - Q_UNREACHABLE(); - break; - case cmMUL: - Q_UNREACHABLE(); - break; - case cmDIV: - Q_UNREACHABLE(); - break; - case cmPOW: - Q_UNREACHABLE(); - break; - case cmLAND: - Q_UNREACHABLE(); - break; - case cmLOR: - Q_UNREACHABLE(); - break; - case cmASSIGN: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; - default: - qDebug() << stOprt.top().GetCode() << " "; - break; - } - } - stOprt.pop(); - } - qDebug() << dec; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** @brief Evaluate an expression containing comma seperated subexpressions - * @param [out] nStackSize The total number of results available - * @return Pointer to the array containing all expression results - * - * This member function can be used to retriev all results of an expression made up of multiple comma seperated - * subexpressions (i.e. "x+y,sin(x),cos(y)") - */ -qreal* QmuParserBase::Eval(int &nStackSize) const -{ - (this->*m_pParseFormula)(); - nStackSize = m_nFinalResultIdx; - - // (for historic reasons the stack starts at position 1) - return &m_vStackBuffer[1]; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Return the number of results on the calculation stack. - * - * If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). There mey be more than one return - * value. This function returns the number of available results. - */ -int QmuParserBase::GetNumResults() const -{ - return m_nFinalResultIdx; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Calculate the result. - * - * A note on const correctness: - * I consider it important that Calc is a const function. - * Due to caching operations Calc changes only the state of internal variables with one exception - * m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making - * Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. - * - * @pre A formula must be set. - * @pre Variables must have been set (if needed) - * - * @sa #m_pParseFormula - * @return The evaluation result - * @throw ParseException if no Formula is set or in case of any other error related to the formula. - */ -qreal QmuParserBase::Eval() const -{ - return (this->*m_pParseFormula)(); -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::Eval(qreal *results, int nBulkSize) -{ - CreateRPN(); - - int i = 0; - - #ifdef QMUP_USE_OPENMP - //#define DEBUG_OMP_STUFF - #ifdef DEBUG_OMP_STUFF - int *pThread = new int[nBulkSize]; - int *pIdx = new int[nBulkSize]; - #endif - - int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads); - int nThreadID, ct=0; - omp_set_num_threads(nMaxThreads); - - #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) - for (i=0; i + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparserbase.h" +#include +#include +#ifdef QMUP_USE_OPENMP + #include +#endif + +using namespace std; + +/** + * @file + * @brief This file contains the basic implementation of the muparser engine. + */ + +namespace qmu +{ +std::locale QmuParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep('.')); + +bool QmuParserBase::g_DbgDumpCmdCode = false; +bool QmuParserBase::g_DbgDumpStack = false; + +/** + * @brief Identifiers for built in binary operators. + * + * When defining custom binary operators with #AddOprt(...) make sure not to choose + * names conflicting with these definitions. + */ +const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" << "!=" << "==" << "<" << ">" + << "+" << "-" << "*" << "/" << "^" << "&&" + << "||" << "=" << "(" << ")" << "?" << ":"; + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Constructor. + * @param a_szFormula the formula to interpret. + * @throw ParserException if a_szFormula is null. + */ +QmuParserBase::QmuParserBase() + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), + m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), + m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + m_nFinalResultIdx(0) +{ + InitTokenReader(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy constructor. + * + * Tha parser can be safely copy constructed but the bytecode is reset during copy construction. + */ +QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) + :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), + m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), + m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), + m_nFinalResultIdx(0) +{ + m_pTokenReader.reset(new token_reader_type(this)); + Assign(a_Parser); +} + +//--------------------------------------------------------------------------------------------------------------------- +QmuParserBase::~QmuParserBase() +{} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Assignement operator. + * + * Implemented by calling Assign(a_Parser). Self assignement is suppressed. + * @param a_Parser Object to copy to this. + * @return *this + * @throw nothrow + */ +QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) +{ + Assign(a_Parser); + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy state of a parser object to this. + * + * Clears Variables and Functions of this parser. + * Copies the states of all internal variables. + * Resets parse function to string parse mode. + * + * @param a_Parser the source object. + */ +void QmuParserBase::Assign(const QmuParserBase &a_Parser) +{ + if (&a_Parser==this) + { + return; + } + + // Don't copy bytecode instead cause the parser to create new bytecode + // by resetting the parse function. + ReInit(); + + m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants + m_VarDef = a_Parser.m_VarDef; // Copy user defined variables + m_bBuiltInOp = a_Parser.m_bBuiltInOp; + m_vStringBuf = a_Parser.m_vStringBuf; + m_vStackBuffer = a_Parser.m_vStackBuffer; + m_nFinalResultIdx = a_Parser.m_nFinalResultIdx; + m_StrVarDef = a_Parser.m_StrVarDef; + m_vStringVarBuf = a_Parser.m_vStringVarBuf; + m_nIfElseCounter = a_Parser.m_nIfElseCounter; + m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this)); + + // Copy function and operator callbacks + m_FunDef = a_Parser.m_FunDef; // Copy function definitions + m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators + m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation + m_OprtDef = a_Parser.m_OprtDef; // binary operators + + m_sNameChars = a_Parser.m_sNameChars; + m_sOprtChars = a_Parser.m_sOprtChars; + m_sInfixOprtChars = a_Parser.m_sInfixOprtChars; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set the decimal separator. + * @param cDecSep Decimal separator as a character value. + * @sa SetThousandsSep + * + * By default muparser uses the "C" locale. The decimal separator of this + * locale is overwritten by the one provided here. + */ +void QmuParserBase::SetDecSep(char_type cDecSep) +{ + char_type cThousandsSep = std::use_facet< change_dec_sep >(s_locale).thousands_sep(); + s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Sets the thousands operator. + * @param cThousandsSep The thousands separator as a character + * @sa SetDecSep + * + * By default muparser uses the "C" locale. The thousands separator of this + * locale is overwritten by the one provided here. + */ +void QmuParserBase::SetThousandsSep(char_type cThousandsSep) +{ + char_type cDecSep = std::use_facet< change_dec_sep >(s_locale).decimal_point(); + s_locale = std::locale(std::locale("C"), new change_dec_sep(cDecSep, cThousandsSep)); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Resets the locale. + * + * The default locale used "." as decimal separator, no thousands separator and "," as function argument separator. + */ +void QmuParserBase::ResetLocale() +{ + s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); + SetArgSep(','); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize the token reader. + * + * Create new token reader object and submit pointers to function, operator, constant and variable definitions. + * + * @post m_pTokenReader.get()!=0 + * @throw nothrow + */ +void QmuParserBase::InitTokenReader() +{ + m_pTokenReader.reset(new token_reader_type(this)); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Reset parser to string parsing mode and clear internal buffers. + * + * Clear bytecode, reset the token reader. + * @throw nothrow + */ +void QmuParserBase::ReInit() const +{ + m_pParseFormula = &QmuParserBase::ParseString; + m_vStringBuf.clear(); + m_vRPN.clear(); + m_pTokenReader->ReInit(); + m_nIfElseCounter = 0; +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) +{ + Q_UNUSED(pExpr); + Q_UNUSED(nStart); + Q_UNUSED(nEnd); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the version of muparser. + * @param eInfo A flag indicating whether the full version info should be returned or not. + * + * Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS are returned only if eInfo==pviFULL. + */ +QString QmuParserBase::GetVersion(EParserVersionInfo eInfo) const +{ + QString versionInfo; + QTextStream ss(&versionInfo); + + ss << QMUP_VERSION; + + if (eInfo==pviFULL) + { + ss << " (" << QMUP_VERSION_DATE; + ss << "; " << sizeof(void*)*8 << "BIT"; + + #ifdef _DEBUG + ss << "; DEBUG"; + #else + ss << "; RELEASE"; + #endif + + #ifdef _UNICODE + ss << "; UNICODE"; + #else + #ifdef _MBCS + ss << "; MBCS"; + #else + ss << "; ASCII"; + #endif + #endif + + #ifdef QMUP_USE_OPENMP + ss << "; OPENMP"; + //#else + // ss << "; NO_OPENMP"; + #endif + + #if defined(MUP_MATH_EXCEPTIONS) + ss << "; MATHEXC"; + //#else + // ss << "; NO_MATHEXC"; + #endif + + ss << ")"; + } + return versionInfo; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a value parsing function. + * + * When parsing an expression muParser tries to detect values in the expression string using different valident + * callbacks. Thuis it's possible to parse for hex values, binary values and floating point values. + */ +void QmuParserBase::AddValIdent(identfun_type a_pCallback) +{ + m_pTokenReader->AddValIdent(a_pCallback); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set a function that can create variable pointer for unknown expression variables. + * @param a_pFactory A pointer to the variable factory. + * @param pUserData A user defined context pointer. + */ +void QmuParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData) +{ + m_pTokenReader->SetVarCreator(a_pFactory, pUserData); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a function or operator callback to the parser. + */ +void QmuParserBase::AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, + funmap_type &a_Storage, const QString &a_szCharSet ) +{ + if (a_Callback.GetAddr()==0) + { + Error(ecINVALID_FUN_PTR); + } + + const funmap_type *pFunMap = &a_Storage; + + // Check for conflicting operator or function names + if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } + + if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } + + if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } + + if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() ) + { + Error(ecNAME_CONFLICT, -1, a_strName); + } + + CheckOprt(a_strName, a_Callback, a_szCharSet); + a_Storage[a_strName] = a_Callback; + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a name contains invalid characters. + * + * @throw ParserException if the name contains invalid charakters. + */ +void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, + const QString &a_szCharSet) const +{ +#if defined(_UNICODE) + const std::wstring a_sNameStd = a_sName.toStdWString(); + const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); +#else + const std::string a_sNameStd = a_sName.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + if ( a_sNameStd.length() == false || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd.at(0)>='0' && a_sNameStd.at(0)<='9')) + { + switch (a_Callback.GetCode()) + { + case cmOPRT_POSTFIX: + Error(ecINVALID_POSTFIX_IDENT, -1, a_sName); + break; + case cmOPRT_INFIX: + Error(ecINVALID_INFIX_IDENT, -1, a_sName); + break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + Error(ecINVALID_NAME, -1, a_sName); + break; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Check if a name contains invalid characters. + * + * @throw ParserException if the name contains invalid charakters. + */ +void QmuParserBase::CheckName(const QString &a_sName, const QString &a_szCharSet) const +{ +#if defined(_UNICODE) + std::wstring a_sNameStd = a_sName.toStdWString(); + std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); +#else + std::string a_sNameStd = a_sName.toStdString(); + std::string a_szCharSetStd = a_szCharSet.toStdString(); +#endif + if ( a_sNameStd.length() == false || (a_sNameStd.find_first_not_of(a_szCharSetStd)!=string_type::npos) || + (a_sNameStd[0]>='0' && a_sNameStd[0]<='9')) + { + Error(ecINVALID_NAME); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set the formula. + * @param a_strFormula Formula as string_type + * @throw ParserException in case of syntax errors. + * + * Triggers first time calculation thus the creation of the bytecode and scanning of used variables. + */ +void QmuParserBase::SetExpr(const QString &a_sExpr) +{ + // Check locale compatibility + std::locale loc; + if (m_pTokenReader->GetArgSep()==std::use_facet >(loc).decimal_point()) + { + Error(ecLOCALE); + } + + // 20060222: Bugfix for Borland-Kylix: + // adding a space to the expression will keep Borlands KYLIX from going wild + // when calling tellg on a stringstream created from the expression after + // reading a value at the end of an expression. (qmu::QmuParser::IsVal function) + // (tellg returns -1 otherwise causing the parser to ignore the value) + QString sBuf(a_sExpr + " " ); + m_pTokenReader->SetFormula(sBuf); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Get the default symbols used for the built in operators. + * @sa c_DefaultOprt + */ +const QStringList &QmuParserBase::GetOprtDef() const +{ + return c_DefaultOprt; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the set of valid characters to be used in names of functions, variables, constants. + */ +void QmuParserBase::DefineNameChars(const QString &a_szCharset) +{ + m_sNameChars = a_szCharset; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the set of valid characters to be used in names of binary operators and postfix operators. + */ +void QmuParserBase::DefineOprtChars(const QString &a_szCharset) +{ + m_sOprtChars = a_szCharset; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define the set of valid characters to be used in names of infix operators. + */ +void QmuParserBase::DefineInfixOprtChars(const QString &a_szCharset) +{ + m_sInfixOprtChars = a_szCharset; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Virtual function that defines the characters allowed in name identifiers. + * @sa #ValidOprtChars, #ValidPrefixOprtChars + */ +const QString& QmuParserBase::ValidNameChars() const +{ + assert(m_sNameChars.size()); + return m_sNameChars; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Virtual function that defines the characters allowed in operator definitions. + * @sa #ValidNameChars, #ValidPrefixOprtChars + */ +const QString &QmuParserBase::ValidOprtChars() const +{ + assert(m_sOprtChars.size()); + return m_sOprtChars; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Virtual function that defines the characters allowed in infix operator definitions. + * @sa #ValidNameChars, #ValidOprtChars + */ +const QString &QmuParserBase::ValidInfixOprtChars() const +{ + assert(m_sInfixOprtChars.size()); + return m_sInfixOprtChars; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a user defined operator. + * @post Will reset the Parser to string parsing mode. + */ +void QmuParserBase::DefinePostfixOprt(const QString &a_sName, fun_type1 a_pFun, bool a_bAllowOpt) +{ + AddCallback(a_sName, QmuParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX), m_PostOprtDef, + ValidOprtChars() ); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Initialize user defined functions. + * + * Calls the virtual functions InitFun(), InitConst() and InitOprt(). + */ +void QmuParserBase::Init() +{ + InitCharSets(); + InitFun(); + InitConst(); + InitOprt(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a user defined operator. + * @post Will reset the Parser to string parsing mode. + * @param [in] a_sName operator Identifier + * @param [in] a_pFun Operator callback function + * @param [in] a_iPrec Operator Precedence (default=prSIGN) + * @param [in] a_bAllowOpt True if operator is volatile (default=false) + * @sa EPrec + */ +void QmuParserBase::DefineInfixOprt(const QString &a_sName, fun_type1 a_pFun, int a_iPrec, bool a_bAllowOpt) +{ + AddCallback(a_sName, QmuParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), m_InfixOprtDef, + ValidInfixOprtChars() ); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Define a binary operator. + * @param [in] a_sName The identifier of the operator. + * @param [in] a_pFun Pointer to the callback function. + * @param [in] a_iPrec Precedence of the operator. + * @param [in] a_eAssociativity The associativity of the operator. + * @param [in] a_bAllowOpt If this is true the operator may be optimized away. + * + * Adds a new Binary operator the the parser instance. + */ +void QmuParserBase::DefineOprt( const QString &a_sName, fun_type2 a_pFun, unsigned a_iPrec, + EOprtAssociativity a_eAssociativity, bool a_bAllowOpt ) +{ + // Check for conflicts with built in operator names + for (int i=0; m_bBuiltInOp && iIgnoreUndefVar(true); + CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it + // may contain references to nonexisting variables. + m_pParseFormula = &QmuParserBase::ParseString; + m_pTokenReader->IgnoreUndefVar(false); + } + catch (exception_type &e) + { + // Make sure to stay in string parse mode, dont call ReInit() + // because it deletes the array with the used variables + m_pParseFormula = &QmuParserBase::ParseString; + m_pTokenReader->IgnoreUndefVar(false); + throw e; + } + return m_pTokenReader->GetUsedVar(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return a map containing the used variables only. + */ +const varmap_type& QmuParserBase::GetVar() const +{ + return m_VarDef; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return a map containing all parser constants. + */ +const valmap_type& QmuParserBase::GetConst() const +{ + return m_ConstDef; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return prototypes of all parser functions. + * @return #m_FunDef + * @sa FunProt + * @throw nothrow + * + * The return type is a map of the public type #funmap_type containing the prototype definitions for all numerical + * parser functions. String functions are not part of this map. The Prototype definition is encapsulated in objects + * of the class FunProt one per parser function each associated with function names via a map construct. + */ +const funmap_type& QmuParserBase::GetFunDef() const +{ + return m_FunDef; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Retrieve the formula. + */ +const QString& QmuParserBase::GetExpr() const +{ + return m_pTokenReader->GetExpr(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Execute a function that takes a single string argument. + * @param a_FunTok Function token. + * @throw exception_type If the function token is not a string function + */ +QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, + const QVector &a_vArg) const +{ + if (a_vArg.back().GetCode()!=cmSTRING) + { + Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); + } + + token_type valTok; + generic_fun_type pFunc = a_FunTok.GetFuncAddr(); + assert(pFunc); + + try + { + // Check function arguments; write dummy value into valtok to represent the result + switch (a_FunTok.GetArgCount()) + { + case 0: + valTok.SetVal(1); + a_vArg[0].GetAsString(); + break; + case 1: + valTok.SetVal(1); + a_vArg[1].GetAsString(); + a_vArg[0].GetVal(); + break; + case 2: + valTok.SetVal(1); + a_vArg[2].GetAsString(); + a_vArg[1].GetVal(); + a_vArg[0].GetVal(); + break; + default: + Error(ecINTERNAL_ERROR); + break; + } + } + catch (QmuParserError& ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString()); + } + + // string functions won't be optimized + m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx()); + + // Push dummy value representing the function result to the stack + return valTok; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Apply a function token. + * @param iArgCount Number of Arguments actually gathered used only for multiarg functions. + * @post The result is pushed to the value stack + * @post The function token is removed from the stack + * @throw exception_type if Argument count does not mach function requirements. + */ +void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const +{ + assert(m_pTokenReader.get()); + + // Operator stack empty or does not contain tokens with callback functions + if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 ) + { + return; + } + + token_type funTok = a_stOpt.pop(); + assert(funTok.GetFuncAddr()); + + // Binary operators must rely on their internal operator number + // since counting of operators relies on commas for function arguments + // binary operators do not have commas in their expression + int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount; + + // determine how many parameters the function needs. To remember iArgCount includes the + // string parameter whilst GetArgCount() counts only numeric parameters. + int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0); + + // Thats the number of numerical parameters + int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0); + + if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1) + { + Error(ecINTERNAL_ERROR); + } + + if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) + { + Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); + } + + if (funTok.GetCode()!=cmOPRT_BIN && iArgCountGetPos()-1, funTok.GetAsString()); + } + + if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired ) + { + Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString()); + } + + // Collect the numeric function arguments from the value stack and store them + // in a vector + QVector stArg; + for (int i=0; iGetPos(), funTok.GetAsString()); + } + } + + switch (funTok.GetCode()) + { + case cmFUNC_STR: + stArg.push_back(a_stVal.pop()); + + if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR ) + { + Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString()); + } + + ApplyStrFunc(funTok, stArg); + break; + case cmFUNC_BULK: + m_vRPN.AddBulkFun(funTok.GetFuncAddr(), stArg.size()); + break; + case cmOPRT_BIN: + case cmOPRT_POSTFIX: + case cmOPRT_INFIX: + case cmFUNC: + if (funTok.GetArgCount()==-1 && iArgCount==0) + { + Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString()); + } + + m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical); + break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + break; + } + // Push dummy value representing the function result to the stack + token_type token; + token.SetVal(1); + a_stVal.push(token); +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const +{ + // Check if there is an if Else clause to be calculated + while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE) + { + token_type opElse = a_stOpt.pop(); + Q_ASSERT(a_stOpt.size()>0); + + // Take the value associated with the else branch from the value stack + token_type vVal2 = a_stVal.pop(); + + Q_ASSERT(a_stOpt.size()>0); + Q_ASSERT(a_stVal.size()>=2); + + // it then else is a ternary operator Pop all three values from the value s + // tack and just return the right value + token_type vVal1 = a_stVal.pop(); + token_type vExpr = a_stVal.pop(); + + a_stVal.push( (qFuzzyCompare(vExpr.GetVal()+1, 1+0)==false) ? vVal1 : vVal2); + + token_type opIf = a_stOpt.pop(); + Q_ASSERT(opElse.GetCode()==cmELSE); + Q_ASSERT(opIf.GetCode()==cmIF); + + m_vRPN.AddIfElse(cmENDIF); + } // while pending if-else-clause found +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Performs the necessary steps to write code for the execution of binary operators into the bytecode. + */ +void QmuParserBase::ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const +{ + // is it a user defined binary operator? + if (a_stOpt.top().GetCode()==cmOPRT_BIN) + { + ApplyFunc(a_stOpt, a_stVal, 2); + } + else + { + Q_ASSERT(a_stVal.size()>=2); + token_type valTok1 = a_stVal.pop(), + valTok2 = a_stVal.pop(), + optTok = a_stOpt.pop(), + resTok; + + if ( valTok1.GetType()!=valTok2.GetType() || (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) ) + { + Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString()); + } + + if (optTok.GetCode()==cmASSIGN) + { + if (valTok2.GetCode()!=cmVAR) + { + Error(ecUNEXPECTED_OPERATOR, -1, "="); + } + m_vRPN.AddAssignOp(valTok2.GetVar()); + } + else + { + m_vRPN.AddOp(optTok.GetCode()); + } + resTok.SetVal(1); + a_stVal.push(resTok); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Apply a binary operator. + * @param a_stOpt The operator stack + * @param a_stVal The value stack + */ +void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStack &stVal) const +{ + while (stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmIF) + { + token_type tok = stOpt.top(); + switch (tok.GetCode()) + { + case cmOPRT_INFIX: + case cmOPRT_BIN: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmLT: + case cmGT: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmLAND: + case cmLOR: + case cmASSIGN: + if (stOpt.top().GetCode()==cmOPRT_INFIX) + { + ApplyFunc(stOpt, stVal, 1); + } + else + { + ApplyBinOprt(stOpt, stVal); + } + break; + case cmELSE: + ApplyIfElse(stOpt, stVal); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + Error(ecINTERNAL_ERROR); + break; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Parse the command code. + * @sa ParseString(...) + * + * Command code contains precalculated stack positions of the values and the associated operators. The Stack is + * filled beginning from index one the value at index zero is not used at all. + */ +qreal QmuParserBase::ParseCmdCode() const +{ + return ParseCmdCodeBulk(0, 0); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Evaluate the RPN. + * @param nOffset The offset added to variable addresses (for bulk mode) + * @param nThreadID OpenMP Thread id of the calling thread + */ +qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const +{ + assert(nThreadID<=s_MaxNumOpenMPThreads); + + // Note: The check for nOffset==0 and nThreadID here is not necessary but + // brings a minor performance gain when not in bulk mode. + qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * + (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; + qreal buf; + int sidx(0); + for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) + { + switch (pTok->Cmd) + { + // built in binary operators + case cmLE: + --sidx; + Stack[sidx] = Stack[sidx] <= Stack[sidx+1]; + continue; + case cmGE: + --sidx; + Stack[sidx] = Stack[sidx] >= Stack[sidx+1]; + continue; + case cmNEQ: + --sidx; + Stack[sidx] = (qFuzzyCompare(Stack[sidx], Stack[sidx+1])==false); + continue; + case cmEQ: + --sidx; + Stack[sidx] = qFuzzyCompare(Stack[sidx], Stack[sidx+1]); + continue; + case cmLT: + --sidx; + Stack[sidx] = Stack[sidx] < Stack[sidx+1]; + continue; + case cmGT: + --sidx; + Stack[sidx] = Stack[sidx] > Stack[sidx+1]; + continue; + case cmADD: + --sidx; + Stack[sidx] += Stack[1+sidx]; + continue; + case cmSUB: + --sidx; + Stack[sidx] -= Stack[1+sidx]; + continue; + case cmMUL: + --sidx; + Stack[sidx] *= Stack[1+sidx]; + continue; + case cmDIV: + --sidx; + #if defined(MUP_MATH_EXCEPTIONS) + if (Stack[1+sidx]==0) + { + Error(ecDIV_BY_ZERO); + } + #endif + Stack[sidx] /= Stack[1+sidx]; + continue; + case cmPOW: + --sidx; + Stack[sidx] = qPow(Stack[sidx], Stack[1+sidx]); + continue; + case cmLAND: + --sidx; +#ifdef Q_CC_GNU + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + Stack[sidx] = Stack[sidx] && Stack[sidx+1]; +#ifdef Q_CC_GNU + #pragma GCC diagnostic pop +#endif + continue; + case cmLOR: + --sidx; +#ifdef Q_CC_GNU + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + Stack[sidx] = Stack[sidx] || Stack[sidx+1]; +#ifdef Q_CC_GNU + #pragma GCC diagnostic pop +#endif + continue; + case cmASSIGN: + --sidx; + Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; + continue; + case cmBO: // unused, listed for compiler optimization purposes + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + case cmIF: + if (qFuzzyCompare(Stack[sidx--]+1, 1+0)) + { + pTok += pTok->Oprt.offset; + } + continue; + case cmELSE: + pTok += pTok->Oprt.offset; + continue; + case cmENDIF: + continue; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + + // value and variable tokens + case cmVAR: + Stack[++sidx] = *(pTok->Val.ptr + nOffset); + continue; + case cmVAL: + Stack[++sidx] = pTok->Val.data2; + continue; + case cmVARPOW2: + buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf; + continue; + case cmVARPOW3: + buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf*buf; + continue; + case cmVARPOW4: + buf = *(pTok->Val.ptr + nOffset); + Stack[++sidx] = buf*buf*buf*buf; + continue; + case cmVARMUL: + Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2; + continue; + // Next is treatment of numeric functions + case cmFUNC: + { + int iArgCount = pTok->Fun.argc; + + // switch according to argument count + switch (iArgCount) + { + case 0: + sidx += 1; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(); + continue; + case 1: + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx]); + continue; + case 2: + sidx -= 1; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1]); + continue; + case 3: + sidx -= 2; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2]); + continue; + case 4: + sidx -= 3; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3]); + continue; + case 5: + sidx -= 4; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); + continue; + case 6: + sidx -= 5; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); + continue; + case 7: + sidx -= 6; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); + continue; + case 8: + sidx -= 7; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7]); + continue; + case 9: + sidx -= 8; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7], Stack[sidx+8]); + continue; + case 10: + sidx -= 9; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1], + Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], + Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); + continue; + default: + if (iArgCount>0) // function with variable arguments store the number as a negative value + { + Error(ecINTERNAL_ERROR, 1); + } + + sidx -= -iArgCount - 1; + Stack[sidx] =(*reinterpret_cast(pTok->Fun.ptr))(&Stack[sidx], -iArgCount); + continue; + } + } + // Next is treatment of string functions + case cmFUNC_STR: + { + sidx -= pTok->Fun.argc -1; + + // The index of the string argument in the string table + int iIdxStack = pTok->Fun.idx; + Q_ASSERT( iIdxStack>=0 && iIdxStackFun.argc) // switch according to argument count + { + case 0: + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack)); + continue; + case 1: + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), + Stack[sidx]); + continue; + case 2: + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack), + Stack[sidx], Stack[sidx+1]); + continue; + default: + break; + } + + continue; + } + case cmFUNC_BULK: + { + int iArgCount = pTok->Fun.argc; + + // switch according to argument count + switch (iArgCount) + { + case 0: + sidx += 1; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID); + continue; + case 1: + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, + Stack[sidx]); + continue; + case 2: + sidx -= 1; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1]); + continue; + case 3: + sidx -= 2; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2]); + continue; + case 4: + sidx -= 3; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); + continue; + case 5: + sidx -= 4; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4]); + continue; + case 6: + sidx -= 5; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], + Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); + continue; + case 7: + sidx -= 6; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); + continue; + case 8: + sidx -= 7; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); + continue; + case 9: + sidx -= 8; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); + continue; + case 10: + sidx -= 9; + Stack[sidx] = (*reinterpret_cast(pTok->Fun.ptr))(nOffset, nThreadID, + Stack[sidx], + Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], + Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], + Stack[sidx+9]); + continue; + default: + Error(ecINTERNAL_ERROR, 2); + continue; + } + } + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + case cmEND: + Q_UNREACHABLE(); + break; + // return Stack[m_nFinalResultIdx]; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + Error(ecINTERNAL_ERROR, 3); + return 0; + } // switch CmdCode + } // for all bytecode tokens + + return Stack[m_nFinalResultIdx]; +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::CreateRPN() const +{ + if (m_pTokenReader->GetExpr().length() == false) + { + Error(ecUNEXPECTED_EOF, 0); + } + + QStack stOpt, stVal; + QStack stArgCount; + token_type opta, opt; // for storing operators + token_type val, tval; // for storing value + string_type strBuf; // buffer for string function arguments + + ReInit(); + + // The outermost counter counts the number of seperated items + // such as in "a=10,b=20,c=c+a" + stArgCount.push(1); + + for (;;) + { + opt = m_pTokenReader->ReadNextToken(); + + switch (opt.GetCode()) + { + // + // Next three are different kind of value entries + // + case cmSTRING: + opt.SetIdx(m_vStringBuf.size()); // Assign buffer index to token + stVal.push(opt); + m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer + break; + case cmVAR: + stVal.push(opt); + m_vRPN.AddVar( static_cast(opt.GetVar()) ); + break; + case cmVAL: + stVal.push(opt); + m_vRPN.AddVal( opt.GetVal() ); + break; + case cmELSE: + m_nIfElseCounter--; + if (m_nIfElseCounter<0) + { + Error(ecMISPLACED_COLON, m_pTokenReader->GetPos()); + } + ApplyRemainingOprt(stOpt, stVal); + m_vRPN.AddIfElse(cmELSE); + stOpt.push(opt); + break; + case cmARG_SEP: + if (stArgCount.empty()) + { + Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); + } + ++stArgCount.top(); + // fallthrough intentional (no break!) + case cmEND: + ApplyRemainingOprt(stOpt, stVal); + break; + case cmBC: + { + // The argument count for parameterless functions is zero + // by default an opening bracket sets parameter count to 1 + // in preparation of arguments to come. If the last token + // was an opening bracket we know better... + if (opta.GetCode()==cmBO) + { + --stArgCount.top(); + } + + ApplyRemainingOprt(stOpt, stVal); + + // Check if the bracket content has been evaluated completely + if (stOpt.size() && stOpt.top().GetCode()==cmBO) + { + // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check + // if there is either a function or a sign pending + // neither the opening nor the closing bracket will be pushed back to + // the operator stack + // Check if a function is standing in front of the opening bracket, + // if yes evaluate it afterwards check for infix operators + assert(stArgCount.size()); + int iArgCount = stArgCount.pop(); + + stOpt.pop(); // Take opening bracket from stack + + if (iArgCount>1 && ( stOpt.size()==0 || (stOpt.top().GetCode()!=cmFUNC && + stOpt.top().GetCode()!=cmFUNC_BULK && + stOpt.top().GetCode()!=cmFUNC_STR) ) ) + { + Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos()); + } + + // The opening bracket was popped from the stack now check if there + // was a function before this bracket + if (stOpt.size() && stOpt.top().GetCode()!=cmOPRT_INFIX && stOpt.top().GetCode()!=cmOPRT_BIN && + stOpt.top().GetFuncAddr()!=0) + { + ApplyFunc(stOpt, stVal, iArgCount); + } + } + } // if bracket content is evaluated + break; + // + // Next are the binary operator entries + // + //case cmAND: // built in binary operators + //case cmOR: + //case cmXOR: + case cmIF: + m_nIfElseCounter++; + // fallthrough intentional (no break!) + case cmLAND: + case cmLOR: + case cmLT: + case cmGT: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmASSIGN: + case cmOPRT_BIN: + // A binary operator (user defined or built in) has been found. + while ( stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmELSE && + stOpt.top().GetCode() != cmIF) + { + int nPrec1 = GetOprtPrecedence(stOpt.top()), + nPrec2 = GetOprtPrecedence(opt); + + if (stOpt.top().GetCode()==opt.GetCode()) + { + // Deal with operator associativity + EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt); + if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || + (eOprtAsct==oaLEFT && (nPrec1 < nPrec2)) ) + { + break; + } + } + else if (nPrec1 < nPrec2) + { + // In case the operators are not equal the precedence decides alone... + break; + } + if (stOpt.top().GetCode()==cmOPRT_INFIX) + { + ApplyFunc(stOpt, stVal, 1); + } + else + { + ApplyBinOprt(stOpt, stVal); + } + } // while ( ... ) + + if (opt.GetCode()==cmIF) + { + m_vRPN.AddIfElse(opt.GetCode()); + } + + // The operator can't be evaluated right now, push back to the operator stack + stOpt.push(opt); + break; + // + // Last section contains functions and operators implicitely mapped to functions + // + case cmBO: + stArgCount.push(1); + stOpt.push(opt); + break; + case cmOPRT_INFIX: + case cmFUNC: + case cmFUNC_BULK: + case cmFUNC_STR: + stOpt.push(opt); + break; + case cmOPRT_POSTFIX: + stOpt.push(opt); + ApplyFunc(stOpt, stVal, 1); // this is the postfix operator + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + Error(ecINTERNAL_ERROR, 3); + } // end of switch operator-token + + opta = opt; + + if ( opt.GetCode() == cmEND ) + { + m_vRPN.Finalize(); + break; + } + + if (QmuParserBase::g_DbgDumpStack) + { + StackDump(stVal, stOpt); + m_vRPN.AsciiDump(); + } + } // while (true) + + if (QmuParserBase::g_DbgDumpCmdCode) + { + m_vRPN.AsciiDump(); + } + + if (m_nIfElseCounter>0) + { + Error(ecMISSING_ELSE_CLAUSE); + } + + // get the last value (= final result) from the stack + Q_ASSERT(stArgCount.size()==1); + m_nFinalResultIdx = stArgCount.top(); + if (m_nFinalResultIdx==0) + { + Error(ecINTERNAL_ERROR, 9); + } + + if (stVal.size()==0) + { + Error(ecEMPTY_EXPRESSION); + } + + if (stVal.top().GetType()!=tpDBL) + { + Error(ecSTR_RESULT); + } + + m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief One of the two main parse functions. + * @sa ParseCmdCode(...) + * + * Parse expression from input string. Perform syntax checking and create bytecode. After parsing the string and + * creating the bytecode the function pointer #m_pParseFormula will be changed to the second parse routine the + * uses bytecode instead of string parsing. + */ +qreal QmuParserBase::ParseString() const +{ + try + { + CreateRPN(); + m_pParseFormula = &QmuParserBase::ParseCmdCode; + return (this->*m_pParseFormula)(); + } + catch (QmuParserError &exc) + { + exc.SetFormula(m_pTokenReader->GetExpr()); + throw; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** +* @brief Create an error containing the parse error position. +* +* This function will create an Parser Exception object containing the error text and its position. +* +* @param a_iErrc [in] The error code of type #EErrorCodes. +* @param a_iPos [in] The position where the error was detected. +* @param a_strTok [in] The token string representation associated with the error. +* @throw ParserException always throws thats the only purpose of this function. +*/ +void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const +{ + throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined variables. + * @throw nothrow + * + * Resets the parser to string parsing mode by calling #ReInit. + */ +void QmuParserBase::ClearVar() +{ + m_VarDef.clear(); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Remove a variable from internal storage. + * @throw nothrow + * + * Removes a variable if it exists. If the Variable does not exist nothing will be done. + */ +void QmuParserBase::RemoveVar(const QString &a_strVarName) +{ + varmap_type::iterator item = m_VarDef.find(a_strVarName); + if (item!=m_VarDef.end()) + { + m_VarDef.erase(item); + ReInit(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all functions. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearFun() +{ + m_FunDef.clear(); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined constants. + * + * Both numeric and string constants will be removed from the internal storage. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearConst() +{ + m_ConstDef.clear(); + m_StrVarDef.clear(); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined postfix operators. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearPostfixOprt() +{ + m_PostOprtDef.clear(); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear all user defined binary operators. + * @post Resets the parser to string parsing mode. + * @throw nothrow + */ +void QmuParserBase::ClearOprt() +{ + m_OprtDef.clear(); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Clear the user defined Prefix operators. + * @post Resets the parser to string parser mode. + * @throw nothrow + */ +void QmuParserBase::ClearInfixOprt() +{ + m_InfixOprtDef.clear(); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Enable or disable the formula optimization feature. + * @post Resets the parser to string parser mode. + * @throw nothrow + */ +void QmuParserBase::EnableOptimizer(bool a_bIsOn) +{ + m_vRPN.EnableOptimizer(a_bIsOn); + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Enable the dumping of bytecode amd stack content on the console. + * @param bDumpCmd Flag to enable dumping of the current bytecode to the console. + * @param bDumpStack Flag to enable dumping of the stack content is written to the console. + * + * This function is for debug purposes only! + */ +void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) +{ + QmuParserBase::g_DbgDumpCmdCode = bDumpCmd; + QmuParserBase::g_DbgDumpStack = bDumpStack; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Enable or disable the built in binary operators. + * @throw nothrow + * @sa m_bBuiltInOp, ReInit() + * + * If you disable the built in binary operators there will be no binary operators defined. Thus you must add them + * manually one by one. It is not possible to disable built in operators selectively. This function will Reinitialize + * the parser by calling ReInit(). + */ +void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) +{ + m_bBuiltInOp = a_bIsOn; + ReInit(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Query status of built in variables. + * @return #m_bBuiltInOp; true if built in operators are enabled. + * @throw nothrow + */ +bool QmuParserBase::HasBuiltInOprt() const +{ + return m_bBuiltInOp; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Get the argument separator character. + */ +QChar QmuParserBase::GetArgSep() const +{ + return m_pTokenReader->GetArgSep(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Set argument separator. + * @param cArgSep the argument separator character. + */ +void QmuParserBase::SetArgSep(char_type cArgSep) +{ + m_pTokenReader->SetArgSep(cArgSep); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Dump stack content. + * + * This function is used for debugging only. + */ +void QmuParserBase::StackDump(const QStack &a_stVal, const QStack &a_stOprt) const +{ + QStack stOprt(a_stOprt), + stVal(a_stVal); + + qDebug() << "\nValue stack:\n"; + while ( stVal.empty() == false ) + { + token_type val = stVal.pop(); + if (val.GetType()==tpSTR) + { + qDebug() << " \"" << val.GetAsString() << "\" "; + } + else + { + qDebug() << " " << val.GetVal() << " "; + } + } + qDebug() << "\nOperator stack:\n"; + + while ( stOprt.empty() == false ) + { + if (stOprt.top().GetCode()<=cmASSIGN) + { + qDebug() << "OPRT_INTRNL \"" << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << "\" \n"; + } + else + { + switch ( stOprt.top().GetCode()) + { + case cmVAR: + qDebug() << "VAR\n"; + break; + case cmVAL: + qDebug() << "VAL\n"; + break; + case cmFUNC: + qDebug() << "FUNC \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmFUNC_BULK: + qDebug() << "FUNC_BULK \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmOPRT_INFIX: + qDebug() << "OPRT_INFIX \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmOPRT_BIN: + qDebug() << "OPRT_BIN \"" << stOprt.top().GetAsString() << "\"\n"; + break; + case cmFUNC_STR: + qDebug() << "FUNC_STR\n"; + break; + case cmEND: + qDebug() << "END\n"; + break; + case cmUNKNOWN: + qDebug() << "UNKNOWN\n"; + break; + case cmBO: + qDebug() << "BRACKET \"(\"\n"; + break; + case cmBC: + qDebug() << "BRACKET \")\"\n"; + break; + case cmIF: + qDebug() << "IF\n"; + break; + case cmELSE: + qDebug() << "ELSE\n"; + break; + case cmENDIF: + qDebug() << "ENDIF\n"; + break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + default: + qDebug() << stOprt.top().GetCode() << " "; + break; + } + } + stOprt.pop(); + } + qDebug() << dec; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** @brief Evaluate an expression containing comma seperated subexpressions + * @param [out] nStackSize The total number of results available + * @return Pointer to the array containing all expression results + * + * This member function can be used to retriev all results of an expression made up of multiple comma seperated + * subexpressions (i.e. "x+y,sin(x),cos(y)") + */ +qreal* QmuParserBase::Eval(int &nStackSize) const +{ + (this->*m_pParseFormula)(); + nStackSize = m_nFinalResultIdx; + + // (for historic reasons the stack starts at position 1) + return &m_vStackBuffer[1]; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Return the number of results on the calculation stack. + * + * If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). There mey be more than one return + * value. This function returns the number of available results. + */ +int QmuParserBase::GetNumResults() const +{ + return m_nFinalResultIdx; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Calculate the result. + * + * A note on const correctness: + * I consider it important that Calc is a const function. + * Due to caching operations Calc changes only the state of internal variables with one exception + * m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making + * Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. + * + * @pre A formula must be set. + * @pre Variables must have been set (if needed) + * + * @sa #m_pParseFormula + * @return The evaluation result + * @throw ParseException if no Formula is set or in case of any other error related to the formula. + */ +qreal QmuParserBase::Eval() const +{ + return (this->*m_pParseFormula)(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::Eval(qreal *results, int nBulkSize) +{ + CreateRPN(); + + int i = 0; + + #ifdef QMUP_USE_OPENMP + //#define DEBUG_OMP_STUFF + #ifdef DEBUG_OMP_STUFF + int *pThread = new int[nBulkSize]; + int *pIdx = new int[nBulkSize]; + #endif + + int nMaxThreads = qMin(omp_get_max_threads(), s_MaxNumOpenMPThreads); + int nThreadID, ct=0; + omp_set_num_threads(nMaxThreads); + + #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) + for (i=0; i - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUQPARSERBASE_H -#define QMUQPARSERBASE_H - -#include -#include -#include - -#include "qmuparserdef.h" -#include "qmuparsertokenreader.h" -#include "qmuparserbytecode.h" -#include "qmuparsererror.h" - - -namespace qmu -{ -/** - * @file - * @brief This file contains the class definition of the qmuparser engine. - */ - -/** - * @brief Mathematical expressions parser (base parser engine). - * @author (C) 2013 Ingo Berg - * - * This is the implementation of a bytecode based mathematical expressions parser. - * The formula will be parsed from string and converted into a bytecode. - * Future calculations will be done with the bytecode instead the formula string - * resulting in a significant performance increase. - * Complementary to a set of internally implemented functions the parser is able to handle - * user defined functions and variables. - */ -class QmuParserBase -{ - friend class QmuParserTokenReader; -public: - /** - * @brief Type of the error class. - * - * Included for backwards compatibility. - */ - typedef QmuParserError exception_type; - - QmuParserBase(); - QmuParserBase(const QmuParserBase &a_Parser); - QmuParserBase& operator=(const QmuParserBase &a_Parser); - virtual ~QmuParserBase(); - - static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); - qreal Eval() const; - qreal* Eval(int &nStackSize) const; - void Eval(qreal *results, int nBulkSize); - int GetNumResults() const; - void SetExpr(const QString &a_sExpr); - void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); - void SetDecSep(char_type cDecSep); - void SetThousandsSep(char_type cThousandsSep = 0); - void ResetLocale(); - void EnableOptimizer(bool a_bIsOn=true); - void EnableBuiltInOprt(bool a_bIsOn=true); - bool HasBuiltInOprt() const; - void AddValIdent(identfun_type a_pCallback); - void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, - EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); - void DefineConst(const QString &a_sName, qreal a_fVal); - void DefineStrConst(const QString &a_sName, const QString &a_strVal); - void DefineVar(const QString &a_sName, qreal *a_fVar); - void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); - void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, - bool a_bAllowOpt=true); - // Clear user defined variables, constants or functions - void ClearVar(); - void ClearFun(); - void ClearConst(); - void ClearInfixOprt(); - void ClearPostfixOprt(); - void ClearOprt(); - void RemoveVar(const QString &a_strVarName); - const varmap_type& GetUsedVar() const; - const varmap_type& GetVar() const; - const valmap_type& GetConst() const; - const QString& GetExpr() const; - const funmap_type& GetFunDef() const; - QString GetVersion(EParserVersionInfo eInfo = pviFULL) const; - const QStringList& GetOprtDef() const; - void DefineNameChars(const QString &a_szCharset); - void DefineOprtChars(const QString &a_szCharset); - void DefineInfixOprtChars(const QString &a_szCharset); - const QString& ValidNameChars() const; - const QString& ValidOprtChars() const; - const QString& ValidInfixOprtChars() const; - void SetArgSep(char_type cArgSep); - QChar GetArgSep() const; - void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; - /** - * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, - * bool a_bAllowOpt = true) - * @brief Define a parser function without arguments. - * @param a_strName Name of the function - * @param a_pFun Pointer to the callback function - * @param a_bAllowOpt A flag indicating this function may be optimized - */ - template - void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) - { - AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); - } -protected: - static const QStringList c_DefaultOprt; - static std::locale s_locale; ///< The locale used by the parser - static bool g_DbgDumpCmdCode; - static bool g_DbgDumpStack; - void Init(); - virtual void InitCharSets() = 0; - virtual void InitFun() = 0; - virtual void InitConst() = 0; - virtual void InitOprt() = 0; - virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); - /** - * @brief A facet class used to change decimal and thousands separator. - */ - template - class change_dec_sep : public std::numpunct - { - public: - explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) - :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) - {} - protected: - virtual char_type do_decimal_point() const - { - return m_cDecPoint; - } - - virtual char_type do_thousands_sep() const - { - return m_cThousandsSep; - } - - virtual std::string do_grouping() const - { - return std::string(1, m_nGroup); - } - private: - int m_nGroup; - char_type m_cDecPoint; - char_type m_cThousandsSep; - }; -private: - /** - * @brief Typedef for the parse functions. - * - * The parse function do the actual work. The parser exchanges - * the function pointer to the parser function depending on - * which state it is in. (i.e. bytecode parser vs. string parser) - */ - typedef qreal (QmuParserBase::*ParseFunction)() const; - - /** - * @brief Type used for storing an array of values. - */ - typedef QVector valbuf_type; - - /** - * @brief Type for a vector of strings. - */ - typedef QVector stringbuf_type; - - /** - * @brief Typedef for the token reader. - */ - typedef QmuParserTokenReader token_reader_type; - - /** - * @brief Type used for parser tokens. - */ - typedef QmuParserToken token_type; - - /** - * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. - */ - static const int s_MaxNumOpenMPThreads = 4; - - /** - * @brief Pointer to the parser function. - * - * Eval() calls the function whose address is stored there. - */ - mutable ParseFunction m_pParseFormula; - mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. - mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments - stringbuf_type m_vStringVarBuf; - - std::unique_ptr m_pTokenReader; ///< Managed pointer to the token reader object. - - funmap_type m_FunDef; ///< Map of function names and pointers. - funmap_type m_PostOprtDef; ///< Postfix operator callbacks - funmap_type m_InfixOprtDef; ///< unary infix operator. - funmap_type m_OprtDef; ///< Binary operator callbacks - valmap_type m_ConstDef; ///< user constants. - strmap_type m_StrVarDef; ///< user defined string constants - varmap_type m_VarDef; ///< user defind variables. - - bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off - - QString m_sNameChars; ///< Charset for names - QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens - QString m_sInfixOprtChars; ///< Charset for infix operator tokens - - mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses - - // items merely used for caching state information - mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine - mutable int m_nFinalResultIdx; - - void Assign(const QmuParserBase &a_Parser); - void InitTokenReader(); - void ReInit() const; - void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, - funmap_type &a_Storage, const QString &a_szCharSet ); - void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; - void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; - token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; - int GetOprtPrecedence(const token_type &a_Tok) const; - EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; - void CreateRPN() const; - qreal ParseString() const; - qreal ParseCmdCode() const; - qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; - void CheckName(const QString &a_strName, const QString &a_CharSet) const; - void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, - const QString &a_szCharSet) const; - void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; -}; - -} // namespace qmu - -#endif - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUQPARSERBASE_H +#define QMUQPARSERBASE_H + +#include +#include +#include + +#include "qmuparserdef.h" +#include "qmuparsertokenreader.h" +#include "qmuparserbytecode.h" +#include "qmuparsererror.h" + + +namespace qmu +{ +/** + * @file + * @brief This file contains the class definition of the qmuparser engine. + */ + +/** + * @brief Mathematical expressions parser (base parser engine). + * @author (C) 2013 Ingo Berg + * + * This is the implementation of a bytecode based mathematical expressions parser. + * The formula will be parsed from string and converted into a bytecode. + * Future calculations will be done with the bytecode instead the formula string + * resulting in a significant performance increase. + * Complementary to a set of internally implemented functions the parser is able to handle + * user defined functions and variables. + */ +class QmuParserBase +{ + friend class QmuParserTokenReader; +public: + /** + * @brief Type of the error class. + * + * Included for backwards compatibility. + */ + typedef QmuParserError exception_type; + + QmuParserBase(); + QmuParserBase(const QmuParserBase &a_Parser); + QmuParserBase& operator=(const QmuParserBase &a_Parser); + virtual ~QmuParserBase(); + + static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); + qreal Eval() const; + qreal* Eval(int &nStackSize) const; + void Eval(qreal *results, int nBulkSize); + int GetNumResults() const; + void SetExpr(const QString &a_sExpr); + void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); + void SetDecSep(char_type cDecSep); + void SetThousandsSep(char_type cThousandsSep = 0); + void ResetLocale(); + void EnableOptimizer(bool a_bIsOn=true); + void EnableBuiltInOprt(bool a_bIsOn=true); + bool HasBuiltInOprt() const; + void AddValIdent(identfun_type a_pCallback); + void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, + EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); + void DefineConst(const QString &a_sName, qreal a_fVal); + void DefineStrConst(const QString &a_sName, const QString &a_strVal); + void DefineVar(const QString &a_sName, qreal *a_fVar); + void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); + void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, + bool a_bAllowOpt=true); + // Clear user defined variables, constants or functions + void ClearVar(); + void ClearFun(); + void ClearConst(); + void ClearInfixOprt(); + void ClearPostfixOprt(); + void ClearOprt(); + void RemoveVar(const QString &a_strVarName); + const varmap_type& GetUsedVar() const; + const varmap_type& GetVar() const; + const valmap_type& GetConst() const; + const QString& GetExpr() const; + const funmap_type& GetFunDef() const; + QString GetVersion(EParserVersionInfo eInfo = pviFULL) const; + const QStringList& GetOprtDef() const; + void DefineNameChars(const QString &a_szCharset); + void DefineOprtChars(const QString &a_szCharset); + void DefineInfixOprtChars(const QString &a_szCharset); + const QString& ValidNameChars() const; + const QString& ValidOprtChars() const; + const QString& ValidInfixOprtChars() const; + void SetArgSep(char_type cArgSep); + QChar GetArgSep() const; + void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; + /** + * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, + * bool a_bAllowOpt = true) + * @brief Define a parser function without arguments. + * @param a_strName Name of the function + * @param a_pFun Pointer to the callback function + * @param a_bAllowOpt A flag indicating this function may be optimized + */ + template + void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true) + { + AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); + } +protected: + static const QStringList c_DefaultOprt; + static std::locale s_locale; ///< The locale used by the parser + static bool g_DbgDumpCmdCode; + static bool g_DbgDumpStack; + void Init(); + virtual void InitCharSets() = 0; + virtual void InitFun() = 0; + virtual void InitConst() = 0; + virtual void InitOprt() = 0; + virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd); + /** + * @brief A facet class used to change decimal and thousands separator. + */ + template + class change_dec_sep : public std::numpunct + { + public: + explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3) + :std::numpunct(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep) + {} + protected: + virtual char_type do_decimal_point() const + { + return m_cDecPoint; + } + + virtual char_type do_thousands_sep() const + { + return m_cThousandsSep; + } + + virtual std::string do_grouping() const + { + return std::string(1, m_nGroup); + } + private: + int m_nGroup; + char_type m_cDecPoint; + char_type m_cThousandsSep; + }; +private: + /** + * @brief Typedef for the parse functions. + * + * The parse function do the actual work. The parser exchanges + * the function pointer to the parser function depending on + * which state it is in. (i.e. bytecode parser vs. string parser) + */ + typedef qreal (QmuParserBase::*ParseFunction)() const; + + /** + * @brief Type used for storing an array of values. + */ + typedef QVector valbuf_type; + + /** + * @brief Type for a vector of strings. + */ + typedef QVector stringbuf_type; + + /** + * @brief Typedef for the token reader. + */ + typedef QmuParserTokenReader token_reader_type; + + /** + * @brief Type used for parser tokens. + */ + typedef QmuParserToken token_type; + + /** + * @brief Maximum number of threads spawned by OpenMP when using the bulk mode. + */ + static const int s_MaxNumOpenMPThreads = 4; + + /** + * @brief Pointer to the parser function. + * + * Eval() calls the function whose address is stored there. + */ + mutable ParseFunction m_pParseFormula; + mutable QmuParserByteCode m_vRPN; ///< The Bytecode class. + mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments + stringbuf_type m_vStringVarBuf; + + std::unique_ptr m_pTokenReader; ///< Managed pointer to the token reader object. + + funmap_type m_FunDef; ///< Map of function names and pointers. + funmap_type m_PostOprtDef; ///< Postfix operator callbacks + funmap_type m_InfixOprtDef; ///< unary infix operator. + funmap_type m_OprtDef; ///< Binary operator callbacks + valmap_type m_ConstDef; ///< user constants. + strmap_type m_StrVarDef; ///< user defined string constants + varmap_type m_VarDef; ///< user defind variables. + + bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off + + QString m_sNameChars; ///< Charset for names + QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens + QString m_sInfixOprtChars; ///< Charset for infix operator tokens + + mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses + + // items merely used for caching state information + mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine + mutable int m_nFinalResultIdx; + + void Assign(const QmuParserBase &a_Parser); + void InitTokenReader(); + void ReInit() const; + void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, + funmap_type &a_Storage, const QString &a_szCharSet ); + void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyBinOprt(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyIfElse(QStack &a_stOpt, QStack &a_stVal) const; + void ApplyFunc(QStack &a_stOpt, QStack &a_stVal, int iArgCount) const; + token_type ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const; + int GetOprtPrecedence(const token_type &a_Tok) const; + EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const; + void CreateRPN() const; + qreal ParseString() const; + qreal ParseCmdCode() const; + qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const; + void CheckName(const QString &a_strName, const QString &a_CharSet) const; + void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback, + const QString &a_szCharSet) const; + void StackDump(const QStack &a_stVal, const QStack &a_stOprt) const; +}; + +} // namespace qmu + +#endif diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 80e6822ea..296d89c53 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -1,953 +1,953 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#include "qmuparserbytecode.h" - -#include -#include -#include -#include -#include - -#include "qmuparserdef.h" -#include "qmuparsererror.h" -#include "qmuparsertoken.h" - - -namespace qmu -{ -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Bytecode default constructor. - */ -QmuParserByteCode::QmuParserByteCode() - :m_iStackPos(0), m_iMaxStackSize(0), m_vRPN(), m_bEnableOptimizer(true) -{ - m_vRPN.reserve(50); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Copy constructor. - * - * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) - */ -QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) - :m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN), - m_bEnableOptimizer(true) -{ - Assign(a_ByteCode); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Assignment operator. - * - * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) - */ -QmuParserByteCode& QmuParserByteCode::operator=(const QmuParserByteCode &a_ByteCode) -{ - Assign(a_ByteCode); - return *this; -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserByteCode::EnableOptimizer(bool bStat) -{ - m_bEnableOptimizer = bStat; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Copy state of another object to this. - * - * @throw nowthrow - */ -void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) -{ - if (this==&a_ByteCode) - { - return; - } - - m_iStackPos = a_ByteCode.m_iStackPos; - m_vRPN = a_ByteCode.m_vRPN; - m_iMaxStackSize = a_ByteCode.m_iMaxStackSize; -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a Variable pointer to bytecode. - * @param a_pVar Pointer to be added. - * @throw nothrow - */ -void QmuParserByteCode::AddVar(qreal *a_pVar) -{ - ++m_iStackPos; - m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); - - // optimization does not apply - SToken tok; - tok.Cmd = cmVAR; - tok.Val.ptr = a_pVar; - tok.Val.data = 1; - tok.Val.data2 = 0; - m_vRPN.push_back(tok); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a Variable pointer to bytecode. - * - * Value entries in byte code consist of: - *
      - *
    • value array position of the value
    • - *
    • the operator code according to ParserToken::cmVAL
    • - *
    • the value stored in #mc_iSizeVal number of bytecode entries.
    • - *
    - * - * @param a_pVal Value to be added. - * @throw nothrow - */ -void QmuParserByteCode::AddVal(qreal a_fVal) -{ - ++m_iStackPos; - m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); - - // If optimization does not apply - SToken tok; - tok.Cmd = cmVAL; - tok.Val.ptr = NULL; - tok.Val.data = 0; - tok.Val.data2 = a_fVal; - m_vRPN.push_back(tok); -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) -{ - std::size_t sz = m_vRPN.size(); - qreal &x = m_vRPN[sz-2].Val.data2, - &y = m_vRPN[sz-1].Val.data2; - switch (a_Oprt) - { - case cmLAND: - x = static_cast(x) && static_cast(y); - m_vRPN.pop_back(); - break; - case cmLOR: - x = static_cast(x) || static_cast(y); - m_vRPN.pop_back(); - break; - case cmLT: - x = x < y; - m_vRPN.pop_back(); - break; - case cmGT: - x = x > y; - m_vRPN.pop_back(); - break; - case cmLE: - x = x <= y; - m_vRPN.pop_back(); - break; - case cmGE: - x = x >= y; - m_vRPN.pop_back(); - break; - case cmNEQ: - x = (qFuzzyCompare(x, y) == false); - m_vRPN.pop_back(); - break; - case cmEQ: - x = qFuzzyCompare(x, y); - m_vRPN.pop_back(); - break; - case cmADD: - x = x + y; - m_vRPN.pop_back(); - break; - case cmSUB: - x = x - y; - m_vRPN.pop_back(); - break; - case cmMUL: - x = x * y; - m_vRPN.pop_back(); - break; - case cmDIV: - #if defined(MUP_MATH_EXCEPTIONS) - if (y==0) - { - throw ParserError(ecDIV_BY_ZERO, "0"); - } - #endif - x = x / y; - m_vRPN.pop_back(); - break; - case cmPOW: - x = qPow(x, y); - m_vRPN.pop_back(); - break; - case cmASSIGN: - Q_UNREACHABLE(); - break; - case cmBO: - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - case cmIF: - Q_UNREACHABLE(); - break; - case cmELSE: - Q_UNREACHABLE(); - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVAR: - Q_UNREACHABLE(); - break; - case cmVAL: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmFUNC: - Q_UNREACHABLE(); - break; - case cmFUNC_STR: - Q_UNREACHABLE(); - break; - case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_BIN: - Q_UNREACHABLE(); - break; - case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; - case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; - case cmEND: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - break; - } // switch opcode -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add an operator identifier to bytecode. - * - * Operator entries in byte code consist of: - *
      - *
    • value array position of the result
    • - *
    • the operator code according to ParserToken::ECmdCode
    • - *
    - * - * @sa ParserToken::ECmdCode - */ -void QmuParserByteCode::AddOp(ECmdCode a_Oprt) -{ - bool bOptimized = false; - - if (m_bEnableOptimizer) - { - std::size_t sz = m_vRPN.size(); - - // Check for foldable constants like: - // cmVAL cmVAL cmADD - // where cmADD can stand fopr any binary operator applied to - // two constant values. - if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL) - { - ConstantFolding(a_Oprt); - bOptimized = true; - } - else - { - switch(a_Oprt) - { - case cmPOW: - // Optimization for ploynomials of low order - if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) - { - if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 2)) - { - m_vRPN[sz-2].Cmd = cmVARPOW2; - } - else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 3)) - { - m_vRPN[sz-2].Cmd = cmVARPOW3; - } - else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 4)) - { - m_vRPN[sz-2].Cmd = cmVARPOW4; - } - else - { - break; - } - m_vRPN.pop_back(); - bOptimized = true; - } - break; - - case cmSUB: - case cmADD: - // Simple optimization based on pattern recognition for a shitload of different - // bytecode combinations of addition/subtraction - if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || - (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) || - (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) || - (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && - m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || - (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL - && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && - m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && - m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) - { - assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) || - (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || - (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); - - m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = reinterpret_cast( - reinterpret_cast(m_vRPN[sz-2].Val.ptr) | - reinterpret_cast(m_vRPN[sz-1].Val.ptr)); // variable - m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset - m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior - m_vRPN.pop_back(); - bOptimized = true; - } - break; - case cmMUL: - if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || - (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) - { - m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = reinterpret_cast( - reinterpret_cast(m_vRPN[sz-2].Val.ptr) | - reinterpret_cast(m_vRPN[sz-1].Val.ptr)); - m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 = 0; - m_vRPN.pop_back(); - bOptimized = true; - } - else if ( (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || - (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ) - { - // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 - m_vRPN[sz-2].Cmd = cmVARMUL; - m_vRPN[sz-2].Val.ptr = reinterpret_cast( - reinterpret_cast(m_vRPN[sz-2].Val.ptr) | - reinterpret_cast(m_vRPN[sz-1].Val.ptr)); - if (m_vRPN[sz-1].Cmd == cmVAL) - { - m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2; - } - else - { - m_vRPN[sz-2].Val.data = m_vRPN[sz-1].Val.data * m_vRPN[sz-2].Val.data2; - m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2; - } - m_vRPN.pop_back(); - bOptimized = true; - } - else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && - m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr) - { - // Optimization: a*a -> a^2 - m_vRPN[sz-2].Cmd = cmVARPOW2; - m_vRPN.pop_back(); - bOptimized = true; - } - break; - case cmDIV: - if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && - (qFuzzyCompare(m_vRPN[sz-1].Val.data2+1, 1+0)==false)) - { - // Optimization: 4*a/2 -> 2*a - m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; - m_vRPN.pop_back(); - bOptimized = true; - } - break; - case cmLE: - Q_UNREACHABLE(); - break; - case cmGE: - Q_UNREACHABLE(); - break; - case cmNEQ: - Q_UNREACHABLE(); - break; - case cmEQ: - Q_UNREACHABLE(); - break; - case cmLT: - Q_UNREACHABLE(); - break; - case cmGT: - Q_UNREACHABLE(); - break; - case cmLAND: - Q_UNREACHABLE(); - break; - case cmLOR: - Q_UNREACHABLE(); - break; - case cmASSIGN: - Q_UNREACHABLE(); - break; - case cmBO: - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - case cmIF: - Q_UNREACHABLE(); - break; - case cmELSE: - Q_UNREACHABLE(); - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVAR: - Q_UNREACHABLE(); - break; - case cmVAL: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmFUNC: - Q_UNREACHABLE(); - break; - case cmFUNC_STR: - Q_UNREACHABLE(); - break; - case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_BIN: - Q_UNREACHABLE(); - break; - case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; - case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; - case cmEND: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - break; - - } // switch a_Oprt - } - } - - // If optimization can't be applied just write the value - if (!bOptimized) - { - --m_iStackPos; - SToken tok; - tok.Cmd = a_Oprt; - m_vRPN.push_back(tok); - } -} - -//---------------------------------------------------------------------------------------------------------------------- -void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt) -{ - SToken tok; - tok.Cmd = a_Oprt; - m_vRPN.push_back(tok); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add an assignement operator - * - * Operator entries in byte code consist of: - *
      - *
    • cmASSIGN code
    • - *
    • the pointer of the destination variable
    • - *
    - * - * @sa ParserToken::ECmdCode - */ -void QmuParserByteCode::AddAssignOp(qreal *a_pVar) -{ - --m_iStackPos; - - SToken tok; - tok.Cmd = cmASSIGN; - tok.Val.ptr = a_pVar; - m_vRPN.push_back(tok); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add function to bytecode. - * - * @param a_iArgc Number of arguments, negative numbers indicate multiarg functions. - * @param a_pFun Pointer to function callback. - */ -void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) -{ - if (a_iArgc>=0) - { - m_iStackPos = m_iStackPos - a_iArgc + 1; - } - else - { - // function with unlimited number of arguments - m_iStackPos = m_iStackPos + a_iArgc + 1; - } - m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); - - SToken tok; - tok.Cmd = cmFUNC; - tok.Fun.argc = a_iArgc; - tok.Fun.ptr = a_pFun; - m_vRPN.push_back(tok); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add a bulk function to bytecode. - * - * @param a_iArgc Number of arguments, negative numbers indicate multiarg functions. - * @param a_pFun Pointer to function callback. - */ -void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) -{ - m_iStackPos = m_iStackPos - a_iArgc + 1; - m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); - - SToken tok; - tok.Cmd = cmFUNC_BULK; - tok.Fun.argc = a_iArgc; - tok.Fun.ptr = a_pFun; - m_vRPN.push_back(tok); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add Strung function entry to the parser bytecode. - * @throw nothrow - * - * A string function entry consists of the stack position of the return value, followed by a cmSTRFUNC code, the - * function pointer and an index into the string buffer maintained by the parser. - */ -void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) -{ - m_iStackPos = m_iStackPos - a_iArgc + 1; - - SToken tok; - tok.Cmd = cmFUNC_STR; - tok.Fun.argc = a_iArgc; - tok.Fun.idx = a_iIdx; - tok.Fun.ptr = a_pFun; - m_vRPN.push_back(tok); - - m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); -} - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Add end marker to bytecode. - * - * @throw nothrow - */ -void QmuParserByteCode::Finalize() -{ - SToken tok; - tok.Cmd = cmEND; - m_vRPN.push_back(tok); - rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit - - // Determine the if-then-else jump offsets - QStack stIf, stElse; - int idx; - for (int i=0; i + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#include "qmuparserbytecode.h" + +#include +#include +#include +#include +#include + +#include "qmuparserdef.h" +#include "qmuparsererror.h" +#include "qmuparsertoken.h" + + +namespace qmu +{ +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Bytecode default constructor. + */ +QmuParserByteCode::QmuParserByteCode() + :m_iStackPos(0), m_iMaxStackSize(0), m_vRPN(), m_bEnableOptimizer(true) +{ + m_vRPN.reserve(50); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy constructor. + * + * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) + */ +QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) + :m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN), + m_bEnableOptimizer(true) +{ + Assign(a_ByteCode); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Assignment operator. + * + * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) + */ +QmuParserByteCode& QmuParserByteCode::operator=(const QmuParserByteCode &a_ByteCode) +{ + Assign(a_ByteCode); + return *this; +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserByteCode::EnableOptimizer(bool bStat) +{ + m_bEnableOptimizer = bStat; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Copy state of another object to this. + * + * @throw nowthrow + */ +void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) +{ + if (this==&a_ByteCode) + { + return; + } + + m_iStackPos = a_ByteCode.m_iStackPos; + m_vRPN = a_ByteCode.m_vRPN; + m_iMaxStackSize = a_ByteCode.m_iMaxStackSize; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a Variable pointer to bytecode. + * @param a_pVar Pointer to be added. + * @throw nothrow + */ +void QmuParserByteCode::AddVar(qreal *a_pVar) +{ + ++m_iStackPos; + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); + + // optimization does not apply + SToken tok; + tok.Cmd = cmVAR; + tok.Val.ptr = a_pVar; + tok.Val.data = 1; + tok.Val.data2 = 0; + m_vRPN.push_back(tok); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a Variable pointer to bytecode. + * + * Value entries in byte code consist of: + *
      + *
    • value array position of the value
    • + *
    • the operator code according to ParserToken::cmVAL
    • + *
    • the value stored in #mc_iSizeVal number of bytecode entries.
    • + *
    + * + * @param a_pVal Value to be added. + * @throw nothrow + */ +void QmuParserByteCode::AddVal(qreal a_fVal) +{ + ++m_iStackPos; + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); + + // If optimization does not apply + SToken tok; + tok.Cmd = cmVAL; + tok.Val.ptr = NULL; + tok.Val.data = 0; + tok.Val.data2 = a_fVal; + m_vRPN.push_back(tok); +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) +{ + std::size_t sz = m_vRPN.size(); + qreal &x = m_vRPN[sz-2].Val.data2, + &y = m_vRPN[sz-1].Val.data2; + switch (a_Oprt) + { + case cmLAND: + x = static_cast(x) && static_cast(y); + m_vRPN.pop_back(); + break; + case cmLOR: + x = static_cast(x) || static_cast(y); + m_vRPN.pop_back(); + break; + case cmLT: + x = x < y; + m_vRPN.pop_back(); + break; + case cmGT: + x = x > y; + m_vRPN.pop_back(); + break; + case cmLE: + x = x <= y; + m_vRPN.pop_back(); + break; + case cmGE: + x = x >= y; + m_vRPN.pop_back(); + break; + case cmNEQ: + x = (qFuzzyCompare(x, y) == false); + m_vRPN.pop_back(); + break; + case cmEQ: + x = qFuzzyCompare(x, y); + m_vRPN.pop_back(); + break; + case cmADD: + x = x + y; + m_vRPN.pop_back(); + break; + case cmSUB: + x = x - y; + m_vRPN.pop_back(); + break; + case cmMUL: + x = x * y; + m_vRPN.pop_back(); + break; + case cmDIV: + #if defined(MUP_MATH_EXCEPTIONS) + if (y==0) + { + throw ParserError(ecDIV_BY_ZERO, "0"); + } + #endif + x = x / y; + m_vRPN.pop_back(); + break; + case cmPOW: + x = qPow(x, y); + m_vRPN.pop_back(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + break; + } // switch opcode +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add an operator identifier to bytecode. + * + * Operator entries in byte code consist of: + *
      + *
    • value array position of the result
    • + *
    • the operator code according to ParserToken::ECmdCode
    • + *
    + * + * @sa ParserToken::ECmdCode + */ +void QmuParserByteCode::AddOp(ECmdCode a_Oprt) +{ + bool bOptimized = false; + + if (m_bEnableOptimizer) + { + std::size_t sz = m_vRPN.size(); + + // Check for foldable constants like: + // cmVAL cmVAL cmADD + // where cmADD can stand fopr any binary operator applied to + // two constant values. + if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL) + { + ConstantFolding(a_Oprt); + bOptimized = true; + } + else + { + switch (a_Oprt) + { + case cmPOW: + // Optimization for ploynomials of low order + if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL) + { + if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 2)) + { + m_vRPN[sz-2].Cmd = cmVARPOW2; + } + else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 3)) + { + m_vRPN[sz-2].Cmd = cmVARPOW3; + } + else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 4)) + { + m_vRPN[sz-2].Cmd = cmVARPOW4; + } + else + { + break; + } + m_vRPN.pop_back(); + bOptimized = true; + } + break; + + case cmSUB: + case cmADD: + // Simple optimization based on pattern recognition for a shitload of different + // bytecode combinations of addition/subtraction + if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL + && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && + m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) + { + assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) || + (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || + (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); + + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); // variable + m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset + m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior + m_vRPN.pop_back(); + bOptimized = true; + } + break; + case cmMUL: + if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) || + (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) + { + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); + m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 = 0; + m_vRPN.pop_back(); + bOptimized = true; + } + else if ( (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) || + (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ) + { + // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 + m_vRPN[sz-2].Cmd = cmVARMUL; + m_vRPN[sz-2].Val.ptr = reinterpret_cast( + reinterpret_cast(m_vRPN[sz-2].Val.ptr) | + reinterpret_cast(m_vRPN[sz-1].Val.ptr)); + if (m_vRPN[sz-1].Cmd == cmVAL) + { + m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2; + } + else + { + m_vRPN[sz-2].Val.data = m_vRPN[sz-1].Val.data * m_vRPN[sz-2].Val.data2; + m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2; + } + m_vRPN.pop_back(); + bOptimized = true; + } + else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && + m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr) + { + // Optimization: a*a -> a^2 + m_vRPN[sz-2].Cmd = cmVARPOW2; + m_vRPN.pop_back(); + bOptimized = true; + } + break; + case cmDIV: + if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && + (qFuzzyCompare(m_vRPN[sz-1].Val.data2+1, 1+0)==false)) + { + // Optimization: 4*a/2 -> 2*a + m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; + m_vRPN.pop_back(); + bOptimized = true; + } + break; + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVAR: + Q_UNREACHABLE(); + break; + case cmVAL: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + break; + + } // switch a_Oprt + } + } + + // If optimization can't be applied just write the value + if (bOptimized == false) + { + --m_iStackPos; + SToken tok; + tok.Cmd = a_Oprt; + m_vRPN.push_back(tok); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserByteCode::AddIfElse(ECmdCode a_Oprt) +{ + SToken tok; + tok.Cmd = a_Oprt; + m_vRPN.push_back(tok); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add an assignement operator + * + * Operator entries in byte code consist of: + *
      + *
    • cmASSIGN code
    • + *
    • the pointer of the destination variable
    • + *
    + * + * @sa ParserToken::ECmdCode + */ +void QmuParserByteCode::AddAssignOp(qreal *a_pVar) +{ + --m_iStackPos; + + SToken tok; + tok.Cmd = cmASSIGN; + tok.Val.ptr = a_pVar; + m_vRPN.push_back(tok); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add function to bytecode. + * + * @param a_iArgc Number of arguments, negative numbers indicate multiarg functions. + * @param a_pFun Pointer to function callback. + */ +void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) +{ + if (a_iArgc>=0) + { + m_iStackPos = m_iStackPos - a_iArgc + 1; + } + else + { + // function with unlimited number of arguments + m_iStackPos = m_iStackPos + a_iArgc + 1; + } + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); + + SToken tok; + tok.Cmd = cmFUNC; + tok.Fun.argc = a_iArgc; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add a bulk function to bytecode. + * + * @param a_iArgc Number of arguments, negative numbers indicate multiarg functions. + * @param a_pFun Pointer to function callback. + */ +void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) +{ + m_iStackPos = m_iStackPos - a_iArgc + 1; + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); + + SToken tok; + tok.Cmd = cmFUNC_BULK; + tok.Fun.argc = a_iArgc; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add Strung function entry to the parser bytecode. + * @throw nothrow + * + * A string function entry consists of the stack position of the return value, followed by a cmSTRFUNC code, the + * function pointer and an index into the string buffer maintained by the parser. + */ +void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) +{ + m_iStackPos = m_iStackPos - a_iArgc + 1; + + SToken tok; + tok.Cmd = cmFUNC_STR; + tok.Fun.argc = a_iArgc; + tok.Fun.idx = a_iIdx; + tok.Fun.ptr = a_pFun; + m_vRPN.push_back(tok); + + m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Add end marker to bytecode. + * + * @throw nothrow + */ +void QmuParserByteCode::Finalize() +{ + SToken tok; + tok.Cmd = cmEND; + m_vRPN.push_back(tok); + rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit + + // Determine the if-then-else jump offsets + QStack stIf, stElse; + int idx; + for (int i=0; i - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERBYTECODE_H -#define QMUPARSERBYTECODE_H - -#include "qmuparserdef.h" -#include "qmuparsererror.h" -#include "qmuparsertoken.h" - -/** - * @file - * @brief Definition of the parser bytecode class. - */ - -namespace qmu -{ -struct SToken -{ - ECmdCode Cmd; - int StackPos; - - union - { - struct //SValData - { - qreal *ptr; - qreal data; - qreal data2; - } Val; - - struct //SFunData - { - // Note: generic_fun_type is merely a placeholder. The real type could be - // anything between gun_type1 and fun_type9. I can't use a void - // pointer due to constraints in the ANSI standard which allows - // data pointers and function pointers to differ in size. - generic_fun_type ptr; - int argc; - int idx; - } Fun; - - struct //SOprtData - { - qreal *ptr; - int offset; - } Oprt; - }; -}; - - -/** - * @brief Bytecode implementation of the Math Parser. - * - * The bytecode contains the formula converted to revers polish notation stored in a continious - * memory area. Associated with this data are operator codes, variable pointers, constant - * values and function pointers. Those are necessary in order to calculate the result. - * All those data items will be casted to the underlying datatype of the bytecode. - * - * @author (C) 2004-2013 Ingo Berg - */ -class QmuParserByteCode -{ -private: - /** @brief Token type for internal use only. */ - typedef QmuParserToken token_type; - - /** @brief Token vector for storing the RPN. */ - typedef QVector rpn_type; - - /** @brief Position in the Calculation array. */ - unsigned m_iStackPos; - - /** @brief Maximum size needed for the stack. */ - std::size_t m_iMaxStackSize; - - /** @brief The actual rpn storage. */ - rpn_type m_vRPN; - - bool m_bEnableOptimizer; - - void ConstantFolding(ECmdCode a_Oprt); -public: - QmuParserByteCode(); - QmuParserByteCode(const QmuParserByteCode &a_ByteCode); - QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); - void Assign(const QmuParserByteCode &a_ByteCode); - void AddVar(qreal *a_pVar); - void AddVal(qreal a_fVal); - void AddOp(ECmdCode a_Oprt); - void AddIfElse(ECmdCode a_Oprt); - void AddAssignOp(qreal *a_pVar); - void AddFun(generic_fun_type a_pFun, int a_iArgc); - void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); - void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); - void EnableOptimizer(bool bStat); - void Finalize(); - void clear(); - std::size_t GetMaxStackSize() const; - std::size_t GetSize() const; - const SToken* GetBase() const; - void AsciiDump(); -}; -} // namespace qmu -#endif - - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERBYTECODE_H +#define QMUPARSERBYTECODE_H + +#include "qmuparserdef.h" +#include "qmuparsererror.h" +#include "qmuparsertoken.h" + +/** + * @file + * @brief Definition of the parser bytecode class. + */ + +namespace qmu +{ +struct SToken +{ + ECmdCode Cmd; + int StackPos; + + union // + { + struct //SValData + { + qreal *ptr; + qreal data; + qreal data2; + } Val; + + struct //SFunData + { + // Note: generic_fun_type is merely a placeholder. The real type could be + // anything between gun_type1 and fun_type9. I can't use a void + // pointer due to constraints in the ANSI standard which allows + // data pointers and function pointers to differ in size. + generic_fun_type ptr; + int argc; + int idx; + } Fun; + + struct //SOprtData + { + qreal *ptr; + int offset; + } Oprt; + }; +}; + + +/** + * @brief Bytecode implementation of the Math Parser. + * + * The bytecode contains the formula converted to revers polish notation stored in a continious + * memory area. Associated with this data are operator codes, variable pointers, constant + * values and function pointers. Those are necessary in order to calculate the result. + * All those data items will be casted to the underlying datatype of the bytecode. + * + * @author (C) 2004-2013 Ingo Berg + */ +class QmuParserByteCode +{ +private: + /** @brief Token type for internal use only. */ + typedef QmuParserToken token_type; + + /** @brief Token vector for storing the RPN. */ + typedef QVector rpn_type; + + /** @brief Position in the Calculation array. */ + unsigned m_iStackPos; + + /** @brief Maximum size needed for the stack. */ + std::size_t m_iMaxStackSize; + + /** @brief The actual rpn storage. */ + rpn_type m_vRPN; + + bool m_bEnableOptimizer; + + void ConstantFolding(ECmdCode a_Oprt); +public: + QmuParserByteCode(); + QmuParserByteCode(const QmuParserByteCode &a_ByteCode); + QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); + void Assign(const QmuParserByteCode &a_ByteCode); + void AddVar(qreal *a_pVar); + void AddVal(qreal a_fVal); + void AddOp(ECmdCode a_Oprt); + void AddIfElse(ECmdCode a_Oprt); + void AddAssignOp(qreal *a_pVar); + void AddFun(generic_fun_type a_pFun, int a_iArgc); + void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); + void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); + void EnableOptimizer(bool bStat); + void Finalize(); + void clear(); + std::size_t GetMaxStackSize() const; + std::size_t GetSize() const; + const SToken* GetBase() const; + void AsciiDump(); +}; +} // namespace qmu +#endif diff --git a/src/libs/qmuparser/qmuparsercallback.cpp b/src/libs/qmuparser/qmuparsercallback.cpp index cf6455863..139d91092 100644 --- a/src/libs/qmuparser/qmuparsercallback.cpp +++ b/src/libs/qmuparser/qmuparsercallback.cpp @@ -29,27 +29,27 @@ namespace qmu { -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- //Supressing specific warnings on gcc/g++ http://www.mr-edd.co.uk/blog/supressing_gcc_warnings #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type0 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), - m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), + m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Constructor for constructing funcstion callbacks taking two arguments. * @throw nothrow @@ -58,11 +58,11 @@ QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Constructor for constructing binary operator callbacks. * @param a_pFun Pointer to a static function taking two arguments @@ -75,104 +75,104 @@ QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti ) __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, - EOprtAssociativity a_eOprtAsct ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), - m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + EOprtAssociativity a_eOprtAsct ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ), + m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Constructor for constructing funcstion callbacks taking two arguments. * @throw nothrow @@ -181,156 +181,156 @@ QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti ) __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- #ifdef __GNUC__ __extension__ #endif QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti ) - : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), - m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) + : m_pFun ( reinterpret_cast ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), + m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Default constructor. * @throw nothrow */ QmuParserCallback::QmuParserCallback() - : m_pFun ( 0 ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), - m_bAllowOpti ( 0 ) + : m_pFun ( 0 ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), + m_bAllowOpti ( 0 ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Copy constructor. * @throw nothrow */ QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref ) - : m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ), - m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti ) + : m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ), + m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti ) { - m_pFun = ref.m_pFun; - m_iArgc = ref.m_iArgc; - m_bAllowOpti = ref.m_bAllowOpti; - m_iCode = ref.m_iCode; - m_iType = ref.m_iType; - m_iPri = ref.m_iPri; - m_eOprtAsct = ref.m_eOprtAsct; + m_pFun = ref.m_pFun; + m_iArgc = ref.m_iArgc; + m_bAllowOpti = ref.m_bAllowOpti; + m_iCode = ref.m_iCode; + m_iType = ref.m_iType; + m_iPri = ref.m_iPri; + m_eOprtAsct = ref.m_eOprtAsct; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Clone this instance and return a pointer to the new instance. */ QmuParserCallback* QmuParserCallback::Clone() const { - return new QmuParserCallback ( *this ); + return new QmuParserCallback ( *this ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return tru if the function is conservative. * @@ -339,10 +339,10 @@ QmuParserCallback* QmuParserCallback::Clone() const */ bool QmuParserCallback::IsOptimizable() const { - return m_bAllowOpti; + return m_bAllowOpti; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Get the callback address for the parser function. * @@ -353,25 +353,25 @@ bool QmuParserCallback::IsOptimizable() const */ void* QmuParserCallback::GetAddr() const { - return m_pFun; + return m_pFun; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return the callback code. */ ECmdCode QmuParserCallback::GetCode() const { - return m_iCode; + return m_iCode; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- ETypeCode QmuParserCallback::GetType() const { - return m_iType; + return m_iType; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return the operator precedence. * @throw nothrown @@ -380,10 +380,10 @@ ETypeCode QmuParserCallback::GetType() const */ int QmuParserCallback::GetPri() const { - return m_iPri; + return m_iPri; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return the operators associativity. * @throw nothrown @@ -392,15 +392,15 @@ int QmuParserCallback::GetPri() const */ EOprtAssociativity QmuParserCallback::GetAssociativity() const { - return m_eOprtAsct; + return m_eOprtAsct; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Returns the number of function Arguments. */ int QmuParserCallback::GetArgc() const { - return m_iArgc; + return m_iArgc; } } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsercallback.h b/src/libs/qmuparser/qmuparsercallback.h index 2ebb4c5f3..2c876bf79 100644 --- a/src/libs/qmuparser/qmuparsercallback.h +++ b/src/libs/qmuparser/qmuparsercallback.h @@ -1,115 +1,114 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERCALLBACK_H -#define QMUPARSERCALLBACK_H - -#include "qmuparserdef.h" - -/** - * @file - * @brief Definition of the parser callback class. - */ - -namespace qmu -{ - -/** - * @brief Encapsulation of prototypes for a numerical parser function. - * - * Encapsulates the prototyp for numerical parser functions. The class stores the number of arguments for parser - * functions as well as additional flags indication the function is non optimizeable. The pointer to the callback - * function pointer is stored as void* and needs to be casted according to the argument count. Negative argument counts - * indicate a parser function with a variable number of arguments. - * - * @author (C) 2004-2011 Ingo Berg - */ -class QmuParserCallback -{ -public: - QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC); - QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity); - QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti); - QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti); - - QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti); - QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti); - - QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti); - QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti); - QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti); - QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti); - QmuParserCallback(); - QmuParserCallback(const QmuParserCallback &a_Fun); - - QmuParserCallback* Clone() const; - bool IsOptimizable() const; - void* GetAddr() const; - ECmdCode GetCode() const; - ETypeCode GetType() const; - int GetPri() const; - EOprtAssociativity GetAssociativity() const; - int GetArgc() const; -private: - void *m_pFun; ///< Pointer to the callback function, casted to void - - /** - * @brief Number of numeric function arguments - * - * This number is negative for functions with variable number of arguments. in this cases - * they represent the actual number of arguments found. - */ - int m_iArgc; - int m_iPri; ///< Valid only for binary and infix operators; Operator precedence. - EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators - ECmdCode m_iCode; - ETypeCode m_iType; - bool m_bAllowOpti; ///< Flag indication optimizeability -}; - -//---------------------------------------------------------------------------------------------------------------------- -/** - * @brief Container for Callback objects. - */ -typedef std::map funmap_type; - -} // namespace qmu - -#endif - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERCALLBACK_H +#define QMUPARSERCALLBACK_H + +#include "qmuparserdef.h" + +/** + * @file + * @brief Definition of the parser callback class. + */ + +namespace qmu +{ + +/** + * @brief Encapsulation of prototypes for a numerical parser function. + * + * Encapsulates the prototyp for numerical parser functions. The class stores the number of arguments for parser + * functions as well as additional flags indication the function is non optimizeable. The pointer to the callback + * function pointer is stored as void* and needs to be casted according to the argument count. Negative argument counts + * indicate a parser function with a variable number of arguments. + * + * @author (C) 2004-2011 Ingo Berg + */ +class QmuParserCallback +{ +public: + QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC); + QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity); + QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti); + QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti); + + QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti); + QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti); + + QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti); + QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti); + QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti); + QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti); + QmuParserCallback(); + QmuParserCallback(const QmuParserCallback &a_Fun); + + QmuParserCallback* Clone() const; + bool IsOptimizable() const; + void* GetAddr() const; + ECmdCode GetCode() const; + ETypeCode GetType() const; + int GetPri() const; + EOprtAssociativity GetAssociativity() const; + int GetArgc() const; +private: + void *m_pFun; ///< Pointer to the callback function, casted to void + + /** + * @brief Number of numeric function arguments + * + * This number is negative for functions with variable number of arguments. in this cases + * they represent the actual number of arguments found. + */ + int m_iArgc; + int m_iPri; ///< Valid only for binary and infix operators; Operator precedence. + EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators + ECmdCode m_iCode; + ETypeCode m_iType; + bool m_bAllowOpti; ///< Flag indication optimizeability +}; + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Container for Callback objects. + */ +typedef std::map funmap_type; + +} // namespace qmu + +#endif diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 4edd3f390..6f4b2aa0d 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -47,11 +47,11 @@ //#define QMUP_USE_OPENMP #if defined(_UNICODE) - /** @brief Definition of the basic parser string type. */ - #define QMUP_STRING_TYPE std::wstring + /** @brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::wstring #else - /** @brief Definition of the basic parser string type. */ - #define QMUP_STRING_TYPE std::string + /** @brief Definition of the basic parser string type. */ + #define QMUP_STRING_TYPE std::string #endif namespace qmu @@ -272,4 +272,3 @@ typedef qreal* ( *facfun_type ) ( const QString &, void* ); } // end of namespace #endif - diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 543d60d9f..ab5c237cb 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -28,116 +28,116 @@ namespace qmu { const QmuParserErrorMsg QmuParserErrorMsg::m_Instance; -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- const QmuParserErrorMsg& QmuParserErrorMsg::Instance() { - return m_Instance; + return m_Instance; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const { - return ( a_iIdx < static_cast( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString(); + return ( a_iIdx < static_cast( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString(); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QmuParserErrorMsg::~QmuParserErrorMsg() {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QmuParserErrorMsg::QmuParserErrorMsg() - : m_vErrMsg ( 0 ) + : m_vErrMsg ( 0 ) { - m_vErrMsg.resize ( ecCOUNT ); + m_vErrMsg.resize ( ecCOUNT ); - m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$."; - m_vErrMsg[ecINTERNAL_ERROR] = "Internal error"; - m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\"."; - m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\"."; - m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\"."; - m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\"."; - m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function."; - m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty."; - m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable."; - m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$"; - m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$"; - m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$"; - m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$"; - m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$"; - m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$"; - m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$"; - m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)"; - m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis"; - m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$"; - m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$"; - m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero"; - m_vErrMsg[ecDOMAIN_ERROR] = "Domain error"; - m_vErrMsg[ecNAME_CONFLICT] = "Name conflict"; - m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero)."; - m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator."; - m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$."; - m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$."; - m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument."; - m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected."; - m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$."; - m_vErrMsg[ecSTR_RESULT] = "Function result is a string."; - m_vErrMsg[ecGENERIC] = "Parser error."; - m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator."; - m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket."; - m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause"; - m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$"; + m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$."; + m_vErrMsg[ecINTERNAL_ERROR] = "Internal error"; + m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\"."; + m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\"."; + m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function."; + m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty."; + m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable."; + m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$"; + m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$"; + m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$"; + m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$"; + m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$"; + m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)"; + m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis"; + m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$"; + m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$"; + m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero"; + m_vErrMsg[ecDOMAIN_ERROR] = "Domain error"; + m_vErrMsg[ecNAME_CONFLICT] = "Name conflict"; + m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero)."; + m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator."; + m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$."; + m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$."; + m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument."; + m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected."; + m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$."; + m_vErrMsg[ecSTR_RESULT] = "Function result is a string."; + m_vErrMsg[ecGENERIC] = "Parser error."; + m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator."; + m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket."; + m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause"; + m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$"; #if defined(_DEBUG) - for ( int i = 0; i < ecCOUNT; ++i ) - { - if ( !m_vErrMsg[i].length() ) - { - assert ( false ); - } - } + for ( int i = 0; i < ecCOUNT; ++i ) + { + if ( m_vErrMsg[i].length() == false) + { + assert ( false ); + } + } #endif } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- // // QParserError class // -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Default constructor. */ QmuParserError::QmuParserError() - : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), - m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) { } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief This Constructor is used for internal exceptions only. * * It does not contain any information but the error code. */ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) - : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), - m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - m_strMsg = m_ErrMsg[m_iErrc]; - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + m_strMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Construct an error from a message text. */ QmuParserError::QmuParserError ( const QString &sMsg ) - : m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), - m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Construct an error object. * @param [in] a_iErrc the error code. @@ -149,15 +149,15 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc, const QString &sTok, const QString &sExpr, int iPos ) - : m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), - m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - m_strMsg = m_ErrMsg[m_iErrc]; - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + m_strMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Construct an error object. * @param [in] iErrc the error code. @@ -165,58 +165,58 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc, * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( EErrorCodes iErrc, int iPos, const QString &sTok ) - : m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), - m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - m_strMsg = m_ErrMsg[m_iErrc]; - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + m_strMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** @brief Construct an error object. * @param [in] szMsg The error message text. * @param [in] iPos the position related to the error. * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok ) - : m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), - m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), + m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** @brief Copy constructor. */ QmuParserError::QmuParserError ( const QmuParserError &a_Obj ) - : m_strMsg ( a_Obj.m_strMsg ), m_strFormula ( a_Obj.m_strFormula ), m_strTok ( a_Obj.m_strTok ), - m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) + : m_strMsg ( a_Obj.m_strMsg ), m_strFormula ( a_Obj.m_strFormula ), m_strTok ( a_Obj.m_strTok ), + m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** @brief Assignment operator. */ QmuParserError& QmuParserError::operator= ( const QmuParserError &a_Obj ) { - if ( this == &a_Obj ) - { - return *this; - } + if ( this == &a_Obj ) + { + return *this; + } - m_strMsg = a_Obj.m_strMsg; - m_strFormula = a_Obj.m_strFormula; - m_strTok = a_Obj.m_strTok; - m_iPos = a_Obj.m_iPos; - m_iErrc = a_Obj.m_iErrc; - return *this; + m_strMsg = a_Obj.m_strMsg; + m_strFormula = a_Obj.m_strFormula; + m_strTok = a_Obj.m_strTok; + m_iPos = a_Obj.m_iPos; + m_iErrc = a_Obj.m_iErrc; + return *this; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QmuParserError::~QmuParserError() {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Replace all ocuurences of a substring with another string. * @param strFind The string that shall be replaced. @@ -224,65 +224,67 @@ QmuParserError::~QmuParserError() */ void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ) { - QString strResult; - int iPos ( 0 ), iNext ( 0 ); + QString strResult; + int iPos ( 0 ), iNext ( 0 ); - for ( ;; ) - { - iNext = strSource.indexOf ( strFind, iPos ); - strResult.append ( strSource.mid ( iPos, iNext - iPos ) ); + for ( ;; ) + { + iNext = strSource.indexOf ( strFind, iPos ); + strResult.append ( strSource.mid ( iPos, iNext - iPos ) ); - if ( iNext == -1 ) - break; + if ( iNext == -1 ) + { + break; + } - strResult.append ( strReplaceWith ); - iPos = iNext + strFind.length(); - } + strResult.append ( strReplaceWith ); + iPos = iNext + strFind.length(); + } - strSource.swap ( strResult ); + strSource.swap ( strResult ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Reset the erro object. */ void QmuParserError::Reset() { - m_strMsg.clear(); - m_strFormula.clear(); - m_strTok.clear(); - m_iPos = -1; - m_iErrc = ecUNDEFINED; + m_strMsg.clear(); + m_strFormula.clear(); + m_strTok.clear(); + m_iPos = -1; + m_iErrc = ecUNDEFINED; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Set the expression related to this error. */ void QmuParserError::SetFormula ( const QString &a_strFormula ) { - m_strFormula = a_strFormula; + m_strFormula = a_strFormula; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief gets the expression related tp this error. */ const QString& QmuParserError::GetExpr() const { - return m_strFormula; + return m_strFormula; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Returns the message string for this error. */ const QString& QmuParserError::GetMsg() const { - return m_strMsg; + return m_strMsg; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return the formula position related to the error. * @@ -290,24 +292,24 @@ const QString& QmuParserError::GetMsg() const */ std::size_t QmuParserError::GetPos() const { - return m_iPos; + return m_iPos; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return string related with this token (if available). */ const QString& QmuParserError::GetToken() const { - return m_strTok; + return m_strTok; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return the error code. */ EErrorCodes QmuParserError::GetCode() const { - return m_iErrc; + return m_iErrc; } } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index 0ed154df6..645fba258 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -97,18 +97,18 @@ enum EErrorCodes class QmuParserErrorMsg { public: - typedef QmuParserErrorMsg self_type; + typedef QmuParserErrorMsg self_type; - QmuParserErrorMsg(); - ~QmuParserErrorMsg(); + QmuParserErrorMsg(); + ~QmuParserErrorMsg(); - static const QmuParserErrorMsg& Instance(); - QString operator[] ( unsigned a_iIdx ) const; + static const QmuParserErrorMsg& Instance(); + QString operator[] ( unsigned a_iIdx ) const; private: - Q_DISABLE_COPY(QmuParserErrorMsg) - QVector m_vErrMsg; ///< A vector with the predefined error messages - static const self_type m_Instance; ///< The instance pointer + Q_DISABLE_COPY(QmuParserErrorMsg) + QVector m_vErrMsg; ///< A vector with the predefined error messages + static const self_type m_Instance; ///< The instance pointer }; //--------------------------------------------------------------------------- @@ -121,38 +121,37 @@ class QmuParserError { public: - QmuParserError(); - explicit QmuParserError ( EErrorCodes a_iErrc ); - explicit QmuParserError ( const QString &sMsg ); - QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 ); - QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok ); - QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() ); - QmuParserError ( const QmuParserError &a_Obj ); - QmuParserError& operator= ( const QmuParserError &a_Obj ); - ~QmuParserError(); + QmuParserError(); + explicit QmuParserError ( EErrorCodes a_iErrc ); + explicit QmuParserError ( const QString &sMsg ); + QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 ); + QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok ); + QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() ); + QmuParserError ( const QmuParserError &a_Obj ); + QmuParserError& operator= ( const QmuParserError &a_Obj ); + ~QmuParserError(); - void SetFormula ( const QString &a_strFormula ); - const QString& GetExpr() const; - const QString& GetMsg() const; - std::size_t GetPos() const; - const QString& GetToken() const; - EErrorCodes GetCode() const; + void SetFormula ( const QString &a_strFormula ); + const QString& GetExpr() const; + const QString& GetMsg() const; + std::size_t GetPos() const; + const QString& GetToken() const; + EErrorCodes GetCode() const; private: - QString m_strMsg; ///< The message string - QString m_strFormula; ///< Formula string - QString m_strTok; ///< Token related with the error - int m_iPos; ///< Formula position related to the error - EErrorCodes m_iErrc; ///< Error code - const QmuParserErrorMsg &m_ErrMsg; - /** - * @brief Replace all ocuurences of a substring with another string. - */ - void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ); - void Reset(); + QString m_strMsg; ///< The message string + QString m_strFormula; ///< Formula string + QString m_strTok; ///< Token related with the error + int m_iPos; ///< Formula position related to the error + EErrorCodes m_iErrc; ///< Error code + const QmuParserErrorMsg &m_ErrMsg; + /** + * @brief Replace all ocuurences of a substring with another string. + */ + void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ); + void Reset(); }; } // namespace qmu #endif - diff --git a/src/libs/qmuparser/qmuparserfixes.h b/src/libs/qmuparser/qmuparserfixes.h index be7056930..85b4298cd 100644 --- a/src/libs/qmuparser/qmuparserfixes.h +++ b/src/libs/qmuparser/qmuparserfixes.h @@ -1,59 +1,57 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERFIXES_H -#define QMUPARSERFIXES_H - -/** @file - @brief This file contains compatibility fixes for some platforms. -*/ - -// -// Compatibility fixes -// - -//--------------------------------------------------------------------------- -// -// Intel Compiler -// -//--------------------------------------------------------------------------- - -#ifdef __INTEL_COMPILER - -// remark #981: operands are evaluated in unspecified order -// disabled -> completely pointless if the functions do not have side effects -// -#pragma warning(disable:981) - -// remark #383: value copied to temporary, reference to temporary used -#pragma warning(disable:383) - -// remark #1572: floating-point equality and inequality comparisons are unreliable -// disabled -> everyone knows it, the parser passes this problem -// deliberately to the user -#pragma warning(disable:1572) - -#endif - -#endif // include guard - - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERFIXES_H +#define QMUPARSERFIXES_H + +/** @file + @brief This file contains compatibility fixes for some platforms. +*/ + +// +// Compatibility fixes +// + +//--------------------------------------------------------------------------- +// +// Intel Compiler +// +//--------------------------------------------------------------------------- + +#ifdef __INTEL_COMPILER + +// remark #981: operands are evaluated in unspecified order +// disabled -> completely pointless if the functions do not have side effects +// +#pragma warning(disable:981) + +// remark #383: value copied to temporary, reference to temporary used +#pragma warning(disable:383) + +// remark #1572: floating-point equality and inequality comparisons are unreliable +// disabled -> everyone knows it, the parser passes this problem +// deliberately to the user +#pragma warning(disable:1572) + +#endif + +#endif // include guard diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index fa6fcb4b1..95305cdc5 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -41,1179 +41,1177 @@ namespace Test { int QmuParserTester::c_iCount = 0; -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QmuParserTester::QmuParserTester() - : m_vTestFun() + : m_vTestFun() { - AddTest ( &QmuParserTester::TestNames ); - AddTest ( &QmuParserTester::TestSyntax ); - AddTest ( &QmuParserTester::TestPostFix ); - AddTest ( &QmuParserTester::TestInfixOprt ); - AddTest ( &QmuParserTester::TestVarConst ); - AddTest ( &QmuParserTester::TestMultiArg ); - AddTest ( &QmuParserTester::TestExpression ); - AddTest ( &QmuParserTester::TestIfThenElse ); - AddTest ( &QmuParserTester::TestInterface ); - AddTest ( &QmuParserTester::TestBinOprt ); - AddTest ( &QmuParserTester::TestException ); - AddTest ( &QmuParserTester::TestStrArg ); + AddTest ( &QmuParserTester::TestNames ); + AddTest ( &QmuParserTester::TestSyntax ); + AddTest ( &QmuParserTester::TestPostFix ); + AddTest ( &QmuParserTester::TestInfixOprt ); + AddTest ( &QmuParserTester::TestVarConst ); + AddTest ( &QmuParserTester::TestMultiArg ); + AddTest ( &QmuParserTester::TestExpression ); + AddTest ( &QmuParserTester::TestIfThenElse ); + AddTest ( &QmuParserTester::TestInterface ); + AddTest ( &QmuParserTester::TestBinOprt ); + AddTest ( &QmuParserTester::TestException ); + AddTest ( &QmuParserTester::TestStrArg ); - QmuParserTester::c_iCount = 0; + QmuParserTester::c_iCount = 0; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ) { - if ( a_szExpr[1] == 0 || ( a_szExpr[0] != '0' || a_szExpr[1] != 'x' ) ) - { - return 0; - } + if ( a_szExpr[1] == 0 || ( a_szExpr[0] != '0' || a_szExpr[1] != 'x' ) ) + { + return 0; + } - unsigned iVal ( 0 ); - bool ok = false; - iVal = a_szExpr.toUInt ( &ok, 16 ); + unsigned iVal ( 0 ); + bool ok = false; + iVal = a_szExpr.toUInt ( &ok, 16 ); - if ( ok ) - { - int nPos = a_szExpr.indexOf ( QString().setNum ( iVal, 16 ) ); - if ( nPos == 0 ) - { - return 1; - } + if ( ok ) + { + int nPos = a_szExpr.indexOf ( QString().setNum ( iVal, 16 ) ); + if ( nPos == 0 ) + { + return 1; + } - *a_iPos += 2 + nPos; - *a_fVal = static_cast(iVal); - return 1; - } - else - { - return 0; - } + *a_iPos += 2 + nPos; + *a_fVal = static_cast(iVal); + return 1; + } + else + { + return 0; + } } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestInterface() { - int iStat = 0; - qDebug() << "testing member functions..."; + int iStat = 0; + qDebug() << "testing member functions..."; - // Test RemoveVar - qreal afVal[3] = {1, 2, 3}; - QmuParser p; + // Test RemoveVar + qreal afVal[3] = {1, 2, 3}; + QmuParser p; - try - { - p.DefineVar ( "a", &afVal[0] ); - p.DefineVar ( "b", &afVal[1] ); - p.DefineVar ( "c", &afVal[2] ); - p.SetExpr ( "a+b+c" ); - p.Eval(); - } - catch ( ... ) - { - iStat += 1; // this is not supposed to happen - } + try + { + p.DefineVar ( "a", &afVal[0] ); + p.DefineVar ( "b", &afVal[1] ); + p.DefineVar ( "c", &afVal[2] ); + p.SetExpr ( "a+b+c" ); + p.Eval(); + } + catch ( ... ) + { + iStat += 1; // this is not supposed to happen + } - try - { - p.RemoveVar ( "c" ); - p.Eval(); - iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... - } - catch ( ... ) - { - // failure is expected... - } + try + { + p.RemoveVar ( "c" ); + p.Eval(); + iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted... + } + catch ( ... ) + { + // failure is expected... + } - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestStrArg() { - int iStat = 0; - qDebug() << "testing string arguments..."; + int iStat = 0; + qDebug() << "testing string arguments..."; - iStat += EqnTest ( "valueof(\"\")", 123, true ); // empty string arguments caused a crash - iStat += EqnTest ( "valueof(\"aaa\")+valueof(\"bbb\") ", 246, true ); - iStat += EqnTest ( "2*(valueof(\"aaa\")-23)+valueof(\"bbb\")", 323, true ); - // use in expressions with variables - iStat += EqnTest ( "a*(atof(\"10\")-b)", 8, true ); - iStat += EqnTest ( "a-(atof(\"10\")*b)", -19, true ); - // string + numeric arguments - iStat += EqnTest ( "strfun1(\"100\")", 100, true ); - iStat += EqnTest ( "strfun2(\"100\",1)", 101, true ); - iStat += EqnTest ( "strfun3(\"99\",1,2)", 102, true ); + iStat += EqnTest ( "valueof(\"\")", 123, true ); // empty string arguments caused a crash + iStat += EqnTest ( "valueof(\"aaa\")+valueof(\"bbb\") ", 246, true ); + iStat += EqnTest ( "2*(valueof(\"aaa\")-23)+valueof(\"bbb\")", 323, true ); + // use in expressions with variables + iStat += EqnTest ( "a*(atof(\"10\")-b)", 8, true ); + iStat += EqnTest ( "a-(atof(\"10\")*b)", -19, true ); + // string + numeric arguments + iStat += EqnTest ( "strfun1(\"100\")", 100, true ); + iStat += EqnTest ( "strfun2(\"100\",1)", 101, true ); + iStat += EqnTest ( "strfun3(\"99\",1,2)", 102, true ); - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestBinOprt() { - int iStat = 0; - qDebug() << "testing binary operators..."; + int iStat = 0; + qDebug() << "testing binary operators..."; - // built in operators - // xor operator - //iStat += EqnTest("1 xor 2", 3, true); - //iStat += EqnTest("a xor b", 3, true); // with a=1 and b=2 - //iStat += EqnTest("1 xor 2 xor 3", 0, true); - //iStat += EqnTest("a xor b xor 3", 0, true); // with a=1 and b=2 - //iStat += EqnTest("a xor b xor c", 0, true); // with a=1 and b=2 - //iStat += EqnTest("(1 xor 2) xor 3", 0, true); - //iStat += EqnTest("(a xor b) xor c", 0, true); // with a=1 and b=2 - //iStat += EqnTest("(a) xor (b) xor c", 0, true); // with a=1 and b=2 - //iStat += EqnTest("1 or 2"), 3, true; - //iStat += EqnTest("a or b"), 3, true; // with a=1 and b=2 - iStat += EqnTest ( "a++b", 3, true ); - iStat += EqnTest ( "a ++ b", 3, true ); - iStat += EqnTest ( "1++2", 3, true ); - iStat += EqnTest ( "1 ++ 2", 3, true ); - iStat += EqnTest ( "a add b", 3, true ); - iStat += EqnTest ( "1 add 2", 3, true ); - iStat += EqnTest ( "aa", 1, true ); - iStat += EqnTest ( "a>a", 0, true ); - iStat += EqnTest ( "aa", 0, true ); - iStat += EqnTest ( "a<=a", 1, true ); - iStat += EqnTest ( "a<=b", 1, true ); - iStat += EqnTest ( "b<=a", 0, true ); - iStat += EqnTest ( "a>=a", 1, true ); - iStat += EqnTest ( "b>=a", 1, true ); - iStat += EqnTest ( "a>=b", 0, true ); + // built in operators + // xor operator + //iStat += EqnTest("1 xor 2", 3, true); + //iStat += EqnTest("a xor b", 3, true); // with a=1 and b=2 + //iStat += EqnTest("1 xor 2 xor 3", 0, true); + //iStat += EqnTest("a xor b xor 3", 0, true); // with a=1 and b=2 + //iStat += EqnTest("a xor b xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("(1 xor 2) xor 3", 0, true); + //iStat += EqnTest("(a xor b) xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("(a) xor (b) xor c", 0, true); // with a=1 and b=2 + //iStat += EqnTest("1 or 2"), 3, true; + //iStat += EqnTest("a or b"), 3, true; // with a=1 and b=2 + iStat += EqnTest ( "a++b", 3, true ); + iStat += EqnTest ( "a ++ b", 3, true ); + iStat += EqnTest ( "1++2", 3, true ); + iStat += EqnTest ( "1 ++ 2", 3, true ); + iStat += EqnTest ( "a add b", 3, true ); + iStat += EqnTest ( "1 add 2", 3, true ); + iStat += EqnTest ( "aa", 1, true ); + iStat += EqnTest ( "a>a", 0, true ); + iStat += EqnTest ( "aa", 0, true ); + iStat += EqnTest ( "a<=a", 1, true ); + iStat += EqnTest ( "a<=b", 1, true ); + iStat += EqnTest ( "b<=a", 0, true ); + iStat += EqnTest ( "a>=a", 1, true ); + iStat += EqnTest ( "b>=a", 1, true ); + iStat += EqnTest ( "a>=b", 0, true ); - // Test logical operators, expecially if user defined "&" and the internal "&&" collide - iStat += EqnTest ( "1 && 1", 1, true ); - iStat += EqnTest ( "1 && 0", 0, true ); - iStat += EqnTest ( "(aa)", 1, true ); - iStat += EqnTest ( "(ab)", 0, true ); - //iStat += EqnTest("12 and 255", 12, true); - //iStat += EqnTest("12 and 0", 0, true); - iStat += EqnTest ( "12 & 255", 12, true ); - iStat += EqnTest ( "12 & 0", 0, true ); - iStat += EqnTest ( "12&255", 12, true ); - iStat += EqnTest ( "12&0", 0, true ); + // Test logical operators, expecially if user defined "&" and the internal "&&" collide + iStat += EqnTest ( "1 && 1", 1, true ); + iStat += EqnTest ( "1 && 0", 0, true ); + iStat += EqnTest ( "(aa)", 1, true ); + iStat += EqnTest ( "(ab)", 0, true ); + //iStat += EqnTest("12 and 255", 12, true); + //iStat += EqnTest("12 and 0", 0, true); + iStat += EqnTest ( "12 & 255", 12, true ); + iStat += EqnTest ( "12 & 0", 0, true ); + iStat += EqnTest ( "12&255", 12, true ); + iStat += EqnTest ( "12&0", 0, true ); - // Assignement operator - iStat += EqnTest ( "a = b", 2, true ); - iStat += EqnTest ( "a = sin(b)", 0.909297, true ); - iStat += EqnTest ( "a = 1+sin(b)", 1.909297, true ); - iStat += EqnTest ( "(a=b)*2", 4, true ); - iStat += EqnTest ( "2*(a=b)", 4, true ); - iStat += EqnTest ( "2*(a=b+1)", 6, true ); - iStat += EqnTest ( "(a=b+1)*2", 6, true ); + // Assignement operator + iStat += EqnTest ( "a = b", 2, true ); + iStat += EqnTest ( "a = sin(b)", 0.909297, true ); + iStat += EqnTest ( "a = 1+sin(b)", 1.909297, true ); + iStat += EqnTest ( "(a=b)*2", 4, true ); + iStat += EqnTest ( "2*(a=b)", 4, true ); + iStat += EqnTest ( "2*(a=b+1)", 6, true ); + iStat += EqnTest ( "(a=b+1)*2", 6, true ); - iStat += EqnTest ( "2^2^3", 256, true ); - iStat += EqnTest ( "1/2/3", 1.0 / 6.0, true ); + iStat += EqnTest ( "2^2^3", 256, true ); + iStat += EqnTest ( "1/2/3", 1.0 / 6.0, true ); - // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 - iStat += EqnTest ( "3+4*2/(1-5)^2^3", 3.0001220703125, true ); + // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3 + iStat += EqnTest ( "3+4*2/(1-5)^2^3", 3.0001220703125, true ); - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** @brief Check muParser name restriction enforcement. */ int QmuParserTester::TestNames() { - int iStat = 0, - iErr = 0; + int iStat = 0, + iErr = 0; - qDebug() << "testing name restriction enforcement..."; + qDebug() << "testing name restriction enforcement..."; - QmuParser p; + QmuParser p; #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \ iErr = 0; \ QmuParserTester::c_iCount++; \ try \ { \ - p.Define##DOMAIN(EXPR, ARG); \ + p.Define##DOMAIN(EXPR, ARG); \ } \ - catch(QmuParser::exception_type&) \ + catch (QmuParser::exception_type&) \ { \ iErr = (FAIL==false) ? 0 : 1; \ } \ iStat += iErr; - // constant names - PARSER_THROWCHECK ( Const, false, "0a", 1 ) - PARSER_THROWCHECK ( Const, false, "9a", 1 ) - PARSER_THROWCHECK ( Const, false, "+a", 1 ) - PARSER_THROWCHECK ( Const, false, "-a", 1 ) - PARSER_THROWCHECK ( Const, false, "a-", 1 ) - PARSER_THROWCHECK ( Const, false, "a*", 1 ) - PARSER_THROWCHECK ( Const, false, "a?", 1 ) - PARSER_THROWCHECK ( Const, true, "a", 1 ) - PARSER_THROWCHECK ( Const, true, "a_min", 1 ) - PARSER_THROWCHECK ( Const, true, "a_min0", 1 ) - PARSER_THROWCHECK ( Const, true, "a_min9", 1 ) - // variable names - qreal a; - p.ClearConst(); - PARSER_THROWCHECK ( Var, false, "123abc", &a ) - PARSER_THROWCHECK ( Var, false, "9a", &a ) - PARSER_THROWCHECK ( Var, false, "0a", &a ) - PARSER_THROWCHECK ( Var, false, "+a", &a ) - PARSER_THROWCHECK ( Var, false, "-a", &a ) - PARSER_THROWCHECK ( Var, false, "?a", &a ) - PARSER_THROWCHECK ( Var, false, "!a", &a ) - PARSER_THROWCHECK ( Var, false, "a+", &a ) - PARSER_THROWCHECK ( Var, false, "a-", &a ) - PARSER_THROWCHECK ( Var, false, "a*", &a ) - PARSER_THROWCHECK ( Var, false, "a?", &a ) - PARSER_THROWCHECK ( Var, true, "a", &a ) - PARSER_THROWCHECK ( Var, true, "a_min", &a ) - PARSER_THROWCHECK ( Var, true, "a_min0", &a ) - PARSER_THROWCHECK ( Var, true, "a_min9", &a ) - PARSER_THROWCHECK ( Var, false, "a_min9", 0 ) - // Postfix operators - // fail - PARSER_THROWCHECK ( PostfixOprt, false, "(k", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, false, "9+", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, false, "+", 0 ) - // pass - PARSER_THROWCHECK ( PostfixOprt, true, "-a", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "?a", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "_", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "#", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "&&", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "||", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "&", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "|", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "++", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "--", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "?>", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "?<", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "**", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "xor", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "and", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "or", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "not", f1of1 ) - PARSER_THROWCHECK ( PostfixOprt, true, "!", f1of1 ) - // Binary operator - // The following must fail with builtin operators activated - // p.EnableBuiltInOp(true); -> this is the default - p.ClearPostfixOprt(); - PARSER_THROWCHECK ( Oprt, false, "+", f1of2 ) - PARSER_THROWCHECK ( Oprt, false, "-", f1of2 ) - PARSER_THROWCHECK ( Oprt, false, "*", f1of2 ) - PARSER_THROWCHECK ( Oprt, false, "/", f1of2 ) - PARSER_THROWCHECK ( Oprt, false, "^", f1of2 ) - PARSER_THROWCHECK ( Oprt, false, "&&", f1of2 ) - PARSER_THROWCHECK ( Oprt, false, "||", f1of2 ) - // without activated built in operators it should work - p.EnableBuiltInOprt ( false ); - PARSER_THROWCHECK ( Oprt, true, "+", f1of2 ) - PARSER_THROWCHECK ( Oprt, true, "-", f1of2 ) - PARSER_THROWCHECK ( Oprt, true, "*", f1of2 ) - PARSER_THROWCHECK ( Oprt, true, "/", f1of2 ) - PARSER_THROWCHECK ( Oprt, true, "^", f1of2 ) - PARSER_THROWCHECK ( Oprt, true, "&&", f1of2 ) - PARSER_THROWCHECK ( Oprt, true, "||", f1of2 ) + // constant names + PARSER_THROWCHECK ( Const, false, "0a", 1 ) + PARSER_THROWCHECK ( Const, false, "9a", 1 ) + PARSER_THROWCHECK ( Const, false, "+a", 1 ) + PARSER_THROWCHECK ( Const, false, "-a", 1 ) + PARSER_THROWCHECK ( Const, false, "a-", 1 ) + PARSER_THROWCHECK ( Const, false, "a*", 1 ) + PARSER_THROWCHECK ( Const, false, "a?", 1 ) + PARSER_THROWCHECK ( Const, true, "a", 1 ) + PARSER_THROWCHECK ( Const, true, "a_min", 1 ) + PARSER_THROWCHECK ( Const, true, "a_min0", 1 ) + PARSER_THROWCHECK ( Const, true, "a_min9", 1 ) + // variable names + qreal a; + p.ClearConst(); + PARSER_THROWCHECK ( Var, false, "123abc", &a ) + PARSER_THROWCHECK ( Var, false, "9a", &a ) + PARSER_THROWCHECK ( Var, false, "0a", &a ) + PARSER_THROWCHECK ( Var, false, "+a", &a ) + PARSER_THROWCHECK ( Var, false, "-a", &a ) + PARSER_THROWCHECK ( Var, false, "?a", &a ) + PARSER_THROWCHECK ( Var, false, "!a", &a ) + PARSER_THROWCHECK ( Var, false, "a+", &a ) + PARSER_THROWCHECK ( Var, false, "a-", &a ) + PARSER_THROWCHECK ( Var, false, "a*", &a ) + PARSER_THROWCHECK ( Var, false, "a?", &a ) + PARSER_THROWCHECK ( Var, true, "a", &a ) + PARSER_THROWCHECK ( Var, true, "a_min", &a ) + PARSER_THROWCHECK ( Var, true, "a_min0", &a ) + PARSER_THROWCHECK ( Var, true, "a_min9", &a ) + PARSER_THROWCHECK ( Var, false, "a_min9", 0 ) + // Postfix operators + // fail + PARSER_THROWCHECK ( PostfixOprt, false, "(k", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, false, "9+", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, false, "+", 0 ) + // pass + PARSER_THROWCHECK ( PostfixOprt, true, "-a", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "?a", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "_", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "#", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "&&", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "||", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "&", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "|", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "++", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "--", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "?>", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "?<", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "**", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "xor", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "and", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "or", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "not", f1of1 ) + PARSER_THROWCHECK ( PostfixOprt, true, "!", f1of1 ) + // Binary operator + // The following must fail with builtin operators activated + // p.EnableBuiltInOp(true); -> this is the default + p.ClearPostfixOprt(); + PARSER_THROWCHECK ( Oprt, false, "+", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "-", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "*", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "/", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "^", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "&&", f1of2 ) + PARSER_THROWCHECK ( Oprt, false, "||", f1of2 ) + // without activated built in operators it should work + p.EnableBuiltInOprt ( false ); + PARSER_THROWCHECK ( Oprt, true, "+", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "-", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "*", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "/", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "^", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "&&", f1of2 ) + PARSER_THROWCHECK ( Oprt, true, "||", f1of2 ) #undef PARSER_THROWCHECK - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestSyntax() { - int iStat = 0; - qDebug() << "testing syntax engine..."; + int iStat = 0; + qDebug() << "testing syntax engine..."; - iStat += ThrowTest ( "1,", ecUNEXPECTED_EOF ); // incomplete hex definition - iStat += ThrowTest ( "a,", ecUNEXPECTED_EOF ); // incomplete hex definition - iStat += ThrowTest ( "sin(8),", ecUNEXPECTED_EOF ); // incomplete hex definition - iStat += ThrowTest ( "(sin(8)),", ecUNEXPECTED_EOF ); // incomplete hex definition - iStat += ThrowTest ( "a{m},", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "1,", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "a,", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "sin(8),", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "(sin(8)),", ecUNEXPECTED_EOF ); // incomplete hex definition + iStat += ThrowTest ( "a{m},", ecUNEXPECTED_EOF ); // incomplete hex definition - iStat += EqnTest ( "(1+ 2*a)", 3, true ); // Spaces within formula - iStat += EqnTest ( "sqrt((4))", 2, true ); // Multiple brackets - iStat += EqnTest ( "sqrt((2)+2)", 2, true ); // Multiple brackets - iStat += EqnTest ( "sqrt(2+(2))", 2, true ); // Multiple brackets - iStat += EqnTest ( "sqrt(a+(3))", 2, true ); // Multiple brackets - iStat += EqnTest ( "sqrt((3)+a)", 2, true ); // Multiple brackets - iStat += EqnTest ( "order(1,2)", 1, true ); // May not cause name collision with operator "or" - iStat += EqnTest ( "(2+", 0, false ); // missing closing bracket - iStat += EqnTest ( "2++4", 0, false ); // unexpected operator - iStat += EqnTest ( "2+-4", 0, false ); // unexpected operator - iStat += EqnTest ( "(2+)", 0, false ); // unexpected closing bracket - iStat += EqnTest ( "--2", 0, false ); // double sign - iStat += EqnTest ( "ksdfj", 0, false ); // unknown token - iStat += EqnTest ( "()", 0, false ); // empty bracket without a function - iStat += EqnTest ( "5+()", 0, false ); // empty bracket without a function - iStat += EqnTest ( "sin(cos)", 0, false ); // unexpected function - iStat += EqnTest ( "5t6", 0, false ); // unknown token - iStat += EqnTest ( "5 t 6", 0, false ); // unknown token - iStat += EqnTest ( "8*", 0, false ); // unexpected end of formula - iStat += EqnTest ( ",3", 0, false ); // unexpected comma - iStat += EqnTest ( "3,5", 0, false ); // unexpected comma - iStat += EqnTest ( "sin(8,8)", 0, false ); // too many function args - iStat += EqnTest ( "(7,8)", 0, false ); // too many function args - iStat += EqnTest ( "sin)", 0, false ); // unexpected closing bracket - iStat += EqnTest ( "a)", 0, false ); // unexpected closing bracket - iStat += EqnTest ( "pi)", 0, false ); // unexpected closing bracket - iStat += EqnTest ( "sin(())", 0, false ); // unexpected closing bracket - iStat += EqnTest ( "sin()", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "(1+ 2*a)", 3, true ); // Spaces within formula + iStat += EqnTest ( "sqrt((4))", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt((2)+2)", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt(2+(2))", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt(a+(3))", 2, true ); // Multiple brackets + iStat += EqnTest ( "sqrt((3)+a)", 2, true ); // Multiple brackets + iStat += EqnTest ( "order(1,2)", 1, true ); // May not cause name collision with operator "or" + iStat += EqnTest ( "(2+", 0, false ); // missing closing bracket + iStat += EqnTest ( "2++4", 0, false ); // unexpected operator + iStat += EqnTest ( "2+-4", 0, false ); // unexpected operator + iStat += EqnTest ( "(2+)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "--2", 0, false ); // double sign + iStat += EqnTest ( "ksdfj", 0, false ); // unknown token + iStat += EqnTest ( "()", 0, false ); // empty bracket without a function + iStat += EqnTest ( "5+()", 0, false ); // empty bracket without a function + iStat += EqnTest ( "sin(cos)", 0, false ); // unexpected function + iStat += EqnTest ( "5t6", 0, false ); // unknown token + iStat += EqnTest ( "5 t 6", 0, false ); // unknown token + iStat += EqnTest ( "8*", 0, false ); // unexpected end of formula + iStat += EqnTest ( ",3", 0, false ); // unexpected comma + iStat += EqnTest ( "3,5", 0, false ); // unexpected comma + iStat += EqnTest ( "sin(8,8)", 0, false ); // too many function args + iStat += EqnTest ( "(7,8)", 0, false ); // too many function args + iStat += EqnTest ( "sin)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "a)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "pi)", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "sin(())", 0, false ); // unexpected closing bracket + iStat += EqnTest ( "sin()", 0, false ); // unexpected closing bracket - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestVarConst() { - int iStat = 0; - qDebug() << "testing variable/constant detection..."; + int iStat = 0; + qDebug() << "testing variable/constant detection..."; - // Test if the result changes when a variable changes - iStat += EqnTestWithVarChange ( "a", 1, 1, 2, 2 ); - iStat += EqnTestWithVarChange ( "2*a", 2, 4, 3, 6 ); + // Test if the result changes when a variable changes + iStat += EqnTestWithVarChange ( "a", 1, 1, 2, 2 ); + iStat += EqnTestWithVarChange ( "2*a", 2, 4, 3, 6 ); - // distinguish constants with same basename - iStat += EqnTest ( "const", 1, true ); - iStat += EqnTest ( "const1", 2, true ); - iStat += EqnTest ( "const2", 3, true ); - iStat += EqnTest ( "2*const", 2, true ); - iStat += EqnTest ( "2*const1", 4, true ); - iStat += EqnTest ( "2*const2", 6, true ); - iStat += EqnTest ( "2*const+1", 3, true ); - iStat += EqnTest ( "2*const1+1", 5, true ); - iStat += EqnTest ( "2*const2+1", 7, true ); - iStat += EqnTest ( "const", 0, false ); - iStat += EqnTest ( "const1", 0, false ); - iStat += EqnTest ( "const2", 0, false ); + // distinguish constants with same basename + iStat += EqnTest ( "const", 1, true ); + iStat += EqnTest ( "const1", 2, true ); + iStat += EqnTest ( "const2", 3, true ); + iStat += EqnTest ( "2*const", 2, true ); + iStat += EqnTest ( "2*const1", 4, true ); + iStat += EqnTest ( "2*const2", 6, true ); + iStat += EqnTest ( "2*const+1", 3, true ); + iStat += EqnTest ( "2*const1+1", 5, true ); + iStat += EqnTest ( "2*const2+1", 7, true ); + iStat += EqnTest ( "const", 0, false ); + iStat += EqnTest ( "const1", 0, false ); + iStat += EqnTest ( "const2", 0, false ); - // distinguish variables with same basename - iStat += EqnTest ( "a", 1, true ); - iStat += EqnTest ( "aa", 2, true ); - iStat += EqnTest ( "2*a", 2, true ); - iStat += EqnTest ( "2*aa", 4, true ); - iStat += EqnTest ( "2*a-1", 1, true ); - iStat += EqnTest ( "2*aa-1", 3, true ); + // distinguish variables with same basename + iStat += EqnTest ( "a", 1, true ); + iStat += EqnTest ( "aa", 2, true ); + iStat += EqnTest ( "2*a", 2, true ); + iStat += EqnTest ( "2*aa", 4, true ); + iStat += EqnTest ( "2*a-1", 1, true ); + iStat += EqnTest ( "2*aa-1", 3, true ); - // custom value recognition - iStat += EqnTest ( "0xff", 255, true ); - iStat += EqnTest ( "0x97 + 0xff", 406, true ); + // custom value recognition + iStat += EqnTest ( "0xff", 255, true ); + iStat += EqnTest ( "0x97 + 0xff", 406, true ); - // Finally test querying of used variables - try - { - int idx; - qmu::QmuParser p; - qreal vVarVal[] = { 1, 2, 3, 4, 5}; - p.DefineVar ( "a", &vVarVal[0] ); - p.DefineVar ( "b", &vVarVal[1] ); - p.DefineVar ( "c", &vVarVal[2] ); - p.DefineVar ( "d", &vVarVal[3] ); - p.DefineVar ( "e", &vVarVal[4] ); + // Finally test querying of used variables + try + { + int idx; + qmu::QmuParser p; + qreal vVarVal[] = { 1, 2, 3, 4, 5}; + p.DefineVar ( "a", &vVarVal[0] ); + p.DefineVar ( "b", &vVarVal[1] ); + p.DefineVar ( "c", &vVarVal[2] ); + p.DefineVar ( "d", &vVarVal[3] ); + p.DefineVar ( "e", &vVarVal[4] ); - // Test lookup of defined variables - // 4 used variables - p.SetExpr ( "a+b+c+d" ); - qmu::varmap_type UsedVar = p.GetUsedVar(); - int iCount = static_cast(UsedVar.size()); - if ( iCount != 4 ) - { - throw false; - } + // Test lookup of defined variables + // 4 used variables + p.SetExpr ( "a+b+c+d" ); + qmu::varmap_type UsedVar = p.GetUsedVar(); + int iCount = static_cast(UsedVar.size()); + if ( iCount != 4 ) + { + throw false; + } - // the next check will fail if the parser - // erroneousely creates new variables internally - if ( p.GetVar().size() != 5 ) - { - throw false; - } + // the next check will fail if the parser + // erroneousely creates new variables internally + if ( p.GetVar().size() != 5 ) + { + throw false; + } - qmu::varmap_type::const_iterator item = UsedVar.begin(); - for ( idx = 0; item != UsedVar.end(); ++item ) - { - if ( &vVarVal[idx++] != item->second ) - { - throw false; - } - } + qmu::varmap_type::const_iterator item = UsedVar.begin(); + for ( idx = 0; item != UsedVar.end(); ++item ) + { + if ( &vVarVal[idx++] != item->second ) + { + throw false; + } + } - // Test lookup of undefined variables - p.SetExpr ( "undef1+undef2+undef3" ); - UsedVar = p.GetUsedVar(); - iCount = static_cast(UsedVar.size()); - if ( iCount != 3 ) - { - throw false; - } + // Test lookup of undefined variables + p.SetExpr ( "undef1+undef2+undef3" ); + UsedVar = p.GetUsedVar(); + iCount = static_cast(UsedVar.size()); + if ( iCount != 3 ) + { + throw false; + } - // the next check will fail if the parser - // erroneousely creates new variables internally - if ( p.GetVar().size() != 5 ) - { - throw false; - } + // the next check will fail if the parser + // erroneousely creates new variables internally + if ( p.GetVar().size() != 5 ) + { + throw false; + } - for ( item = UsedVar.begin(); item != UsedVar.end(); ++item ) - { - if ( item->second != 0 ) - { - throw false; // all pointers to undefined variables must be null - } - } + for ( item = UsedVar.begin(); item != UsedVar.end(); ++item ) + { + if ( item->second != 0 ) + { + throw false; // all pointers to undefined variables must be null + } + } - // 1 used variables - p.SetExpr ( "a+b" ); - UsedVar = p.GetUsedVar(); - iCount = static_cast(UsedVar.size()); - if ( iCount != 2 ) - { - throw false; - } - item = UsedVar.begin(); - for ( idx = 0; item != UsedVar.end(); ++item ) - { - if ( &vVarVal[idx++] != item->second ) - { - throw false; - } - } + // 1 used variables + p.SetExpr ( "a+b" ); + UsedVar = p.GetUsedVar(); + iCount = static_cast(UsedVar.size()); + if ( iCount != 2 ) + { + throw false; + } + item = UsedVar.begin(); + for ( idx = 0; item != UsedVar.end(); ++item ) + { + if ( &vVarVal[idx++] != item->second ) + { + throw false; + } + } - } - catch ( ... ) - { - iStat += 1; - } + } + catch ( ... ) + { + iStat += 1; + } - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestMultiArg() { - int iStat = 0; - qDebug() << "testing multiarg functions..."; + int iStat = 0; + qDebug() << "testing multiarg functions..."; - // Compound expressions - iStat += EqnTest ( "1,2,3", 3, true ); - iStat += EqnTest ( "a,b,c", 3, true ); - iStat += EqnTest ( "a=10,b=20,c=a*b", 200, true ); - iStat += EqnTest ( "1,\n2,\n3", 3, true ); - iStat += EqnTest ( "a,\nb,\nc", 3, true ); - iStat += EqnTest ( "a=10,\nb=20,\nc=a*b", 200, true ); - iStat += EqnTest ( "1,\r\n2,\r\n3", 3, true ); - iStat += EqnTest ( "a,\r\nb,\r\nc", 3, true ); - iStat += EqnTest ( "a=10,\r\nb=20,\r\nc=a*b", 200, true ); + // Compound expressions + iStat += EqnTest ( "1,2,3", 3, true ); + iStat += EqnTest ( "a,b,c", 3, true ); + iStat += EqnTest ( "a=10,b=20,c=a*b", 200, true ); + iStat += EqnTest ( "1,\n2,\n3", 3, true ); + iStat += EqnTest ( "a,\nb,\nc", 3, true ); + iStat += EqnTest ( "a=10,\nb=20,\nc=a*b", 200, true ); + iStat += EqnTest ( "1,\r\n2,\r\n3", 3, true ); + iStat += EqnTest ( "a,\r\nb,\r\nc", 3, true ); + iStat += EqnTest ( "a=10,\r\nb=20,\r\nc=a*b", 200, true ); - // picking the right argument - iStat += EqnTest ( "f1of1(1)", 1, true ); - iStat += EqnTest ( "f1of2(1, 2)", 1, true ); - iStat += EqnTest ( "f2of2(1, 2)", 2, true ); - iStat += EqnTest ( "f1of3(1, 2, 3)", 1, true ); - iStat += EqnTest ( "f2of3(1, 2, 3)", 2, true ); - iStat += EqnTest ( "f3of3(1, 2, 3)", 3, true ); - iStat += EqnTest ( "f1of4(1, 2, 3, 4)", 1, true ); - iStat += EqnTest ( "f2of4(1, 2, 3, 4)", 2, true ); - iStat += EqnTest ( "f3of4(1, 2, 3, 4)", 3, true ); - iStat += EqnTest ( "f4of4(1, 2, 3, 4)", 4, true ); - iStat += EqnTest ( "f1of5(1, 2, 3, 4, 5)", 1, true ); - iStat += EqnTest ( "f2of5(1, 2, 3, 4, 5)", 2, true ); - iStat += EqnTest ( "f3of5(1, 2, 3, 4, 5)", 3, true ); - iStat += EqnTest ( "f4of5(1, 2, 3, 4, 5)", 4, true ); - iStat += EqnTest ( "f5of5(1, 2, 3, 4, 5)", 5, true ); - // Too few arguments / Too many arguments - iStat += EqnTest ( "1+ping()", 11, true ); - iStat += EqnTest ( "ping()+1", 11, true ); - iStat += EqnTest ( "2*ping()", 20, true ); - iStat += EqnTest ( "ping()*2", 20, true ); - iStat += EqnTest ( "ping(1,2)", 0, false ); - iStat += EqnTest ( "1+ping(1,2)", 0, false ); - iStat += EqnTest ( "f1of1(1,2)", 0, false ); - iStat += EqnTest ( "f1of1()", 0, false ); - iStat += EqnTest ( "f1of2(1, 2, 3)", 0, false ); - iStat += EqnTest ( "f1of2(1)", 0, false ); - iStat += EqnTest ( "f1of3(1, 2, 3, 4)", 0, false ); - iStat += EqnTest ( "f1of3(1)", 0, false ); - iStat += EqnTest ( "f1of4(1, 2, 3, 4, 5)", 0, false ); - iStat += EqnTest ( "f1of4(1)", 0, false ); - iStat += EqnTest ( "(1,2,3)", 0, false ); - iStat += EqnTest ( "1,2,3", 0, false ); - iStat += EqnTest ( "(1*a,2,3)", 0, false ); - iStat += EqnTest ( "1,2*a,3", 0, false ); + // picking the right argument + iStat += EqnTest ( "f1of1(1)", 1, true ); + iStat += EqnTest ( "f1of2(1, 2)", 1, true ); + iStat += EqnTest ( "f2of2(1, 2)", 2, true ); + iStat += EqnTest ( "f1of3(1, 2, 3)", 1, true ); + iStat += EqnTest ( "f2of3(1, 2, 3)", 2, true ); + iStat += EqnTest ( "f3of3(1, 2, 3)", 3, true ); + iStat += EqnTest ( "f1of4(1, 2, 3, 4)", 1, true ); + iStat += EqnTest ( "f2of4(1, 2, 3, 4)", 2, true ); + iStat += EqnTest ( "f3of4(1, 2, 3, 4)", 3, true ); + iStat += EqnTest ( "f4of4(1, 2, 3, 4)", 4, true ); + iStat += EqnTest ( "f1of5(1, 2, 3, 4, 5)", 1, true ); + iStat += EqnTest ( "f2of5(1, 2, 3, 4, 5)", 2, true ); + iStat += EqnTest ( "f3of5(1, 2, 3, 4, 5)", 3, true ); + iStat += EqnTest ( "f4of5(1, 2, 3, 4, 5)", 4, true ); + iStat += EqnTest ( "f5of5(1, 2, 3, 4, 5)", 5, true ); + // Too few arguments / Too many arguments + iStat += EqnTest ( "1+ping()", 11, true ); + iStat += EqnTest ( "ping()+1", 11, true ); + iStat += EqnTest ( "2*ping()", 20, true ); + iStat += EqnTest ( "ping()*2", 20, true ); + iStat += EqnTest ( "ping(1,2)", 0, false ); + iStat += EqnTest ( "1+ping(1,2)", 0, false ); + iStat += EqnTest ( "f1of1(1,2)", 0, false ); + iStat += EqnTest ( "f1of1()", 0, false ); + iStat += EqnTest ( "f1of2(1, 2, 3)", 0, false ); + iStat += EqnTest ( "f1of2(1)", 0, false ); + iStat += EqnTest ( "f1of3(1, 2, 3, 4)", 0, false ); + iStat += EqnTest ( "f1of3(1)", 0, false ); + iStat += EqnTest ( "f1of4(1, 2, 3, 4, 5)", 0, false ); + iStat += EqnTest ( "f1of4(1)", 0, false ); + iStat += EqnTest ( "(1,2,3)", 0, false ); + iStat += EqnTest ( "1,2,3", 0, false ); + iStat += EqnTest ( "(1*a,2,3)", 0, false ); + iStat += EqnTest ( "1,2*a,3", 0, false ); - // correct calculation of arguments - iStat += EqnTest ( "min(a, 1)", 1, true ); - iStat += EqnTest ( "min(3*2, 1)", 1, true ); - iStat += EqnTest ( "min(3*2, 1)", 6, false ); - iStat += EqnTest ( "firstArg(2,3,4)", 2, true ); - iStat += EqnTest ( "lastArg(2,3,4)", 4, true ); - iStat += EqnTest ( "min(3*a+1, 1)", 1, true ); - iStat += EqnTest ( "max(3*a+1, 1)", 4, true ); - iStat += EqnTest ( "max(3*a+1, 1)*2", 8, true ); - iStat += EqnTest ( "2*max(3*a+1, 1)+2", 10, true ); + // correct calculation of arguments + iStat += EqnTest ( "min(a, 1)", 1, true ); + iStat += EqnTest ( "min(3*2, 1)", 1, true ); + iStat += EqnTest ( "min(3*2, 1)", 6, false ); + iStat += EqnTest ( "firstArg(2,3,4)", 2, true ); + iStat += EqnTest ( "lastArg(2,3,4)", 4, true ); + iStat += EqnTest ( "min(3*a+1, 1)", 1, true ); + iStat += EqnTest ( "max(3*a+1, 1)", 4, true ); + iStat += EqnTest ( "max(3*a+1, 1)*2", 8, true ); + iStat += EqnTest ( "2*max(3*a+1, 1)+2", 10, true ); - // functions with Variable argument count - iStat += EqnTest ( "sum(a)", 1, true ); - iStat += EqnTest ( "sum(1,2,3)", 6, true ); - iStat += EqnTest ( "sum(a,b,c)", 6, true ); - iStat += EqnTest ( "sum(1,-max(1,2),3)*2", 4, true ); - iStat += EqnTest ( "2*sum(1,2,3)", 12, true ); - iStat += EqnTest ( "2*sum(1,2,3)+2", 14, true ); - iStat += EqnTest ( "2*sum(-1,2,3)+2", 10, true ); - iStat += EqnTest ( "2*sum(-1,2,-(-a))+2", 6, true ); - iStat += EqnTest ( "2*sum(-1,10,-a)+2", 18, true ); - iStat += EqnTest ( "2*sum(1,2,3)*2", 24, true ); - iStat += EqnTest ( "sum(1,-max(1,2),3)*2", 4, true ); - iStat += EqnTest ( "sum(1*3, 4, a+2)", 10, true ); - iStat += EqnTest ( "sum(1*3, 2*sum(1,2,2), a+2)", 16, true ); - iStat += EqnTest ( "sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)", 24, true ); + // functions with Variable argument count + iStat += EqnTest ( "sum(a)", 1, true ); + iStat += EqnTest ( "sum(1,2,3)", 6, true ); + iStat += EqnTest ( "sum(a,b,c)", 6, true ); + iStat += EqnTest ( "sum(1,-max(1,2),3)*2", 4, true ); + iStat += EqnTest ( "2*sum(1,2,3)", 12, true ); + iStat += EqnTest ( "2*sum(1,2,3)+2", 14, true ); + iStat += EqnTest ( "2*sum(-1,2,3)+2", 10, true ); + iStat += EqnTest ( "2*sum(-1,2,-(-a))+2", 6, true ); + iStat += EqnTest ( "2*sum(-1,10,-a)+2", 18, true ); + iStat += EqnTest ( "2*sum(1,2,3)*2", 24, true ); + iStat += EqnTest ( "sum(1,-max(1,2),3)*2", 4, true ); + iStat += EqnTest ( "sum(1*3, 4, a+2)", 10, true ); + iStat += EqnTest ( "sum(1*3, 2*sum(1,2,2), a+2)", 16, true ); + iStat += EqnTest ( "sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)", 24, true ); - // some failures - iStat += EqnTest ( "sum()", 0, false ); - iStat += EqnTest ( "sum(,)", 0, false ); - iStat += EqnTest ( "sum(1,2,)", 0, false ); - iStat += EqnTest ( "sum(,1,2)", 0, false ); + // some failures + iStat += EqnTest ( "sum()", 0, false ); + iStat += EqnTest ( "sum(,)", 0, false ); + iStat += EqnTest ( "sum(1,2,)", 0, false ); + iStat += EqnTest ( "sum(,1,2)", 0, false ); - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestInfixOprt() { - int iStat ( 0 ); - qDebug() << "testing infix operators..."; + int iStat ( 0 ); + qDebug() << "testing infix operators..."; - iStat += EqnTest ( "-1", -1, true ); - iStat += EqnTest ( "-(-1)", 1, true ); - iStat += EqnTest ( "-(-1)*2", 2, true ); - iStat += EqnTest ( "-(-2)*sqrt(4)", 4, true ); - iStat += EqnTest ( "-_pi", -M_PI, true ); - iStat += EqnTest ( "-a", -1, true ); - iStat += EqnTest ( "-(a)", -1, true ); - iStat += EqnTest ( "-(-a)", 1, true ); - iStat += EqnTest ( "-(-a)*2", 2, true ); - iStat += EqnTest ( "-(8)", -8, true ); - iStat += EqnTest ( "-8", -8, true ); - iStat += EqnTest ( "-(2+1)", -3, true ); - iStat += EqnTest ( "-(f1of1(1+2*3)+1*2)", -9, true ); - iStat += EqnTest ( "-(-f1of1(1+2*3)+1*2)", 5, true ); - iStat += EqnTest ( "-sin(8)", -0.989358, true ); - iStat += EqnTest ( "3-(-a)", 4, true ); - iStat += EqnTest ( "3--a", 4, true ); - iStat += EqnTest ( "-1*3", -3, true ); + iStat += EqnTest ( "-1", -1, true ); + iStat += EqnTest ( "-(-1)", 1, true ); + iStat += EqnTest ( "-(-1)*2", 2, true ); + iStat += EqnTest ( "-(-2)*sqrt(4)", 4, true ); + iStat += EqnTest ( "-_pi", -M_PI, true ); + iStat += EqnTest ( "-a", -1, true ); + iStat += EqnTest ( "-(a)", -1, true ); + iStat += EqnTest ( "-(-a)", 1, true ); + iStat += EqnTest ( "-(-a)*2", 2, true ); + iStat += EqnTest ( "-(8)", -8, true ); + iStat += EqnTest ( "-8", -8, true ); + iStat += EqnTest ( "-(2+1)", -3, true ); + iStat += EqnTest ( "-(f1of1(1+2*3)+1*2)", -9, true ); + iStat += EqnTest ( "-(-f1of1(1+2*3)+1*2)", 5, true ); + iStat += EqnTest ( "-sin(8)", -0.989358, true ); + iStat += EqnTest ( "3-(-a)", 4, true ); + iStat += EqnTest ( "3--a", 4, true ); + iStat += EqnTest ( "-1*3", -3, true ); - // Postfix / infix priorities - iStat += EqnTest ( "~2#", 8, true ); - iStat += EqnTest ( "~f1of1(2)#", 8, true ); - iStat += EqnTest ( "~(b)#", 8, true ); - iStat += EqnTest ( "(~b)#", 12, true ); - iStat += EqnTest ( "~(2#)", 8, true ); - iStat += EqnTest ( "~(f1of1(2)#)", 8, true ); - // - iStat += EqnTest ( "-2^2", -4, true ); - iStat += EqnTest ( "-(a+b)^2", -9, true ); - iStat += EqnTest ( "(-3)^2", 9, true ); - iStat += EqnTest ( "-(-2^2)", 4, true ); - iStat += EqnTest ( "3+-3^2", -6, true ); - // The following assumes use of sqr as postfix operator ("") together - // with a sign operator of low priority: - iStat += EqnTest ( "-2'", -4, true ); - iStat += EqnTest ( "-(1+1)'", -4, true ); - iStat += EqnTest ( "2+-(1+1)'", -2, true ); - iStat += EqnTest ( "2+-2'", -2, true ); - // This is the classic behaviour of the infix sign operator (here: "$") which is - // now deprecated: - iStat += EqnTest ( "$2^2", 4, true ); - iStat += EqnTest ( "$(a+b)^2", 9, true ); - iStat += EqnTest ( "($3)^2", 9, true ); - iStat += EqnTest ( "$($2^2)", -4, true ); - iStat += EqnTest ( "3+$3^2", 12, true ); + // Postfix / infix priorities + iStat += EqnTest ( "~2#", 8, true ); + iStat += EqnTest ( "~f1of1(2)#", 8, true ); + iStat += EqnTest ( "~(b)#", 8, true ); + iStat += EqnTest ( "(~b)#", 12, true ); + iStat += EqnTest ( "~(2#)", 8, true ); + iStat += EqnTest ( "~(f1of1(2)#)", 8, true ); + // + iStat += EqnTest ( "-2^2", -4, true ); + iStat += EqnTest ( "-(a+b)^2", -9, true ); + iStat += EqnTest ( "(-3)^2", 9, true ); + iStat += EqnTest ( "-(-2^2)", 4, true ); + iStat += EqnTest ( "3+-3^2", -6, true ); + // The following assumes use of sqr as postfix operator ("") together + // with a sign operator of low priority: + iStat += EqnTest ( "-2'", -4, true ); + iStat += EqnTest ( "-(1+1)'", -4, true ); + iStat += EqnTest ( "2+-(1+1)'", -2, true ); + iStat += EqnTest ( "2+-2'", -2, true ); + // This is the classic behaviour of the infix sign operator (here: "$") which is + // now deprecated: + iStat += EqnTest ( "$2^2", 4, true ); + iStat += EqnTest ( "$(a+b)^2", 9, true ); + iStat += EqnTest ( "($3)^2", 9, true ); + iStat += EqnTest ( "$($2^2)", -4, true ); + iStat += EqnTest ( "3+$3^2", 12, true ); - // infix operators sharing the first few characters - iStat += EqnTest ( "~ 123", 123 + 2, true ); - iStat += EqnTest ( "~~ 123", 123 + 2, true ); + // infix operators sharing the first few characters + iStat += EqnTest ( "~ 123", 123 + 2, true ); + iStat += EqnTest ( "~~ 123", 123 + 2, true ); - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestPostFix() { - int iStat = 0; - qDebug() << "testing postfix operators..."; + int iStat = 0; + qDebug() << "testing postfix operators..."; - // application - iStat += EqnTest ( "3{m}+5", 5.003, true ); - iStat += EqnTest ( "1000{m}", 1, true ); - iStat += EqnTest ( "1000 {m}", 1, true ); - iStat += EqnTest ( "(a){m}", 1e-3, true ); - iStat += EqnTest ( "a{m}", 1e-3, true ); - iStat += EqnTest ( "a {m}", 1e-3, true ); - iStat += EqnTest ( "-(a){m}", -1e-3, true ); - iStat += EqnTest ( "-2{m}", -2e-3, true ); - iStat += EqnTest ( "-2 {m}", -2e-3, true ); - iStat += EqnTest ( "f1of1(1000){m}", 1, true ); - iStat += EqnTest ( "-f1of1(1000){m}", -1, true ); - iStat += EqnTest ( "-f1of1(-1000){m}", 1, true ); - iStat += EqnTest ( "f4of4(0,0,0,1000){m}", 1, true ); - iStat += EqnTest ( "2+(a*1000){m}", 3, true ); + // application + iStat += EqnTest ( "3{m}+5", 5.003, true ); + iStat += EqnTest ( "1000{m}", 1, true ); + iStat += EqnTest ( "1000 {m}", 1, true ); + iStat += EqnTest ( "(a){m}", 1e-3, true ); + iStat += EqnTest ( "a{m}", 1e-3, true ); + iStat += EqnTest ( "a {m}", 1e-3, true ); + iStat += EqnTest ( "-(a){m}", -1e-3, true ); + iStat += EqnTest ( "-2{m}", -2e-3, true ); + iStat += EqnTest ( "-2 {m}", -2e-3, true ); + iStat += EqnTest ( "f1of1(1000){m}", 1, true ); + iStat += EqnTest ( "-f1of1(1000){m}", -1, true ); + iStat += EqnTest ( "-f1of1(-1000){m}", 1, true ); + iStat += EqnTest ( "f4of4(0,0,0,1000){m}", 1, true ); + iStat += EqnTest ( "2+(a*1000){m}", 3, true ); - // can postfix operators "m" und "meg" be told apart properly? - iStat += EqnTest ( "2*3000meg+2", 2 * 3e9 + 2, true ); + // can postfix operators "m" und "meg" be told apart properly? + iStat += EqnTest ( "2*3000meg+2", 2 * 3e9 + 2, true ); - // some incorrect results - iStat += EqnTest ( "1000{m}", 0.1, false ); - iStat += EqnTest ( "(a){m}", 2, false ); - // failure due to syntax checking - iStat += ThrowTest ( "0x", ecUNASSIGNABLE_TOKEN ); // incomplete hex definition - iStat += ThrowTest ( "3+", ecUNEXPECTED_EOF ); - iStat += ThrowTest ( "4 + {m}", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "{m}4", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "sin({m})", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "{m} {m}", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "{m}(8)", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "4,{m}", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "-{m}", ecUNASSIGNABLE_TOKEN ); - iStat += ThrowTest ( "2(-{m})", ecUNEXPECTED_PARENS ); - iStat += ThrowTest ( "2({m})", ecUNEXPECTED_PARENS ); + // some incorrect results + iStat += EqnTest ( "1000{m}", 0.1, false ); + iStat += EqnTest ( "(a){m}", 2, false ); + // failure due to syntax checking + iStat += ThrowTest ( "0x", ecUNASSIGNABLE_TOKEN ); // incomplete hex definition + iStat += ThrowTest ( "3+", ecUNEXPECTED_EOF ); + iStat += ThrowTest ( "4 + {m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "{m}4", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "sin({m})", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "{m} {m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "{m}(8)", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "4,{m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "-{m}", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "2(-{m})", ecUNEXPECTED_PARENS ); + iStat += ThrowTest ( "2({m})", ecUNEXPECTED_PARENS ); - iStat += ThrowTest ( "multi*1.0", ecUNASSIGNABLE_TOKEN ); + iStat += ThrowTest ( "multi*1.0", ecUNASSIGNABLE_TOKEN ); - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestExpression() { - int iStat = 0; - qDebug() << "testing expression samples..."; + int iStat = 0; + qDebug() << "testing expression samples..."; - qreal b = 2; + qreal b = 2; - // Optimization - iStat += EqnTest ( "2*b*5", 20, true ); - iStat += EqnTest ( "2*b*5 + 4*b", 28, true ); - iStat += EqnTest ( "2*a/3", 2.0 / 3.0, true ); + // Optimization + iStat += EqnTest ( "2*b*5", 20, true ); + iStat += EqnTest ( "2*b*5 + 4*b", 28, true ); + iStat += EqnTest ( "2*a/3", 2.0 / 3.0, true ); - // Addition auf cmVARMUL - iStat += EqnTest ( "3+b", b + 3, true ); - iStat += EqnTest ( "b+3", b + 3, true ); - iStat += EqnTest ( "b*3+2", b * 3 + 2, true ); - iStat += EqnTest ( "3*b+2", b * 3 + 2, true ); - iStat += EqnTest ( "2+b*3", b * 3 + 2, true ); - iStat += EqnTest ( "2+3*b", b * 3 + 2, true ); - iStat += EqnTest ( "b+3*b", b + 3 * b, true ); - iStat += EqnTest ( "3*b+b", b + 3 * b, true ); + // Addition auf cmVARMUL + iStat += EqnTest ( "3+b", b + 3, true ); + iStat += EqnTest ( "b+3", b + 3, true ); + iStat += EqnTest ( "b*3+2", b * 3 + 2, true ); + iStat += EqnTest ( "3*b+2", b * 3 + 2, true ); + iStat += EqnTest ( "2+b*3", b * 3 + 2, true ); + iStat += EqnTest ( "2+3*b", b * 3 + 2, true ); + iStat += EqnTest ( "b+3*b", b + 3 * b, true ); + iStat += EqnTest ( "3*b+b", b + 3 * b, true ); - iStat += EqnTest ( "2+b*3+b", 2 + b * 3 + b, true ); - iStat += EqnTest ( "b+2+b*3", b + 2 + b * 3, true ); + iStat += EqnTest ( "2+b*3+b", 2 + b * 3 + b, true ); + iStat += EqnTest ( "b+2+b*3", b + 2 + b * 3, true ); - iStat += EqnTest ( "(2*b+1)*4", ( 2 * b + 1 ) * 4, true ); - iStat += EqnTest ( "4*(2*b+1)", ( 2 * b + 1 ) * 4, true ); + iStat += EqnTest ( "(2*b+1)*4", ( 2 * b + 1 ) * 4, true ); + iStat += EqnTest ( "4*(2*b+1)", ( 2 * b + 1 ) * 4, true ); - // operator precedencs - iStat += EqnTest ( "1+2-3*4/5^6", 2.99923, true ); - iStat += EqnTest ( "1^2/3*4-5+6", 2.33333333, true ); - iStat += EqnTest ( "1+2*3", 7, true ); - iStat += EqnTest ( "1+2*3", 7, true ); - iStat += EqnTest ( "(1+2)*3", 9, true ); - iStat += EqnTest ( "(1+2)*(-3)", -9, true ); - iStat += EqnTest ( "2/4", 0.5, true ); + // operator precedencs + iStat += EqnTest ( "1+2-3*4/5^6", 2.99923, true ); + iStat += EqnTest ( "1^2/3*4-5+6", 2.33333333, true ); + iStat += EqnTest ( "1+2*3", 7, true ); + iStat += EqnTest ( "1+2*3", 7, true ); + iStat += EqnTest ( "(1+2)*3", 9, true ); + iStat += EqnTest ( "(1+2)*(-3)", -9, true ); + iStat += EqnTest ( "2/4", 0.5, true ); - iStat += EqnTest ( "exp(ln(7))", 7, true ); - iStat += EqnTest ( "e^ln(7)", 7, true ); - iStat += EqnTest ( "e^(ln(7))", 7, true ); - iStat += EqnTest ( "(e^(ln(7)))", 7, true ); - iStat += EqnTest ( "1-(e^(ln(7)))", -6, true ); - iStat += EqnTest ( "2*(e^(ln(7)))", 14, true ); - iStat += EqnTest ( "10^log(5)", 5, true ); - iStat += EqnTest ( "10^log10(5)", 5, true ); - iStat += EqnTest ( "2^log2(4)", 4, true ); - iStat += EqnTest ( "-(sin(0)+1)", -1, true ); - iStat += EqnTest ( "-(2^1.1)", -2.14354692, true ); + iStat += EqnTest ( "exp(ln(7))", 7, true ); + iStat += EqnTest ( "e^ln(7)", 7, true ); + iStat += EqnTest ( "e^(ln(7))", 7, true ); + iStat += EqnTest ( "(e^(ln(7)))", 7, true ); + iStat += EqnTest ( "1-(e^(ln(7)))", -6, true ); + iStat += EqnTest ( "2*(e^(ln(7)))", 14, true ); + iStat += EqnTest ( "10^log(5)", 5, true ); + iStat += EqnTest ( "10^log10(5)", 5, true ); + iStat += EqnTest ( "2^log2(4)", 4, true ); + iStat += EqnTest ( "-(sin(0)+1)", -1, true ); + iStat += EqnTest ( "-(2^1.1)", -2.14354692, true ); - iStat += EqnTest ( "(cos(2.41)/b)", -0.372056, true ); - iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160, true ); - iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120, true ); - iStat += EqnTest ( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))", - 0.00377999, true ); + iStat += EqnTest ( "(cos(2.41)/b)", -0.372056, true ); + iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160, true ); + iStat += EqnTest ( "(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120, true ); + iStat += EqnTest ( "(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))", + 0.00377999, true ); - // long formula (Reference: Matlab) - iStat += EqnTest ( - "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))" - "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/" - "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-" - "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6" - "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e" - "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549, true ); + // long formula (Reference: Matlab) + iStat += EqnTest ( + "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))" + "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/" + "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-" + "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6" + "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e" + "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549, true ); - // long formula (Reference: Matlab) - iStat += EqnTest ( - "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e" - ")+a)))*2.77)", -2.16995656, true ); + // long formula (Reference: Matlab) + iStat += EqnTest ( + "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e" + ")+a)))*2.77)", -2.16995656, true ); - // long formula (Reference: Matlab) - iStat += EqnTest ( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true ); + // long formula (Reference: Matlab) + iStat += EqnTest ( "1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926, true ); - if ( iStat == 0 ) - { - qDebug() << "passed"; - } - else - { - qDebug() << "\n failed with " << iStat << " errors"; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } - - -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::TestIfThenElse() { - int iStat = 0; - qDebug() << "testing if-then-else operator..."; + int iStat = 0; + qDebug() << "testing if-then-else operator..."; - // Test error detection - iStat += ThrowTest ( ":3", ecUNEXPECTED_CONDITIONAL ); - iStat += ThrowTest ( "? 1 : 2", ecUNEXPECTED_CONDITIONAL ); - iStat += ThrowTest ( "(ab) ? 10 : 11", 11, true ); - iStat += EqnTest ( "(ab) ? c : d", -2, true ); + iStat += EqnTest ( "1 ? 128 : 255", 128, true ); + iStat += EqnTest ( "1<2 ? 128 : 255", 128, true ); + iStat += EqnTest ( "ab) ? 10 : 11", 11, true ); + iStat += EqnTest ( "(ab) ? c : d", -2, true ); - iStat += EqnTest ( "(a>b) ? 1 : 0", 0, true ); - iStat += EqnTest ( "((a>b) ? 1 : 0) ? 1 : 2", 2, true ); - iStat += EqnTest ( "((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)", 2, true ); - iStat += EqnTest ( "((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)", 1, true ); + iStat += EqnTest ( "(a>b) ? 1 : 0", 0, true ); + iStat += EqnTest ( "((a>b) ? 1 : 0) ? 1 : 2", 2, true ); + iStat += EqnTest ( "((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)", 2, true ); + iStat += EqnTest ( "((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)", 1, true ); - iStat += EqnTest ( "sum((a>b) ? 1 : 2)", 2, true ); - iStat += EqnTest ( "sum((1) ? 1 : 2)", 1, true ); - iStat += EqnTest ( "sum((a>b) ? 1 : 2, 100)", 102, true ); - iStat += EqnTest ( "sum((1) ? 1 : 2, 100)", 101, true ); - iStat += EqnTest ( "sum(3, (a>b) ? 3 : 10)", 13, true ); - iStat += EqnTest ( "sum(3, (ab) ? 3 : 10)", 130, true ); - iStat += EqnTest ( "10*sum(3, (ab) ? 3 : 10)*10", 130, true ); - iStat += EqnTest ( "sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? 1 : 2)", 2, true ); + iStat += EqnTest ( "sum((1) ? 1 : 2)", 1, true ); + iStat += EqnTest ( "sum((a>b) ? 1 : 2, 100)", 102, true ); + iStat += EqnTest ( "sum((1) ? 1 : 2, 100)", 101, true ); + iStat += EqnTest ( "sum(3, (a>b) ? 3 : 10)", 13, true ); + iStat += EqnTest ( "sum(3, (ab) ? 3 : 10)", 130, true ); + iStat += EqnTest ( "10*sum(3, (ab) ? 3 : 10)*10", 130, true ); + iStat += EqnTest ( "sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab) ? sum(3, (ab)&&(a2)&&(1<2) ? 128 : 255", 255, true ); - iStat += EqnTest ( "((1<2)&&(1<2)) ? 128 : 255", 128, true ); - iStat += EqnTest ( "((1>2)&&(1<2)) ? 128 : 255", 255, true ); - iStat += EqnTest ( "((ab)&&(ab)&&(a2)&&(1<2) ? 128 : 255", 255, true ); + iStat += EqnTest ( "((1<2)&&(1<2)) ? 128 : 255", 128, true ); + iStat += EqnTest ( "((1>2)&&(1<2)) ? 128 : 255", 255, true ); + iStat += EqnTest ( "((ab)&&(a0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 255, true ); - iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)", 255, true ); - iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 128, true ); - iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)", 128, true ); - iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 32, true ); - iStat += EqnTest ( "1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 64, true ); - iStat += EqnTest ( "1>0 ? 50 : 1>0 ? 128 : 255", 50, true ); - iStat += EqnTest ( "1>0 ? 50 : (1>0 ? 128 : 255)", 50, true ); - iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 : 50", 128, true ); - iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16", 32, true ); - iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)", 32, true ); - iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16", 255, true ); - iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)", 255, true ); - iStat += EqnTest ( "1 ? 0 ? 128 : 255 : 1 ? 32 : 64", 255, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 255, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)", 255, true ); + iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 128, true ); + iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)", 128, true ); + iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 32, true ); + iStat += EqnTest ( "1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 64, true ); + iStat += EqnTest ( "1>0 ? 50 : 1>0 ? 128 : 255", 50, true ); + iStat += EqnTest ( "1>0 ? 50 : (1>0 ? 128 : 255)", 50, true ); + iStat += EqnTest ( "1>0 ? 1>0 ? 128 : 255 : 50", 128, true ); + iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16", 32, true ); + iStat += EqnTest ( "1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)", 32, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16", 255, true ); + iStat += EqnTest ( "1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)", 255, true ); + iStat += EqnTest ( "1 ? 0 ? 128 : 255 : 1 ? 32 : 64", 255, true ); - // assignment operators - iStat += EqnTest ( "a= 0 ? 128 : 255, a", 255, true ); - iStat += EqnTest ( "a=((a>b)&&(ab)&&(a - // this is now legal, for reference see: - // https://sourceforge.net/forum/message.php?msg_id=7411373 - // iStat += ThrowTest( "sin=9"), ecUNEXPECTED_OPERATOR); - //
    + // + // this is now legal, for reference see: + // https://sourceforge.net/forum/message.php?msg_id=7411373 + // iStat += ThrowTest( "sin=9"), ecUNEXPECTED_OPERATOR); + // - iStat += ThrowTest ( "(8)=5", ecUNEXPECTED_OPERATOR ); - iStat += ThrowTest ( "(a)=5", ecUNEXPECTED_OPERATOR ); - iStat += ThrowTest ( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT ); + iStat += ThrowTest ( "(8)=5", ecUNEXPECTED_OPERATOR ); + iStat += ThrowTest ( "(a)=5", ecUNEXPECTED_OPERATOR ); + iStat += ThrowTest ( "a=\"tttt\"", ecOPRT_TYPE_CONFLICT ); - if ( iStat == 0 ) - { - qDebug() << "passed" ; - } - else - { - qDebug() << "\n failed with " << iStat << " errors" ; - } + if ( iStat == 0 ) + { + qDebug() << "passed"; + } + else + { + qDebug() << "\n failed with " << iStat << " errors"; + } - return iStat; + return iStat; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParserTester::AddTest ( testfun_type a_pFun ) { - m_vTestFun.push_back ( a_pFun ); + m_vTestFun.push_back ( a_pFun ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParserTester::Run() { - int iStat = 0; - try - { - for ( int i = 0; i < m_vTestFun.size(); ++i ) - { - iStat += ( this->*m_vTestFun[i] ) (); - } - } - catch ( QmuParser::exception_type &e ) - { - qDebug() << "\n" << e.GetMsg() ; - qDebug() << e.GetToken() ; - Abort(); - } - catch ( std::exception &e ) - { - qDebug() << e.what() ; - Abort(); - } - catch ( ... ) - { - qDebug() << "Internal error"; - Abort(); - } + int iStat = 0; + try + { + for ( int i = 0; i < m_vTestFun.size(); ++i ) + { + iStat += ( this->*m_vTestFun[i] ) (); + } + } + catch ( QmuParser::exception_type &e ) + { + qDebug() << "\n" << e.GetMsg(); + qDebug() << e.GetToken(); + Abort(); + } + catch ( std::exception &e ) + { + qDebug() << e.what(); + Abort(); + } + catch ( ... ) + { + qDebug() << "Internal error"; + Abort(); + } - if ( iStat == 0 ) - { - qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)" ; - } - else - { - qDebug() << "Test failed with " << iStat - << " errors (" << QmuParserTester::c_iCount - << " expressions)" ; - } - QmuParserTester::c_iCount = 0; + if ( iStat == 0 ) + { + qDebug() << "Test passed (" << QmuParserTester::c_iCount << " expressions)"; + } + else + { + qDebug() << "Test failed with " << iStat + << " errors (" << QmuParserTester::c_iCount + << " expressions)"; + } + QmuParserTester::c_iCount = 0; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail ) { - QmuParserTester::c_iCount++; + QmuParserTester::c_iCount++; - try - { - qreal fVal[] = {1, 1, 1}; - QmuParser p; + try + { + qreal fVal[] = {1, 1, 1}; + QmuParser p; - p.DefineVar ( "a", &fVal[0] ); - p.DefineVar ( "b", &fVal[1] ); - p.DefineVar ( "c", &fVal[2] ); - p.DefinePostfixOprt ( "{m}", Milli ); - p.DefinePostfixOprt ( "m", Milli ); - p.DefineFun ( "ping", Ping ); - p.DefineFun ( "valueof", ValueOf ); - p.DefineFun ( "strfun1", StrFun1 ); - p.DefineFun ( "strfun2", StrFun2 ); - p.DefineFun ( "strfun3", StrFun3 ); - p.SetExpr ( a_str ); - p.Eval(); - } - catch ( QmuParserError &e ) - { - // output the formula in case of an failed test - if ( a_bFail == false || ( a_bFail == true && a_iErrc != e.GetCode() ) ) - { - qDebug() << "\n " - << "Expression: " << a_str - << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" - << " Expected:" << a_iErrc; - } + p.DefineVar ( "a", &fVal[0] ); + p.DefineVar ( "b", &fVal[1] ); + p.DefineVar ( "c", &fVal[2] ); + p.DefinePostfixOprt ( "{m}", Milli ); + p.DefinePostfixOprt ( "m", Milli ); + p.DefineFun ( "ping", Ping ); + p.DefineFun ( "valueof", ValueOf ); + p.DefineFun ( "strfun1", StrFun1 ); + p.DefineFun ( "strfun2", StrFun2 ); + p.DefineFun ( "strfun3", StrFun3 ); + p.SetExpr ( a_str ); + p.Eval(); + } + catch ( QmuParserError &e ) + { + // output the formula in case of an failed test + if ( a_bFail == false || ( a_bFail == true && a_iErrc != e.GetCode() ) ) + { + qDebug() << "\n " + << "Expression: " << a_str + << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" + << " Expected:" << a_iErrc; + } - return ( a_iErrc == e.GetCode() ) ? 0 : 1; - } + return ( a_iErrc == e.GetCode() ) ? 0 : 1; + } - // if a_bFail==false no exception is expected - bool bRet ( ( a_bFail == false ) ? 0 : 1 ); - if ( bRet == 1 ) - { - qDebug() << "\n " - << "Expression: " << a_str - << " did evaluate; Expected error:" << a_iErrc; - } + // if a_bFail==false no exception is expected + bool bRet ( ( a_bFail == false ) ? 0 : 1 ); + if ( bRet == 1 ) + { + qDebug() << "\n " + << "Expression: " << a_str + << " did evaluate; Expected error:" << a_iErrc; + } - return bRet; + return bRet; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Evaluate a tet expression. * * @return 1 in case of a failure, 0 otherwise. */ int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1, double a_fRes1, double a_fVar2, - double a_fRes2 ) + double a_fRes2 ) { - QmuParserTester::c_iCount++; - qreal fVal[2] = { -999, -999 }; // should be equalinitially + QmuParserTester::c_iCount++; + qreal fVal[2] = { -999, -999 }; // should be equalinitially - try - { - QmuParser p; + try + { + QmuParser p; - // variable - qreal var = 0; - p.DefineVar ( "a", &var ); - p.SetExpr ( a_str ); + // variable + qreal var = 0; + p.DefineVar ( "a", &var ); + p.SetExpr ( a_str ); - var = a_fVar1; - fVal[0] = p.Eval(); + var = a_fVar1; + fVal[0] = p.Eval(); - var = a_fVar2; - fVal[1] = p.Eval(); + var = a_fVar2; + fVal[1] = p.Eval(); - if ( fabs ( a_fRes1 - fVal[0] ) > 0.0000000001 ) - { - throw std::runtime_error ( "incorrect result (first pass)" ); - } + if ( fabs ( a_fRes1 - fVal[0] ) > 0.0000000001 ) + { + throw std::runtime_error ( "incorrect result (first pass)" ); + } - if ( fabs ( a_fRes2 - fVal[1] ) > 0.0000000001 ) - { - throw std::runtime_error ( "incorrect result (second pass)" ); - } - } - catch ( QmuParser::exception_type &e ) - { - qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; - return 1; - } - catch ( std::exception &e ) - { - qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; - return 1; // always return a failure since this exception is not expected - } - catch ( ... ) - { - qDebug() << "\n fail: " << a_str << " (unexpected exception)"; - return 1; // exceptions other than ParserException are not allowed - } + if ( fabs ( a_fRes2 - fVal[1] ) > 0.0000000001 ) + { + throw std::runtime_error ( "incorrect result (second pass)" ); + } + } + catch ( QmuParser::exception_type &e ) + { + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; + return 1; + } + catch ( std::exception &e ) + { + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; + return 1; // always return a failure since this exception is not expected + } + catch ( ... ) + { + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; + return 1; // exceptions other than ParserException are not allowed + } - return 0; + return 0; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Evaluate a tet expression. * @@ -1221,196 +1219,196 @@ int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1 */ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ) { - QmuParserTester::c_iCount++; - int iRet ( 0 ); - qreal fVal[5] = { -999, -998, -997, -996, -995}; // initially should be different + QmuParserTester::c_iCount++; + int iRet ( 0 ); + qreal fVal[5] = { -999, -998, -997, -996, -995}; // initially should be different - try - { - std::unique_ptr p1; - QmuParser p2, p3; // three parser objects - // they will be used for testing copy and assihnment operators - // p1 is a pointer since i'm going to delete it in order to test if - // parsers after copy construction still refer to members of it. - // !! If this is the case this function will crash !! + try + { + std::unique_ptr p1; + QmuParser p2, p3; // three parser objects + // they will be used for testing copy and assihnment operators + // p1 is a pointer since i'm going to delete it in order to test if + // parsers after copy construction still refer to members of it. + // !! If this is the case this function will crash !! - p1.reset ( new qmu::QmuParser() ); - // Add constants - p1->DefineConst ( "pi", ( qreal ) M_PI ); - p1->DefineConst ( "e", ( qreal ) M_E ); - p1->DefineConst ( "const", 1 ); - p1->DefineConst ( "const1", 2 ); - p1->DefineConst ( "const2", 3 ); - // variables - qreal vVarVal[] = { 1, 2, 3, -2}; - p1->DefineVar ( "a", &vVarVal[0] ); - p1->DefineVar ( "aa", &vVarVal[1] ); - p1->DefineVar ( "b", &vVarVal[1] ); - p1->DefineVar ( "c", &vVarVal[2] ); - p1->DefineVar ( "d", &vVarVal[3] ); + p1.reset ( new qmu::QmuParser() ); + // Add constants + p1->DefineConst ( "pi", ( qreal ) M_PI ); + p1->DefineConst ( "e", ( qreal ) M_E ); + p1->DefineConst ( "const", 1 ); + p1->DefineConst ( "const1", 2 ); + p1->DefineConst ( "const2", 3 ); + // variables + qreal vVarVal[] = { 1, 2, 3, -2}; + p1->DefineVar ( "a", &vVarVal[0] ); + p1->DefineVar ( "aa", &vVarVal[1] ); + p1->DefineVar ( "b", &vVarVal[1] ); + p1->DefineVar ( "c", &vVarVal[2] ); + p1->DefineVar ( "d", &vVarVal[3] ); - // custom value ident functions - p1->AddValIdent ( &QmuParserTester::IsHexVal ); + // custom value ident functions + p1->AddValIdent ( &QmuParserTester::IsHexVal ); - // functions - p1->DefineFun ( "ping", Ping ); - p1->DefineFun ( "f1of1", f1of1 ); // one parameter - p1->DefineFun ( "f1of2", f1of2 ); // two parameter - p1->DefineFun ( "f2of2", f2of2 ); - p1->DefineFun ( "f1of3", f1of3 ); // three parameter - p1->DefineFun ( "f2of3", f2of3 ); - p1->DefineFun ( "f3of3", f3of3 ); - p1->DefineFun ( "f1of4", f1of4 ); // four parameter - p1->DefineFun ( "f2of4", f2of4 ); - p1->DefineFun ( "f3of4", f3of4 ); - p1->DefineFun ( "f4of4", f4of4 ); - p1->DefineFun ( "f1of5", f1of5 ); // five parameter - p1->DefineFun ( "f2of5", f2of5 ); - p1->DefineFun ( "f3of5", f3of5 ); - p1->DefineFun ( "f4of5", f4of5 ); - p1->DefineFun ( "f5of5", f5of5 ); + // functions + p1->DefineFun ( "ping", Ping ); + p1->DefineFun ( "f1of1", f1of1 ); // one parameter + p1->DefineFun ( "f1of2", f1of2 ); // two parameter + p1->DefineFun ( "f2of2", f2of2 ); + p1->DefineFun ( "f1of3", f1of3 ); // three parameter + p1->DefineFun ( "f2of3", f2of3 ); + p1->DefineFun ( "f3of3", f3of3 ); + p1->DefineFun ( "f1of4", f1of4 ); // four parameter + p1->DefineFun ( "f2of4", f2of4 ); + p1->DefineFun ( "f3of4", f3of4 ); + p1->DefineFun ( "f4of4", f4of4 ); + p1->DefineFun ( "f1of5", f1of5 ); // five parameter + p1->DefineFun ( "f2of5", f2of5 ); + p1->DefineFun ( "f3of5", f3of5 ); + p1->DefineFun ( "f4of5", f4of5 ); + p1->DefineFun ( "f5of5", f5of5 ); - // binary operators - p1->DefineOprt ( "add", add, 0 ); - p1->DefineOprt ( "++", add, 0 ); - p1->DefineOprt ( "&", land, prLAND ); + // binary operators + p1->DefineOprt ( "add", add, 0 ); + p1->DefineOprt ( "++", add, 0 ); + p1->DefineOprt ( "&", land, prLAND ); - // sample functions - p1->DefineFun ( "min", Min ); - p1->DefineFun ( "max", Max ); - p1->DefineFun ( "sum", Sum ); - p1->DefineFun ( "valueof", ValueOf ); - p1->DefineFun ( "atof", StrToFloat ); - p1->DefineFun ( "strfun1", StrFun1 ); - p1->DefineFun ( "strfun2", StrFun2 ); - p1->DefineFun ( "strfun3", StrFun3 ); - p1->DefineFun ( "lastArg", LastArg ); - p1->DefineFun ( "firstArg", FirstArg ); - p1->DefineFun ( "order", FirstArg ); + // sample functions + p1->DefineFun ( "min", Min ); + p1->DefineFun ( "max", Max ); + p1->DefineFun ( "sum", Sum ); + p1->DefineFun ( "valueof", ValueOf ); + p1->DefineFun ( "atof", StrToFloat ); + p1->DefineFun ( "strfun1", StrFun1 ); + p1->DefineFun ( "strfun2", StrFun2 ); + p1->DefineFun ( "strfun3", StrFun3 ); + p1->DefineFun ( "lastArg", LastArg ); + p1->DefineFun ( "firstArg", FirstArg ); + p1->DefineFun ( "order", FirstArg ); - // infix / postfix operator - // Note: Identifiers used here do not have any meaning - // they are mere placeholders to test certain features. - p1->DefineInfixOprt ( "$", sign, prPOW + 1 ); // sign with high priority - p1->DefineInfixOprt ( "~", plus2 ); // high priority - p1->DefineInfixOprt ( "~~", plus2 ); - p1->DefinePostfixOprt ( "{m}", Milli ); - p1->DefinePostfixOprt ( "{M}", Mega ); - p1->DefinePostfixOprt ( "m", Milli ); - p1->DefinePostfixOprt ( "meg", Mega ); - p1->DefinePostfixOprt ( "#", times3 ); - p1->DefinePostfixOprt ( "'", sqr ); - p1->SetExpr ( a_str ); + // infix / postfix operator + // Note: Identifiers used here do not have any meaning + // they are mere placeholders to test certain features. + p1->DefineInfixOprt ( "$", sign, prPOW + 1 ); // sign with high priority + p1->DefineInfixOprt ( "~", plus2 ); // high priority + p1->DefineInfixOprt ( "~~", plus2 ); + p1->DefinePostfixOprt ( "{m}", Milli ); + p1->DefinePostfixOprt ( "{M}", Mega ); + p1->DefinePostfixOprt ( "m", Milli ); + p1->DefinePostfixOprt ( "meg", Mega ); + p1->DefinePostfixOprt ( "#", times3 ); + p1->DefinePostfixOprt ( "'", sqr ); + p1->SetExpr ( a_str ); - // Test bytecode integrity - // String parsing and bytecode parsing must yield the same result - fVal[0] = p1->Eval(); // result from stringparsing - fVal[1] = p1->Eval(); // result from bytecode - if ( qFuzzyCompare( fVal[0], fVal[1] ) == false ) - { - throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); - } + // Test bytecode integrity + // String parsing and bytecode parsing must yield the same result + fVal[0] = p1->Eval(); // result from stringparsing + fVal[1] = p1->Eval(); // result from bytecode + if ( qFuzzyCompare( fVal[0], fVal[1] ) == false ) + { + throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); + } - // Test copy and assignement operators - try - { - // Test copy constructor - QVector vParser; - vParser.push_back ( * ( p1.get() ) ); - qmu::QmuParser p2 = vParser[0]; // take parser from vector + // Test copy and assignement operators + try + { + // Test copy constructor + QVector vParser; + vParser.push_back ( * ( p1.get() ) ); + qmu::QmuParser p2 = vParser[0]; // take parser from vector - // destroy the originals from p2 - vParser.clear(); // delete the vector - p1.reset ( 0 ); + // destroy the originals from p2 + vParser.clear(); // delete the vector + p1.reset ( 0 ); - fVal[2] = p2.Eval(); + fVal[2] = p2.Eval(); - // Test assignement operator - // additionally disable Optimizer this time - qmu::QmuParser p3; - p3 = p2; - p3.EnableOptimizer ( false ); - fVal[3] = p3.Eval(); + // Test assignement operator + // additionally disable Optimizer this time + qmu::QmuParser p3; + p3 = p2; + p3.EnableOptimizer ( false ); + fVal[3] = p3.Eval(); - // Test Eval function for multiple return values - // use p2 since it has the optimizer enabled! - int nNum; - qreal *v = p2.Eval ( nNum ); - fVal[4] = v[nNum - 1]; - } - catch ( std::exception &e ) - { - qDebug() << "\n " << e.what() << "\n"; - } + // Test Eval function for multiple return values + // use p2 since it has the optimizer enabled! + int nNum; + qreal *v = p2.Eval ( nNum ); + fVal[4] = v[nNum - 1]; + } + catch ( std::exception &e ) + { + qDebug() << "\n " << e.what() << "\n"; + } - // limited floating point accuracy requires the following test - bool bCloseEnough ( true ); - for ( unsigned i = 0; i < sizeof ( fVal ) / sizeof ( qreal ); ++i ) - { - bCloseEnough &= ( fabs ( a_fRes - fVal[i] ) <= fabs ( fVal[i] * 0.00001 ) ); + // limited floating point accuracy requires the following test + bool bCloseEnough ( true ); + for ( unsigned i = 0; i < sizeof ( fVal ) / sizeof ( qreal ); ++i ) + { + bCloseEnough &= ( fabs ( a_fRes - fVal[i] ) <= fabs ( fVal[i] * 0.00001 ) ); - // The tests equations never result in infinity, if they do thats a bug. - // reference: - // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825 - if ( numeric_limits::has_infinity ) - { - bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), numeric_limits::infinity())==false ); - } - } + // The tests equations never result in infinity, if they do thats a bug. + // reference: + // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825 + if ( numeric_limits::has_infinity ) + { + bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), numeric_limits::infinity())==false ); + } + } - iRet = ( ( bCloseEnough && a_fPass ) || ( !bCloseEnough && !a_fPass ) ) ? 0 : 1; + iRet = ( ( bCloseEnough && a_fPass ) || ( bCloseEnough == false && a_fPass == false) ) ? 0 : 1; - if ( iRet == 1 ) - { - qDebug() << "\n fail: " << a_str - << " (incorrect result; expected: " << a_fRes - << " ;calculated: " << fVal[0] << "," - << fVal[1] << "," - << fVal[2] << "," - << fVal[3] << "," - << fVal[4] << ")."; - } - } - catch ( QmuParser::exception_type &e ) - { - if ( a_fPass ) - { - if ( (qFuzzyCompare(fVal[0], fVal[2])==false) && (qFuzzyCompare(fVal[0], -999)==false) && - (qFuzzyCompare(fVal[1], -998 )==false)) - { - qDebug() << "\n fail: " << a_str << " (copy construction)"; - } - else - { - qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; - } - return 1; - } - } - catch ( std::exception &e ) - { - qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; - return 1; // always return a failure since this exception is not expected - } - catch ( ... ) - { - qDebug() << "\n fail: " << a_str << " (unexpected exception)"; - return 1; // exceptions other than ParserException are not allowed - } + if ( iRet == 1 ) + { + qDebug() << "\n fail: " << a_str + << " (incorrect result; expected: " << a_fRes + << " ;calculated: " << fVal[0] << "," + << fVal[1] << "," + << fVal[2] << "," + << fVal[3] << "," + << fVal[4] << ")."; + } + } + catch ( QmuParser::exception_type &e ) + { + if ( a_fPass ) + { + if ( (qFuzzyCompare(fVal[0], fVal[2])==false) && (qFuzzyCompare(fVal[0], -999)==false) && + (qFuzzyCompare(fVal[1], -998 )==false)) + { + qDebug() << "\n fail: " << a_str << " (copy construction)"; + } + else + { + qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; + } + return 1; + } + } + catch ( std::exception &e ) + { + qDebug() << "\n fail: " << a_str << " (" << e.what() << ")"; + return 1; // always return a failure since this exception is not expected + } + catch ( ... ) + { + qDebug() << "\n fail: " << a_str << " (unexpected exception)"; + return 1; // exceptions other than ParserException are not allowed + } - return iRet; + return iRet; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Internal error in test class Test is going to be aborted. */ void Q_NORETURN QmuParserTester::Abort() const { - qDebug() << "Test failed (internal error in test class)" ; - while ( !getchar() ); - exit ( -1 ); + qDebug() << "Test failed (internal error in test class)"; + while ( getchar() == false); + exit ( -1 ); } } // namespace test } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index aaf5ab48d..648e6fb9c 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -41,7 +41,7 @@ namespace qmu */ namespace Test { -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Test cases for unit testing. * @@ -50,253 +50,251 @@ namespace Test class QmuParserTester // final { public: - typedef int ( QmuParserTester::*testfun_type ) (); + typedef int ( QmuParserTester::*testfun_type ) (); - QmuParserTester(); - void Run(); + QmuParserTester(); + void Run(); private: - QVector m_vTestFun; - static int c_iCount; + QVector m_vTestFun; + static int c_iCount; - void AddTest ( testfun_type a_pFun ); + void AddTest ( testfun_type a_pFun ); - // Test Double Parser - int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ); - int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 ); - int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true ); + // Test Double Parser + int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ); + int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 ); + int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true ); - // Multiarg callbacks - static qreal f1of1 ( qreal v ) - { - return v; - } + // Multiarg callbacks + static qreal f1of1 ( qreal v ) + { + return v; + } - static qreal f1of2 ( qreal v, qreal ) - { - return v; - } + static qreal f1of2 ( qreal v, qreal ) + { + return v; + } - static qreal f2of2 ( qreal , qreal v ) - { - return v; - } + static qreal f2of2 ( qreal, qreal v ) + { + return v; + } - static qreal f1of3 ( qreal v, qreal , qreal ) - { - return v; - } + static qreal f1of3 ( qreal v, qreal, qreal ) + { + return v; + } - static qreal f2of3 ( qreal , qreal v, qreal ) - { - return v; - } + static qreal f2of3 ( qreal, qreal v, qreal ) + { + return v; + } - static qreal f3of3 ( qreal , qreal , qreal v ) - { - return v; - } + static qreal f3of3 ( qreal, qreal, qreal v ) + { + return v; + } - static qreal f1of4 ( qreal v, qreal, qreal , qreal ) - { - return v; - } + static qreal f1of4 ( qreal v, qreal, qreal, qreal ) + { + return v; + } - static qreal f2of4 ( qreal , qreal v, qreal , qreal ) - { - return v; - } + static qreal f2of4 ( qreal, qreal v, qreal, qreal ) + { + return v; + } - static qreal f3of4 ( qreal , qreal, qreal v, qreal ) - { - return v; - } + static qreal f3of4 ( qreal, qreal, qreal v, qreal ) + { + return v; + } - static qreal f4of4 ( qreal , qreal, qreal , qreal v ) - { - return v; - } + static qreal f4of4 ( qreal, qreal, qreal, qreal v ) + { + return v; + } - static qreal f1of5 ( qreal v, qreal, qreal , qreal , qreal ) - { - return v; - } + static qreal f1of5 ( qreal v, qreal, qreal, qreal, qreal ) + { + return v; + } - static qreal f2of5 ( qreal , qreal v, qreal , qreal , qreal ) - { - return v; - } + static qreal f2of5 ( qreal, qreal v, qreal, qreal, qreal ) + { + return v; + } - static qreal f3of5 ( qreal , qreal, qreal v, qreal , qreal ) - { - return v; - } + static qreal f3of5 ( qreal, qreal, qreal v, qreal, qreal ) + { + return v; + } - static qreal f4of5 ( qreal , qreal, qreal , qreal v, qreal ) - { - return v; - } + static qreal f4of5 ( qreal, qreal, qreal, qreal v, qreal ) + { + return v; + } - static qreal f5of5 ( qreal , qreal, qreal , qreal , qreal v ) - { - return v; - } + static qreal f5of5 ( qreal, qreal, qreal, qreal, qreal v ) + { + return v; + } - static qreal Min ( qreal a_fVal1, qreal a_fVal2 ) - { - return ( a_fVal1 < a_fVal2 ) ? a_fVal1 : a_fVal2; - } + static qreal Min ( qreal a_fVal1, qreal a_fVal2 ) + { + return ( a_fVal1 < a_fVal2 ) ? a_fVal1 : a_fVal2; + } - static qreal Max ( qreal a_fVal1, qreal a_fVal2 ) - { - return ( a_fVal1 > a_fVal2 ) ? a_fVal1 : a_fVal2; - } + static qreal Max ( qreal a_fVal1, qreal a_fVal2 ) + { + return ( a_fVal1 > a_fVal2 ) ? a_fVal1 : a_fVal2; + } - static qreal plus2 ( qreal v1 ) - { - return v1 + 2; - } + static qreal plus2 ( qreal v1 ) + { + return v1 + 2; + } - static qreal times3 ( qreal v1 ) - { - return v1 * 3; - } + static qreal times3 ( qreal v1 ) + { + return v1 * 3; + } - static qreal sqr ( qreal v1 ) - { - return v1 * v1; - } + static qreal sqr ( qreal v1 ) + { + return v1 * v1; + } - static qreal sign ( qreal v ) - { - return -v; - } + static qreal sign ( qreal v ) + { + return -v; + } - static qreal add ( qreal v1, qreal v2 ) - { - return v1 + v2; - } + static qreal add ( qreal v1, qreal v2 ) + { + return v1 + v2; + } - static qreal land ( qreal v1, qreal v2 ) - { - return static_cast( v1 ) & static_cast( v2 ); - } + static qreal land ( qreal v1, qreal v2 ) + { + return static_cast( v1 ) & static_cast( v2 ); + } - static qreal FirstArg ( const qreal* a_afArg, int a_iArgc ) - { - if ( !a_iArgc ) - { - throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." ); - } + static qreal FirstArg ( const qreal* a_afArg, int a_iArgc ) + { + if ( a_iArgc == false) + { + throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." ); + } - return a_afArg[0]; - } + return a_afArg[0]; + } - static qreal LastArg ( const qreal* a_afArg, int a_iArgc ) - { - if ( !a_iArgc ) - { - throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." ); - } + static qreal LastArg ( const qreal* a_afArg, int a_iArgc ) + { + if ( a_iArgc == false) + { + throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." ); + } - return a_afArg[a_iArgc - 1]; - } + return a_afArg[a_iArgc - 1]; + } - static qreal Sum ( const qreal* a_afArg, int a_iArgc ) - { - if ( !a_iArgc ) - { - throw qmu::QmuParser::exception_type ( "too few arguments for function sum." ); - } + static qreal Sum ( const qreal* a_afArg, int a_iArgc ) + { + if ( a_iArgc == false) + { + throw qmu::QmuParser::exception_type ( "too few arguments for function sum." ); + } - qreal fRes = 0; - for ( int i = 0; i < a_iArgc; ++i ) - { - fRes += a_afArg[i]; - } - return fRes; - } + qreal fRes = 0; + for ( int i = 0; i < a_iArgc; ++i ) + { + fRes += a_afArg[i]; + } + return fRes; + } - static qreal Rnd ( qreal v ) - { - return static_cast( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) ); - } + static qreal Rnd ( qreal v ) + { + return static_cast( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) ); + } - static qreal RndWithString ( const char_type* ) - { - return static_cast( ( 1 + ( 1000.0f * static_cast(qrand()) / ( RAND_MAX + 1.0 ) ) ) ); - } + static qreal RndWithString ( const char_type* ) + { + return static_cast( ( 1 + ( 1000.0f * static_cast(qrand()) / ( RAND_MAX + 1.0 ) ) ) ); + } - static qreal Ping() - { - return 10; - } + static qreal Ping() + { + return 10; + } - static qreal ValueOf ( const QString & ) - { - return 123; - } + static qreal ValueOf ( const QString & ) + { + return 123; + } - static qreal StrFun1 ( const QString & v1 ) - { - int val = v1.toInt(); - return static_cast(val); - } + static qreal StrFun1 ( const QString & v1 ) + { + int val = v1.toInt(); + return static_cast(val); + } - static qreal StrFun2 ( const QString & v1, qreal v2 ) - { - int val = v1.toInt(); - return static_cast( val + v2 ); - } + static qreal StrFun2 ( const QString & v1, qreal v2 ) + { + int val = v1.toInt(); + return static_cast( val + v2 ); + } - static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 ) - { - int val = v1.toInt(); - return val + v2 + v3; - } + static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 ) + { + int val = v1.toInt(); + return val + v2 + v3; + } - static qreal StrToFloat ( const QString & a_szMsg ) - { - qreal val = a_szMsg.toDouble(); - return val; - } + static qreal StrToFloat ( const QString & a_szMsg ) + { + qreal val = a_szMsg.toDouble(); + return val; + } - // postfix operator callback - static qreal Mega ( qreal a_fVal ) - { - return a_fVal * static_cast( 1e6 ); - } + // postfix operator callback + static qreal Mega ( qreal a_fVal ) + { + return a_fVal * static_cast( 1e6 ); + } - static qreal Micro ( qreal a_fVal ) - { - return a_fVal * static_cast( 1e-6 ); - } + static qreal Micro ( qreal a_fVal ) + { + return a_fVal * static_cast( 1e-6 ); + } - static qreal Milli ( qreal a_fVal ) - { - return a_fVal / static_cast( 1e3 ); - } + static qreal Milli ( qreal a_fVal ) + { + return a_fVal / static_cast( 1e3 ); + } - // Custom value recognition - static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ); + // Custom value recognition + static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ); - int TestNames(); - int TestSyntax(); - int TestMultiArg(); - int TestPostFix(); - int TestExpression(); - int TestInfixOprt(); - int TestBinOprt(); - int TestVarConst(); - int TestInterface(); - int TestException(); - int TestStrArg(); - int TestIfThenElse(); + int TestNames(); + int TestSyntax(); + int TestMultiArg(); + int TestPostFix(); + int TestExpression(); + int TestInfixOprt(); + int TestBinOprt(); + int TestVarConst(); + int TestInterface(); + int TestException(); + int TestStrArg(); + int TestIfThenElse(); - void Abort() const; + void Abort() const; }; } // namespace Test } // namespace qmu #endif - - diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index a1ef34a13..815de0194 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -50,7 +50,7 @@ namespace qmu *
  • functions with a string as argument
  • *
  • prefix operators
  • *
  • infix operators
  • - *
  • binary operator
  • + *
  • binary operator
  • * * * @author (C) 2004-2013 Ingo Berg @@ -59,458 +59,470 @@ template class QmuParserToken { public: - //--------------------------------------------------------------------------- - /** - * @brief Constructor (default). - * - * Sets token to an neutral state of type cmUNKNOWN. - * @throw nothrow - * @sa ECmdCode - */ - QmuParserToken() - : m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(), - m_pCallback() - {} + //--------------------------------------------------------------------------- + /** + * @brief Constructor (default). + * + * Sets token to an neutral state of type cmUNKNOWN. + * @throw nothrow + * @sa ECmdCode + */ + QmuParserToken() + : m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(), + m_pCallback() + {} - //------------------------------------------------------------------------------ - /** - * @brief Create token from another one. - * - * Implemented by calling Assign(...) - * @throw nothrow - * @post m_iType==cmUNKNOWN - * @sa #Assign - */ - QmuParserToken ( const QmuParserToken &a_Tok ) - : m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ), - m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback() - { - Assign ( a_Tok ); - } + //------------------------------------------------------------------------------ + /** + * @brief Create token from another one. + * + * Implemented by calling Assign(...) + * @throw nothrow + * @post m_iType==cmUNKNOWN + * @sa #Assign + */ + QmuParserToken ( const QmuParserToken &a_Tok ) + : m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ), + m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback() + { + Assign ( a_Tok ); + } - //------------------------------------------------------------------------------ - /** - * @brief Assignement operator. - * - * Copy token state from another token and return this. - * Implemented by calling Assign(...). - * @throw nothrow - */ - QmuParserToken& operator= ( const QmuParserToken &a_Tok ) - { - Assign ( a_Tok ); - return *this; - } + //------------------------------------------------------------------------------ + /** + * @brief Assignement operator. + * + * Copy token state from another token and return this. + * Implemented by calling Assign(...). + * @throw nothrow + */ + QmuParserToken& operator= ( const QmuParserToken &a_Tok ) + { + Assign ( a_Tok ); + return *this; + } - //------------------------------------------------------------------------------ - /** - * @brief Copy token information from argument. - * - * @throw nothrow - */ - void Assign ( const QmuParserToken &a_Tok ) - { - m_iCode = a_Tok.m_iCode; - m_pTok = a_Tok.m_pTok; - m_strTok = a_Tok.m_strTok; - m_iIdx = a_Tok.m_iIdx; - m_strVal = a_Tok.m_strVal; - m_iType = a_Tok.m_iType; - m_fVal = a_Tok.m_fVal; - // create new callback object if a_Tok has one - m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 ); - } + //------------------------------------------------------------------------------ + /** + * @brief Copy token information from argument. + * + * @throw nothrow + */ + void Assign ( const QmuParserToken &a_Tok ) + { + m_iCode = a_Tok.m_iCode; + m_pTok = a_Tok.m_pTok; + m_strTok = a_Tok.m_strTok; + m_iIdx = a_Tok.m_iIdx; + m_strVal = a_Tok.m_strVal; + m_iType = a_Tok.m_iType; + m_fVal = a_Tok.m_fVal; + // create new callback object if a_Tok has one + m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 ); + } - //------------------------------------------------------------------------------ - /** - * @brief Assign a token type. - * - * Token may not be of type value, variable or function. Those have seperate set functions. - * - * @pre [assert] a_iType!=cmVAR - * @pre [assert] a_iType!=cmVAL - * @pre [assert] a_iType!=cmFUNC - * @post m_fVal = 0 - * @post m_pTok = 0 - */ - QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() ) - { - // The following types cant be set this way, they have special Set functions - assert ( a_iType != cmVAR ); - assert ( a_iType != cmVAL ); - assert ( a_iType != cmFUNC ); + //------------------------------------------------------------------------------ + /** + * @brief Assign a token type. + * + * Token may not be of type value, variable or function. Those have seperate set functions. + * + * @pre [assert] a_iType!=cmVAR + * @pre [assert] a_iType!=cmVAL + * @pre [assert] a_iType!=cmFUNC + * @post m_fVal = 0 + * @post m_pTok = 0 + */ + QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() ) + { + // The following types cant be set this way, they have special Set functions + assert ( a_iType != cmVAR ); + assert ( a_iType != cmVAL ); + assert ( a_iType != cmFUNC ); - m_iCode = a_iType; - m_iType = tpVOID; - m_pTok = 0; - m_strTok = a_strTok; - m_iIdx = -1; + m_iCode = a_iType; + m_iType = tpVOID; + m_pTok = 0; + m_strTok = a_strTok; + m_iIdx = -1; - return *this; - } + return *this; + } - //------------------------------------------------------------------------------ - /** - * @brief Set Callback type. - */ - QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok ) - { - assert ( a_pCallback.GetAddr() ); + //------------------------------------------------------------------------------ + /** + * @brief Set Callback type. + */ + QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok ) + { + assert ( a_pCallback.GetAddr() ); - m_iCode = a_pCallback.GetCode(); - m_iType = tpVOID; - m_strTok = a_sTok; - m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) ); + m_iCode = a_pCallback.GetCode(); + m_iType = tpVOID; + m_strTok = a_sTok; + m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) ); - m_pTok = 0; - m_iIdx = -1; + m_pTok = 0; + m_iIdx = -1; - return *this; - } + return *this; + } - //------------------------------------------------------------------------------ - /** - * @brief Make this token a value token. - * - * Member variables not necessary for value tokens will be invalidated. - * @throw nothrow - */ - QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() ) - { - m_iCode = cmVAL; - m_iType = tpDBL; - m_fVal = a_fVal; - m_strTok = a_strTok; - m_iIdx = -1; + //------------------------------------------------------------------------------ + /** + * @brief Make this token a value token. + * + * Member variables not necessary for value tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() ) + { + m_iCode = cmVAL; + m_iType = tpDBL; + m_fVal = a_fVal; + m_strTok = a_strTok; + m_iIdx = -1; - m_pTok = 0; - m_pCallback.reset ( 0 ); + m_pTok = 0; + m_pCallback.reset ( 0 ); - return *this; - } + return *this; + } - //------------------------------------------------------------------------------ - /** - * @brief make this token a variable token. - * - * Member variables not necessary for variable tokens will be invalidated. - * @throw nothrow - */ - QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok ) - { - m_iCode = cmVAR; - m_iType = tpDBL; - m_strTok = a_strTok; - m_iIdx = -1; - m_pTok = reinterpret_cast ( a_pVar ); - m_pCallback.reset ( 0 ); - return *this; - } + //------------------------------------------------------------------------------ + /** + * @brief make this token a variable token. + * + * Member variables not necessary for variable tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok ) + { + m_iCode = cmVAR; + m_iType = tpDBL; + m_strTok = a_strTok; + m_iIdx = -1; + m_pTok = reinterpret_cast ( a_pVar ); + m_pCallback.reset ( 0 ); + return *this; + } - //------------------------------------------------------------------------------ - /** - * @brief Make this token a variable token. - * - * Member variables not necessary for variable tokens will be invalidated. - * @throw nothrow - */ - QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize ) - { - m_iCode = cmSTRING; - m_iType = tpSTR; - m_strTok = a_strTok; - m_iIdx = static_cast ( a_iSize ); + //------------------------------------------------------------------------------ + /** + * @brief Make this token a variable token. + * + * Member variables not necessary for variable tokens will be invalidated. + * @throw nothrow + */ + QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize ) + { + m_iCode = cmSTRING; + m_iType = tpSTR; + m_strTok = a_strTok; + m_iIdx = static_cast ( a_iSize ); - m_pTok = 0; - m_pCallback.reset ( 0 ); - return *this; - } + m_pTok = 0; + m_pCallback.reset ( 0 ); + return *this; + } - //------------------------------------------------------------------------------ - /** - * @brief Set an index associated with the token related data. - * - * In cmSTRFUNC - This is the index to a string table in the main parser. - * @param a_iIdx The index the string function result will take in the bytecode parser. - * @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING - */ - void SetIdx ( int a_iIdx ) - { - if ( m_iCode != cmSTRING || a_iIdx < 0 ) - throw QmuParserError ( ecINTERNAL_ERROR ); + //------------------------------------------------------------------------------ + /** + * @brief Set an index associated with the token related data. + * + * In cmSTRFUNC - This is the index to a string table in the main parser. + * @param a_iIdx The index the string function result will take in the bytecode parser. + * @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING + */ + void SetIdx ( int a_iIdx ) + { + if ( m_iCode != cmSTRING || a_iIdx < 0 ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - m_iIdx = a_iIdx; - } + m_iIdx = a_iIdx; + } - //------------------------------------------------------------------------------ - /** - * @brief Return Index associated with the token related data. - * - * In cmSTRFUNC - This is the index to a string table in the main parser. - * - * @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING - * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). - */ - int GetIdx() const - { - if ( m_iIdx < 0 || m_iCode != cmSTRING ) - throw QmuParserError ( ecINTERNAL_ERROR ); + //------------------------------------------------------------------------------ + /** + * @brief Return Index associated with the token related data. + * + * In cmSTRFUNC - This is the index to a string table in the main parser. + * + * @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING + * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). + */ + int GetIdx() const + { + if ( m_iIdx < 0 || m_iCode != cmSTRING ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - return m_iIdx; - } + return m_iIdx; + } - //------------------------------------------------------------------------------ - /** - * @brief Return the token type. - * - * @return #m_iType - * @throw nothrow - */ - ECmdCode GetCode() const - { - if ( m_pCallback.get() ) - { - return m_pCallback->GetCode(); - } - else - { - return m_iCode; - } - } + //------------------------------------------------------------------------------ + /** + * @brief Return the token type. + * + * @return #m_iType + * @throw nothrow + */ + ECmdCode GetCode() const + { + if ( m_pCallback.get() ) + { + return m_pCallback->GetCode(); + } + else + { + return m_iCode; + } + } - //------------------------------------------------------------------------------ - ETypeCode GetType() const - { - if ( m_pCallback.get() ) - { - return m_pCallback->GetType(); - } - else - { - return m_iType; - } - } + //------------------------------------------------------------------------------ + ETypeCode GetType() const + { + if ( m_pCallback.get() ) + { + return m_pCallback->GetType(); + } + else + { + return m_iType; + } + } - //------------------------------------------------------------------------------ - int GetPri() const - { - if ( !m_pCallback.get() ) - throw QmuParserError ( ecINTERNAL_ERROR ); + //------------------------------------------------------------------------------ + int GetPri() const + { + if ( m_pCallback.get() == false) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX ) - throw QmuParserError ( ecINTERNAL_ERROR ); + if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - return m_pCallback->GetPri(); - } + return m_pCallback->GetPri(); + } - //------------------------------------------------------------------------------ - EOprtAssociativity GetAssociativity() const - { - if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN ) - throw QmuParserError ( ecINTERNAL_ERROR ); + //------------------------------------------------------------------------------ + EOprtAssociativity GetAssociativity() const + { + if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - return m_pCallback->GetAssociativity(); - } + return m_pCallback->GetAssociativity(); + } - //------------------------------------------------------------------------------ - /** - * @brief Return the address of the callback function assoziated with function and operator tokens. - * - * @return The pointer stored in #m_pTok. - * @throw exception_type if token type is non of: - *
      - *
    • cmFUNC
    • - *
    • cmSTRFUNC
    • - *
    • cmPOSTOP
    • - *
    • cmINFIXOP
    • - *
    • cmOPRT_BIN
    • - *
    - * @sa ECmdCode - */ - generic_fun_type GetFuncAddr() const - { - return ( m_pCallback.get() ) ? reinterpret_cast ( m_pCallback->GetAddr() ) : - reinterpret_cast (0); - } + //------------------------------------------------------------------------------ + /** + * @brief Return the address of the callback function assoziated with function and operator tokens. + * + * @return The pointer stored in #m_pTok. + * @throw exception_type if token type is non of: + *
      + *
    • cmFUNC
    • + *
    • cmSTRFUNC
    • + *
    • cmPOSTOP
    • + *
    • cmINFIXOP
    • + *
    • cmOPRT_BIN
    • + *
    + * @sa ECmdCode + */ + generic_fun_type GetFuncAddr() const + { + return ( m_pCallback.get() ) ? reinterpret_cast ( m_pCallback->GetAddr() ) : + reinterpret_cast (0); + } - //------------------------------------------------------------------------------ - /** - * @brief Get value of the token. - * - * Only applicable to variable and value tokens. - * @throw exception_type if token is no value/variable token. - */ - TBase GetVal() const - { - switch ( m_iCode ) - { - case cmVAL: - return m_fVal; - case cmVAR: - return * ( reinterpret_cast(m_pTok) ); - case cmLE: - Q_UNREACHABLE(); - break; - case cmGE: - Q_UNREACHABLE(); - break; - case cmNEQ: - Q_UNREACHABLE(); - break; - case cmEQ: - Q_UNREACHABLE(); - break; - case cmLT: - Q_UNREACHABLE(); - break; - case cmGT: - Q_UNREACHABLE(); - break; - case cmADD: - Q_UNREACHABLE(); - break; - case cmSUB: - Q_UNREACHABLE(); - break; - case cmMUL: - Q_UNREACHABLE(); - break; - case cmDIV: - Q_UNREACHABLE(); - break; - case cmPOW: - Q_UNREACHABLE(); - break; - case cmLAND: - Q_UNREACHABLE(); - break; - case cmLOR: - Q_UNREACHABLE(); - break; - case cmASSIGN: - Q_UNREACHABLE(); - break; - case cmBO: - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - case cmIF: - Q_UNREACHABLE(); - break; - case cmELSE: - Q_UNREACHABLE(); - break; - case cmENDIF: - Q_UNREACHABLE(); - break; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - case cmVARPOW2: - Q_UNREACHABLE(); - break; - case cmVARPOW3: - Q_UNREACHABLE(); - break; - case cmVARPOW4: - Q_UNREACHABLE(); - break; - case cmVARMUL: - Q_UNREACHABLE(); - break; - case cmPOW2: - Q_UNREACHABLE(); - break; - case cmFUNC: - Q_UNREACHABLE(); - break; - case cmFUNC_STR: - Q_UNREACHABLE(); - break; - case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; - case cmOPRT_BIN: - Q_UNREACHABLE(); - break; - case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; - case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; - case cmEND: - Q_UNREACHABLE(); - break; - case cmUNKNOWN: - Q_UNREACHABLE(); - break; - default: - throw QmuParserError ( ecVAL_EXPECTED ); - } - } + //------------------------------------------------------------------------------ + /** + * @brief Get value of the token. + * + * Only applicable to variable and value tokens. + * @throw exception_type if token is no value/variable token. + */ + TBase GetVal() const + { + switch ( m_iCode ) + { + case cmVAL: + return m_fVal; + case cmVAR: + return * ( reinterpret_cast(m_pTok) ); + case cmLE: + Q_UNREACHABLE(); + break; + case cmGE: + Q_UNREACHABLE(); + break; + case cmNEQ: + Q_UNREACHABLE(); + break; + case cmEQ: + Q_UNREACHABLE(); + break; + case cmLT: + Q_UNREACHABLE(); + break; + case cmGT: + Q_UNREACHABLE(); + break; + case cmADD: + Q_UNREACHABLE(); + break; + case cmSUB: + Q_UNREACHABLE(); + break; + case cmMUL: + Q_UNREACHABLE(); + break; + case cmDIV: + Q_UNREACHABLE(); + break; + case cmPOW: + Q_UNREACHABLE(); + break; + case cmLAND: + Q_UNREACHABLE(); + break; + case cmLOR: + Q_UNREACHABLE(); + break; + case cmASSIGN: + Q_UNREACHABLE(); + break; + case cmBO: + Q_UNREACHABLE(); + break; + case cmBC: + Q_UNREACHABLE(); + break; + case cmIF: + Q_UNREACHABLE(); + break; + case cmELSE: + Q_UNREACHABLE(); + break; + case cmENDIF: + Q_UNREACHABLE(); + break; + case cmARG_SEP: + Q_UNREACHABLE(); + break; + case cmVARPOW2: + Q_UNREACHABLE(); + break; + case cmVARPOW3: + Q_UNREACHABLE(); + break; + case cmVARPOW4: + Q_UNREACHABLE(); + break; + case cmVARMUL: + Q_UNREACHABLE(); + break; + case cmPOW2: + Q_UNREACHABLE(); + break; + case cmFUNC: + Q_UNREACHABLE(); + break; + case cmFUNC_STR: + Q_UNREACHABLE(); + break; + case cmFUNC_BULK: + Q_UNREACHABLE(); + break; + case cmSTRING: + Q_UNREACHABLE(); + break; + case cmOPRT_BIN: + Q_UNREACHABLE(); + break; + case cmOPRT_POSTFIX: + Q_UNREACHABLE(); + break; + case cmOPRT_INFIX: + Q_UNREACHABLE(); + break; + case cmEND: + Q_UNREACHABLE(); + break; + case cmUNKNOWN: + Q_UNREACHABLE(); + break; + default: + throw QmuParserError ( ecVAL_EXPECTED ); + } + } - //------------------------------------------------------------------------------ - /** - * @brief Get address of a variable token. - * - * Valid only if m_iType==CmdVar. - * @throw exception_type if token is no variable token. - */ - TBase* GetVar() const - { - if ( m_iCode != cmVAR ) - { - throw QmuParserError ( ecINTERNAL_ERROR ); - } + //------------------------------------------------------------------------------ + /** + * @brief Get address of a variable token. + * + * Valid only if m_iType==CmdVar. + * @throw exception_type if token is no variable token. + */ + TBase* GetVar() const + { + if ( m_iCode != cmVAR ) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - return reinterpret_cast( m_pTok ); - } + return reinterpret_cast( m_pTok ); + } - //------------------------------------------------------------------------------ - /** - * @brief Return the number of function arguments. - * - * Valid only if m_iType==CmdFUNC. - */ - int GetArgCount() const - { - assert ( m_pCallback.get() ); + //------------------------------------------------------------------------------ + /** + * @brief Return the number of function arguments. + * + * Valid only if m_iType==CmdFUNC. + */ + int GetArgCount() const + { + assert ( m_pCallback.get() ); - if ( !m_pCallback->GetAddr() ) - throw QmuParserError ( ecINTERNAL_ERROR ); + if ( m_pCallback->GetAddr() == false) + { + throw QmuParserError ( ecINTERNAL_ERROR ); + } - return m_pCallback->GetArgc(); - } + return m_pCallback->GetArgc(); + } - //------------------------------------------------------------------------------ - /** - * @brief Return the token identifier. - * - * If #m_iType is cmSTRING the token identifier is the value of the string argument - * for a string function. - * @return #m_strTok - * @throw nothrow - * @sa m_strTok - */ - const TString& GetAsString() const - { - return m_strTok; - } + //------------------------------------------------------------------------------ + /** + * @brief Return the token identifier. + * + * If #m_iType is cmSTRING the token identifier is the value of the string argument + * for a string function. + * @return #m_strTok + * @throw nothrow + * @sa m_strTok + */ + const TString& GetAsString() const + { + return m_strTok; + } private: - ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. - ETypeCode m_iType; - void *m_pTok; ///< Stores Token pointer; not applicable for all tokens - int m_iIdx; ///< An otional index to an external buffer storing the token data - TString m_strTok; ///< Token string - TString m_strVal; ///< Value for string variables - qreal m_fVal; ///< the value - std::unique_ptr m_pCallback; + ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode. + ETypeCode m_iType; + void *m_pTok; ///< Stores Token pointer; not applicable for all tokens + int m_iIdx; ///< An otional index to an external buffer storing the token data + TString m_strTok; ///< Token string + TString m_strVal; ///< Value for string variables + qreal m_fVal; ///< the value + std::unique_ptr m_pCallback; }; } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 6ba7a541d..485bdbda0 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -36,7 +36,7 @@ namespace qmu // Forward declaration class QmuParserBase; -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Copy constructor. * @@ -44,17 +44,17 @@ class QmuParserBase; * @throw nothrow */ QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader ) - :m_pParser( a_Reader.m_pParser ), m_strFormula( a_Reader.m_strFormula ), m_iPos( a_Reader.m_iPos ), - m_iSynFlags( a_Reader.m_iSynFlags ), m_bIgnoreUndefVar( a_Reader.m_bIgnoreUndefVar ), - m_pFunDef( a_Reader.m_pFunDef ), m_pPostOprtDef( a_Reader.m_pPostOprtDef ), - m_pInfixOprtDef( a_Reader.m_pInfixOprtDef ), m_pOprtDef( a_Reader.m_pOprtDef), - m_pConstDef( a_Reader.m_pConstDef ), m_pStrVarDef( a_Reader.m_pStrVarDef ), m_pVarDef( a_Reader.m_pVarDef ), - m_pFactory( a_Reader.m_pFactory ), m_pFactoryData( a_Reader.m_pFactoryData ), m_vIdentFun( a_Reader.m_vIdentFun ), - m_UsedVar( a_Reader.m_UsedVar ), m_fZero(0), m_iBrackets( a_Reader.m_iBrackets ), m_lastTok(), - m_cArgSep( a_Reader.m_cArgSep ) + :m_pParser( a_Reader.m_pParser ), m_strFormula( a_Reader.m_strFormula ), m_iPos( a_Reader.m_iPos ), + m_iSynFlags( a_Reader.m_iSynFlags ), m_bIgnoreUndefVar( a_Reader.m_bIgnoreUndefVar ), + m_pFunDef( a_Reader.m_pFunDef ), m_pPostOprtDef( a_Reader.m_pPostOprtDef ), + m_pInfixOprtDef( a_Reader.m_pInfixOprtDef ), m_pOprtDef( a_Reader.m_pOprtDef), + m_pConstDef( a_Reader.m_pConstDef ), m_pStrVarDef( a_Reader.m_pStrVarDef ), m_pVarDef( a_Reader.m_pVarDef ), + m_pFactory( a_Reader.m_pFactory ), m_pFactoryData( a_Reader.m_pFactoryData ), m_vIdentFun( a_Reader.m_vIdentFun ), + m_UsedVar( a_Reader.m_UsedVar ), m_fZero(0), m_iBrackets( a_Reader.m_iBrackets ), m_lastTok(), + m_cArgSep( a_Reader.m_cArgSep ) {} -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Assignement operator. * @@ -65,15 +65,15 @@ QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reade */ QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenReader &a_Reader ) { - if ( &a_Reader != this ) - { - Assign ( a_Reader ); - } + if ( &a_Reader != this ) + { + Assign ( a_Reader ); + } - return *this; + return *this; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Assign state of a token reader to this token reader. * @@ -82,28 +82,28 @@ QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenRead */ void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) { - m_pParser = a_Reader.m_pParser; - m_strFormula = a_Reader.m_strFormula; - m_iPos = a_Reader.m_iPos; - m_iSynFlags = a_Reader.m_iSynFlags; + m_pParser = a_Reader.m_pParser; + m_strFormula = a_Reader.m_strFormula; + m_iPos = a_Reader.m_iPos; + m_iSynFlags = a_Reader.m_iSynFlags; - m_UsedVar = a_Reader.m_UsedVar; - m_pFunDef = a_Reader.m_pFunDef; - m_pConstDef = a_Reader.m_pConstDef; - m_pVarDef = a_Reader.m_pVarDef; - m_pStrVarDef = a_Reader.m_pStrVarDef; - m_pPostOprtDef = a_Reader.m_pPostOprtDef; - m_pInfixOprtDef = a_Reader.m_pInfixOprtDef; - m_pOprtDef = a_Reader.m_pOprtDef; - m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar; - m_vIdentFun = a_Reader.m_vIdentFun; - m_pFactory = a_Reader.m_pFactory; - m_pFactoryData = a_Reader.m_pFactoryData; - m_iBrackets = a_Reader.m_iBrackets; - m_cArgSep = a_Reader.m_cArgSep; + m_UsedVar = a_Reader.m_UsedVar; + m_pFunDef = a_Reader.m_pFunDef; + m_pConstDef = a_Reader.m_pConstDef; + m_pVarDef = a_Reader.m_pVarDef; + m_pStrVarDef = a_Reader.m_pStrVarDef; + m_pPostOprtDef = a_Reader.m_pPostOprtDef; + m_pInfixOprtDef = a_Reader.m_pInfixOprtDef; + m_pOprtDef = a_Reader.m_pOprtDef; + m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar; + m_vIdentFun = a_Reader.m_vIdentFun; + m_pFactory = a_Reader.m_pFactory; + m_pFactoryData = a_Reader.m_pFactoryData; + m_iBrackets = a_Reader.m_iBrackets; + m_cArgSep = a_Reader.m_cArgSep; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Constructor. * @@ -114,16 +114,16 @@ void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) * @param a_pParent Parent parser object of the token reader. */ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) - : m_pParser ( a_pParent ), m_strFormula(), m_iPos ( 0 ), m_iSynFlags ( 0 ), m_bIgnoreUndefVar ( false ), - m_pFunDef ( NULL ), m_pPostOprtDef ( NULL ), m_pInfixOprtDef ( NULL ), m_pOprtDef ( NULL ), m_pConstDef ( NULL ), - m_pStrVarDef ( NULL ), m_pVarDef ( NULL ), m_pFactory ( NULL ), m_pFactoryData ( NULL ), m_vIdentFun(), - m_UsedVar(), m_fZero ( 0 ), m_iBrackets ( 0 ), m_lastTok(), m_cArgSep ( ',' ) + : m_pParser ( a_pParent ), m_strFormula(), m_iPos ( 0 ), m_iSynFlags ( 0 ), m_bIgnoreUndefVar ( false ), + m_pFunDef ( NULL ), m_pPostOprtDef ( NULL ), m_pInfixOprtDef ( NULL ), m_pOprtDef ( NULL ), m_pConstDef ( NULL ), + m_pStrVarDef ( NULL ), m_pVarDef ( NULL ), m_pFactory ( NULL ), m_pFactoryData ( NULL ), m_vIdentFun(), + m_UsedVar(), m_fZero ( 0 ), m_iBrackets ( 0 ), m_lastTok(), m_cArgSep ( ',' ) { - assert ( m_pParser ); - SetParent ( m_pParser ); + assert ( m_pParser ); + SetParent ( m_pParser ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Create instance of a QParserTokenReader identical with this and return its pointer. * @@ -134,38 +134,38 @@ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) */ QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const { - std::unique_ptr ptr ( new QmuParserTokenReader ( *this ) ); - ptr->SetParent ( a_pParent ); - return ptr.release(); + std::unique_ptr ptr ( new QmuParserTokenReader ( *this ) ); + ptr->SetParent ( a_pParent ); + return ptr.release(); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QmuParserTokenReader::token_type& QmuParserTokenReader::SaveBeforeReturn ( const token_type &tok ) { - m_lastTok = tok; - return m_lastTok; + m_lastTok = tok; + return m_lastTok; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParserTokenReader::AddValIdent ( identfun_type a_pCallback ) { - // Use push_front is used to give user defined callbacks a higher priority than - // the built in ones. Otherwise reading hex numbers would not work - // since the "0" in "0xff" would always be read first making parsing of - // the rest impossible. - // reference: - // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956 - m_vIdentFun.push_front ( a_pCallback ); + // Use push_front is used to give user defined callbacks a higher priority than + // the built in ones. Otherwise reading hex numbers would not work + // since the "0" in "0xff" would always be read first making parsing of + // the rest impossible. + // reference: + // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956 + m_vIdentFun.push_front ( a_pCallback ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParserTokenReader::SetVarCreator ( facfun_type a_pFactory, void *pUserData ) { - m_pFactory = a_pFactory; - m_pFactoryData = pUserData; + m_pFactory = a_pFactory; + m_pFactoryData = pUserData; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return the current position of the token reader in the formula string. * @@ -174,10 +174,10 @@ void QmuParserTokenReader::SetVarCreator ( facfun_type a_pFactory, void *pUserDa */ int QmuParserTokenReader::GetPos() const { - return m_iPos; + return m_iPos; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return a reference to the formula. * @@ -186,19 +186,19 @@ int QmuParserTokenReader::GetPos() const */ const QString& QmuParserTokenReader::GetExpr() const { - return m_strFormula; + return m_strFormula; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Return a map containing the used variables only. */ varmap_type& QmuParserTokenReader::GetUsedVar() { - return m_UsedVar; + return m_UsedVar; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Initialize the token Reader. * @@ -207,11 +207,11 @@ varmap_type& QmuParserTokenReader::GetUsedVar() */ void QmuParserTokenReader::SetFormula ( const QString &a_strFormula ) { - m_strFormula = a_strFormula; - ReInit(); + m_strFormula = a_strFormula; + ReInit(); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Set Flag that contronls behaviour in case of undefined variables beeing found. * @@ -222,10 +222,10 @@ void QmuParserTokenReader::SetFormula ( const QString &a_strFormula ) */ void QmuParserTokenReader::IgnoreUndefVar ( bool bIgnore ) { - m_bIgnoreUndefVar = bIgnore; + m_bIgnoreUndefVar = bIgnore; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Reset the token reader to the start of the formula. * @@ -236,87 +236,120 @@ void QmuParserTokenReader::IgnoreUndefVar ( bool bIgnore ) */ void QmuParserTokenReader::ReInit() { - m_iPos = 0; - m_iSynFlags = sfSTART_OF_LINE; - m_iBrackets = 0; - m_UsedVar.clear(); - m_lastTok = token_type(); + m_iPos = 0; + m_iSynFlags = sfSTART_OF_LINE; + m_iBrackets = 0; + m_UsedVar.clear(); + m_lastTok = token_type(); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Read the next token from the string. */ QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken() { - assert ( m_pParser ); + assert ( m_pParser ); #if defined(_UNICODE) - const char_type *szFormula = m_strFormula.toStdWString().c_str(); + const char_type *szFormula = m_strFormula.toStdWString().c_str(); #else - const char_type *szFormula = m_strFormula.toStdString().c_str(); + const char_type *szFormula = m_strFormula.toStdString().c_str(); #endif - token_type tok; + token_type tok; - // Ignore all non printable characters when reading the expression - while ( szFormula[m_iPos] > 0 && szFormula[m_iPos] <= 0x20 ) - { - ++m_iPos; - } + // Ignore all non printable characters when reading the expression + while ( szFormula[m_iPos] > 0 && szFormula[m_iPos] <= 0x20 ) + { + ++m_iPos; + } - if ( IsEOF ( tok ) ) return SaveBeforeReturn ( tok ); // Check for end of formula - if ( IsOprt ( tok ) ) return SaveBeforeReturn ( tok ); // Check for user defined binary operator - if ( IsFunTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for function token - if ( IsBuiltIn ( tok ) ) return SaveBeforeReturn ( tok ); // Check built in operators / tokens - if ( IsArgSep ( tok ) ) return SaveBeforeReturn ( tok ); // Check for function argument separators - if ( IsValTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for values / constant tokens - if ( IsVarTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for variable tokens - if ( IsStrVarTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for string variables - if ( IsString ( tok ) ) return SaveBeforeReturn ( tok ); // Check for String tokens - if ( IsInfixOpTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for unary operators - if ( IsPostOpTok ( tok ) ) return SaveBeforeReturn ( tok ); // Check for unary operators + if ( IsEOF ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for end of formula + } + if ( IsOprt ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for user defined binary operator + } + if ( IsFunTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for function token + } + if ( IsBuiltIn ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check built in operators / tokens + } + if ( IsArgSep ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for function argument separators + } + if ( IsValTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for values / constant tokens + } + if ( IsVarTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for variable tokens + } + if ( IsStrVarTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for string variables + } + if ( IsString ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for String tokens + } + if ( IsInfixOpTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for unary operators + } + if ( IsPostOpTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); // Check for unary operators + } - // Check String for undefined variable token. Done only if a - // flag is set indicating to ignore undefined variables. - // This is a way to conditionally avoid an error if - // undefined variables occur. - // (The GetUsedVar function must suppress the error for - // undefined variables in order to collect all variable - // names including the undefined ones.) - if ( ( m_bIgnoreUndefVar || m_pFactory ) && IsUndefVarTok ( tok ) ) - { - return SaveBeforeReturn ( tok ); - } + // Check String for undefined variable token. Done only if a + // flag is set indicating to ignore undefined variables. + // This is a way to conditionally avoid an error if + // undefined variables occur. + // (The GetUsedVar function must suppress the error for + // undefined variables in order to collect all variable + // names including the undefined ones.) + if ( ( m_bIgnoreUndefVar || m_pFactory ) && IsUndefVarTok ( tok ) ) + { + return SaveBeforeReturn ( tok ); + } - // Check for unknown token - // - // !!! From this point on there is no exit without an exception possible... - // - QString strTok; - int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); - if ( iEnd != m_iPos ) - { - Error ( ecUNASSIGNABLE_TOKEN, m_iPos, strTok ); - } + // Check for unknown token + // + // !!! From this point on there is no exit without an exception possible... + // + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd != m_iPos ) + { + Error ( ecUNASSIGNABLE_TOKEN, m_iPos, strTok ); + } - Error ( ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid ( m_iPos ) ); - return token_type(); // never reached + Error ( ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.mid ( m_iPos ) ); + return token_type(); // never reached } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParserTokenReader::SetParent ( QmuParserBase *a_pParent ) { - m_pParser = a_pParent; - m_pFunDef = &a_pParent->m_FunDef; - m_pOprtDef = &a_pParent->m_OprtDef; - m_pInfixOprtDef = &a_pParent->m_InfixOprtDef; - m_pPostOprtDef = &a_pParent->m_PostOprtDef; - m_pVarDef = &a_pParent->m_VarDef; - m_pStrVarDef = &a_pParent->m_StrVarDef; - m_pConstDef = &a_pParent->m_ConstDef; + m_pParser = a_pParent; + m_pFunDef = &a_pParent->m_FunDef; + m_pOprtDef = &a_pParent->m_OprtDef; + m_pInfixOprtDef = &a_pParent->m_InfixOprtDef; + m_pPostOprtDef = &a_pParent->m_PostOprtDef; + m_pVarDef = &a_pParent->m_VarDef; + m_pStrVarDef = &a_pParent->m_StrVarDef; + m_pConstDef = &a_pParent->m_ConstDef; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Extract all characters that belong to a certain charset. * @@ -329,34 +362,36 @@ void QmuParserTokenReader::SetParent ( QmuParserBase *a_pParent ) int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_sTok, int a_iPos ) const { #if defined(_UNICODE) - const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); - const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); #else - const std::string m_strFormulaStd = m_strFormula.toStdString(); - const std::string a_szCharSetStd = a_szCharSet.toStdString(); + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string a_szCharSetStd = a_szCharSet.toStdString(); #endif - int iEnd = static_cast(m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos )); + int iEnd = static_cast(m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos )); - if ( iEnd == static_cast(string_type::npos) ) - { - iEnd = static_cast(m_strFormulaStd.length()); - } + if ( iEnd == static_cast(string_type::npos) ) + { + iEnd = static_cast(m_strFormulaStd.length()); + } - // Assign token string if there was something found - if ( a_iPos != iEnd ) - { + // Assign token string if there was something found + if ( a_iPos != iEnd ) + { #if defined(_UNICODE) - a_sTok = QString().fromStdWString ( std::wstring ( m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd ) ); + a_sTok = QString().fromStdWString ( std::wstring ( m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd ) ); #else - a_sTok = QString().fromStdString ( std::string ( m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd ) ); + a_sTok = QString().fromStdString ( std::string ( m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd ) ); #endif - } + } - return iEnd; + return iEnd; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check Expression for the presence of a binary operator token. * @@ -367,38 +402,39 @@ int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_ int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) const { #if defined(_UNICODE) - const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); - const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString(); + const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); + const std::wstring oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdWString(); #else - const std::string m_strFormulaStd = m_strFormula.toStdString(); - const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); + const std::string m_strFormulaStd = m_strFormula.toStdString(); + const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString(); #endif - int iEnd = static_cast( m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ) ); - if ( iEnd == static_cast( string_type::npos ) ) - { - iEnd = static_cast( m_strFormulaStd.length() ); - } + int iEnd = static_cast( m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ) ); + if ( iEnd == static_cast( string_type::npos ) ) + { + iEnd = static_cast( m_strFormulaStd.length() ); + } - // Assign token string if there was something found - if ( a_iPos != iEnd ) - { + // Assign token string if there was something found + if ( a_iPos != iEnd ) + { #if defined(_UNICODE) - a_sTok = QString().fromStdWString ( string_type ( m_strFormulaStd.begin() + a_iPos, - m_strFormulaStd.begin() + iEnd ) ); + a_sTok = QString().fromStdWString ( string_type ( m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd ) ); #else - a_sTok = QString().fromStdString ( string_type ( m_strFormulaStd.begin() + a_iPos, m_strFormulaStd.begin() + iEnd ) ); + a_sTok = QString().fromStdString ( string_type ( m_strFormulaStd.begin() + a_iPos, + m_strFormulaStd.begin() + iEnd ) ); #endif - return iEnd; - } - else - { - // There is still the chance of having to deal with an operator consisting exclusively - // of alphabetic characters. - return ExtractToken ( QMUP_CHARS, a_sTok, a_iPos ); - } + return iEnd; + } + else + { + // There is still the chance of having to deal with an operator consisting exclusively + // of alphabetic characters. + return ExtractToken ( QMUP_CHARS, a_sTok, a_iPos ); + } } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check if a built in operator or other token can be found * @param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. @@ -406,131 +442,152 @@ int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) c */ bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok ) { - const QStringList pOprtDef = m_pParser->GetOprtDef(); + const QStringList pOprtDef = m_pParser->GetOprtDef(); - // Compare token with function and operator strings - // check string for operator/function - for ( int i = 0; i < pOprtDef.size(); ++i ) - { - int len = pOprtDef.at ( i ).length(); - if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, m_iPos + len ) ) - { - switch ( i ) - { - //case cmAND: - //case cmOR: - //case cmXOR: - case cmLAND: - case cmLOR: - case cmLT: - case cmGT: - case cmLE: - case cmGE: - case cmNEQ: - case cmEQ: - case cmADD: - case cmSUB: - case cmMUL: - case cmDIV: - case cmPOW: - case cmASSIGN: - //if (len!=sTok.length()) - // continue; + // Compare token with function and operator strings + // check string for operator/function + for ( int i = 0; i < pOprtDef.size(); ++i ) + { + int len = pOprtDef.at ( i ).length(); + if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, m_iPos + len ) ) + { + switch ( i ) + { + //case cmAND: + //case cmOR: + //case cmXOR: + case cmLAND: + case cmLOR: + case cmLT: + case cmGT: + case cmLE: + case cmGE: + case cmNEQ: + case cmEQ: + case cmADD: + case cmSUB: + case cmMUL: + case cmDIV: + case cmPOW: + case cmASSIGN: + //if (len!=sTok.length()) + // continue; - // The assignement operator need special treatment - if ( i == cmASSIGN && m_iSynFlags & noASSIGN ) - Error ( ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at ( i ) ); + // The assignement operator need special treatment + if ( i == cmASSIGN && m_iSynFlags & noASSIGN ) + { + Error ( ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at ( i ) ); + } - if ( !m_pParser->HasBuiltInOprt() ) continue; - if ( m_iSynFlags & noOPT ) - { - // Maybe its an infix operator not an operator - // Both operator types can share characters in - // their identifiers - if ( IsInfixOpTok ( a_Tok ) ) - return true; + if ( m_pParser->HasBuiltInOprt() == false) + { + continue; + } + if ( m_iSynFlags & noOPT ) + { + // Maybe its an infix operator not an operator + // Both operator types can share characters in + // their identifiers + if ( IsInfixOpTok ( a_Tok ) ) + { + return true; + } - Error ( ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at ( i ) ); - } + Error ( ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef.at ( i ) ); + } - m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; - m_iSynFlags |= ( ( i != cmEND ) && ( i != cmBC ) ) ? noEND : 0; - break; + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + m_iSynFlags |= ( ( i != cmEND ) && ( i != cmBC ) ) ? noEND : 0; + break; - case cmBO: - if ( m_iSynFlags & noBO ) - Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + case cmBO: + if ( m_iSynFlags & noBO ) + { + Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + } - if ( m_lastTok.GetCode() == cmFUNC ) - m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; - else - m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + if ( m_lastTok.GetCode() == cmFUNC ) + { + m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + } + else + { + m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE; + } - ++m_iBrackets; - break; + ++m_iBrackets; + break; - case cmBC: - if ( m_iSynFlags & noBC ) - Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + case cmBC: + if ( m_iSynFlags & noBC ) + { + Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + } - m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; + m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN; - if ( --m_iBrackets < 0 ) - Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); - break; + if ( --m_iBrackets < 0 ) + { + Error ( ecUNEXPECTED_PARENS, m_iPos, pOprtDef.at ( i ) ); + } + break; - case cmELSE: - if ( m_iSynFlags & noELSE ) - Error ( ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at ( i ) ); + case cmELSE: + if ( m_iSynFlags & noELSE ) + { + Error ( ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at ( i ) ); + } - m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; - break; + m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; + break; - case cmIF: - if ( m_iSynFlags & noIF ) - Error ( ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at ( i ) ); + case cmIF: + if ( m_iSynFlags & noIF ) + { + Error ( ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef.at ( i ) ); + } - m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; - break; + m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE; + break; - default: // The operator is listed in c_DefaultOprt, but not here. This is a bad thing... - Error ( ecINTERNAL_ERROR ); - } // switch operator id + default: // The operator is listed in c_DefaultOprt, but not here. This is a bad thing... + Error ( ecINTERNAL_ERROR ); + } // switch operator id - m_iPos += len; - a_Tok.Set ( static_cast(i), pOprtDef.at ( i ) ); - return true; - } // if operator string found - } // end of for all operator strings + m_iPos += len; + a_Tok.Set ( static_cast(i), pOprtDef.at ( i ) ); + return true; + } // if operator string found + } // end of for all operator strings - return false; + return false; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok ) { - if ( m_strFormula.at ( m_iPos ) == m_cArgSep ) - { - // copy the separator into null terminated string - QString szSep; - szSep[0] = m_cArgSep; - szSep[1] = 0; + if ( m_strFormula.at ( m_iPos ) == m_cArgSep ) + { + // copy the separator into null terminated string + QString szSep; + szSep[0] = m_cArgSep; + szSep[1] = 0; - if ( m_iSynFlags & noARG_SEP ) - { - Error ( ecUNEXPECTED_ARG_SEP, m_iPos, szSep ); - } + if ( m_iSynFlags & noARG_SEP ) + { + Error ( ecUNEXPECTED_ARG_SEP, m_iPos, szSep ); + } - m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; - m_iPos++; - a_Tok.Set ( cmARG_SEP, szSep ); - return true; - } + m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN; + m_iPos++; + a_Tok.Set ( cmARG_SEP, szSep ); + return true; + } - return false; + return false; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check for End of Formula. * @@ -542,72 +599,82 @@ bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok ) bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) { #if defined(_UNICODE) - const char_type* szFormula = m_strFormula.toStdWString().c_str(); + const char_type* szFormula = m_strFormula.toStdWString().c_str(); #else - const char_type* szFormula = m_strFormula.toStdString().c_str(); + const char_type* szFormula = m_strFormula.toStdString().c_str(); #endif - // check for EOF - if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/ ) - { - if ( m_iSynFlags & noEND ) - Error ( ecUNEXPECTED_EOF, m_iPos ); + // check for EOF + if ( szFormula[m_iPos] == false /*|| szFormula[m_iPos] == '\n'*/ ) + { + if ( m_iSynFlags & noEND ) + { + Error ( ecUNEXPECTED_EOF, m_iPos ); + } - if ( m_iBrackets > 0 ) - Error ( ecMISSING_PARENS, m_iPos, ")" ); + if ( m_iBrackets > 0 ) + { + Error ( ecMISSING_PARENS, m_iPos, ")" ); + } - m_iSynFlags = 0; - a_Tok.Set ( cmEND ); - return true; - } + m_iSynFlags = 0; + a_Tok.Set ( cmEND ); + return true; + } - return false; + return false; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check if a string position contains a unary infix operator. * @return true if a function token has been found false otherwise. */ bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok ) { - QString sTok; - int iEnd = ExtractToken ( m_pParser->ValidInfixOprtChars(), sTok, m_iPos ); - if ( iEnd == m_iPos ) - return false; + QString sTok; + int iEnd = ExtractToken ( m_pParser->ValidInfixOprtChars(), sTok, m_iPos ); + if ( iEnd == m_iPos ) + { + return false; + } - // iteraterate over all postfix operator strings - funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); - for ( ; it != m_pInfixOprtDef->rend(); ++it ) - { - if ( sTok.indexOf ( it->first ) != 0 ) - continue; + // iteraterate over all postfix operator strings + funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); + for ( ; it != m_pInfixOprtDef->rend(); ++it ) + { + if ( sTok.indexOf ( it->first ) != 0 ) + { + continue; + } - a_Tok.Set ( it->second, it->first ); - m_iPos += static_cast(it->first.length()); + a_Tok.Set ( it->second, it->first ); + m_iPos += static_cast(it->first.length()); - if ( m_iSynFlags & noINFIXOP ) - Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() ); + if ( m_iSynFlags & noINFIXOP ) + { + Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() ); + } - m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; - return true; - } + m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; + return true; + } - return false; + return false; - /* - a_Tok.Set(item->second, sTok); - m_iPos = (int)iEnd; + /* + a_Tok.Set(item->second, sTok); + m_iPos = (int)iEnd; - if (m_iSynFlags & noINFIXOP) - Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + if (m_iSynFlags & noINFIXOP) + Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); - m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; - return true; - */ + m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; + return true; + */ } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check whether the token at a given position is a function token. * @param a_Tok [out] If a value token is found it will be placed here. @@ -617,30 +684,38 @@ bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok ) { - QString strTok; - int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); - if ( iEnd == m_iPos ) - return false; + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd == m_iPos ) + { + return false; + } - funmap_type::const_iterator item = m_pFunDef->find ( strTok ); - if ( item == m_pFunDef->end() ) - return false; + funmap_type::const_iterator item = m_pFunDef->find ( strTok ); + if ( item == m_pFunDef->end() ) + { + return false; + } - // Check if the next sign is an opening bracket - if ( m_strFormula.at ( iEnd ) != '(' ) - return false; + // Check if the next sign is an opening bracket + if ( m_strFormula.at ( iEnd ) != '(' ) + { + return false; + } - a_Tok.Set ( item->second, strTok ); + a_Tok.Set ( item->second, strTok ); - m_iPos = iEnd; - if ( m_iSynFlags & noFUN ) - Error ( ecUNEXPECTED_FUN, m_iPos - static_cast(a_Tok.GetAsString().length()), a_Tok.GetAsString() ); + m_iPos = iEnd; + if ( m_iSynFlags & noFUN ) + { + Error ( ecUNEXPECTED_FUN, m_iPos - static_cast(a_Tok.GetAsString().length()), a_Tok.GetAsString() ); + } - m_iSynFlags = noANY ^ noBO; - return true; + m_iSynFlags = noANY ^ noBO; + return true; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check if a string position contains a binary operator. * @param a_Tok [out] Operator token if one is found. This can either be a binary operator or an infix operator token. @@ -648,112 +723,124 @@ bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) { - QString strTok; + QString strTok; - int iEnd = ExtractOperatorToken ( strTok, m_iPos ); - if ( iEnd == m_iPos ) - return false; + int iEnd = ExtractOperatorToken ( strTok, m_iPos ); + if ( iEnd == m_iPos ) + { + return false; + } - // Check if the operator is a built in operator, if so ignore it here - const QStringList pOprtDef = m_pParser->GetOprtDef(); - QStringList::const_iterator constIterator; - for ( constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd(); - ++constIterator ) - { - if ( ( *constIterator ) == strTok ) - return false; - } + // Check if the operator is a built in operator, if so ignore it here + const QStringList pOprtDef = m_pParser->GetOprtDef(); + QStringList::const_iterator constIterator; + for ( constIterator = pOprtDef.constBegin(); m_pParser->HasBuiltInOprt() && constIterator != pOprtDef.constEnd(); + ++constIterator ) + { + if ( ( *constIterator ) == strTok ) + { + return false; + } + } - // Note: - // All tokens in oprt_bin_maptype are have been sorted by their length - // Long operators must come first! Otherwise short names (like: "add") that - // are part of long token names (like: "add123") will be found instead - // of the long ones. - // Length sorting is done with ascending length so we use a reverse iterator here. - funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); - for ( ; it != m_pOprtDef->rend(); ++it ) - { - const QString &sID = it->first; - if ( sID == m_strFormula.mid ( m_iPos, m_iPos + sID.length() ) ) - { - a_Tok.Set ( it->second, strTok ); + // Note: + // All tokens in oprt_bin_maptype are have been sorted by their length + // Long operators must come first! Otherwise short names (like: "add") that + // are part of long token names (like: "add123") will be found instead + // of the long ones. + // Length sorting is done with ascending length so we use a reverse iterator here. + funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); + for ( ; it != m_pOprtDef->rend(); ++it ) + { + const QString &sID = it->first; + if ( sID == m_strFormula.mid ( m_iPos, m_iPos + sID.length() ) ) + { + a_Tok.Set ( it->second, strTok ); - // operator was found - if ( m_iSynFlags & noOPT ) - { - // An operator was found but is not expected to occur at - // this position of the formula, maybe it is an infix - // operator, not a binary operator. Both operator types - // can share characters in their identifiers. - if ( IsInfixOpTok ( a_Tok ) ) - return true; - else - { - // nope, no infix operator - return false; - //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); - } + // operator was found + if ( m_iSynFlags & noOPT ) + { + // An operator was found but is not expected to occur at + // this position of the formula, maybe it is an infix + // operator, not a binary operator. Both operator types + // can share characters in their identifiers. + if ( IsInfixOpTok ( a_Tok ) ) + { + return true; + } + else + { + // nope, no infix operator + return false; + //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); + } - } + } - m_iPos += sID.length(); - m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; - return true; - } - } + m_iPos += sID.length(); + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; + return true; + } + } - return false; + return false; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check if a string position contains a unary post value operator. */ bool QmuParserTokenReader::IsPostOpTok ( token_type &a_Tok ) { - // Do not check for postfix operators if they are not allowed at - // the current expression index. - // - // This will fix the bug reported here: - // - // http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979 - // - if ( m_iSynFlags & noPOSTOP ) - return false; - // + // Do not check for postfix operators if they are not allowed at + // the current expression index. + // + // This will fix the bug reported here: + // + // http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979 + // + if ( m_iSynFlags & noPOSTOP ) + { + return false; + } + // - // Tricky problem with equations like "3m+5": - // m is a postfix operator, + is a valid sign for postfix operators and - // for binary operators parser detects "m+" as operator string and - // finds no matching postfix operator. - // - // This is a special case so this routine slightly differs from the other - // token readers. + // Tricky problem with equations like "3m+5": + // m is a postfix operator, + is a valid sign for postfix operators and + // for binary operators parser detects "m+" as operator string and + // finds no matching postfix operator. + // + // This is a special case so this routine slightly differs from the other + // token readers. - // Test if there could be a postfix operator - QString sTok; - int iEnd = ExtractToken ( m_pParser->ValidOprtChars(), sTok, m_iPos ); - if ( iEnd == m_iPos ) - return false; + // Test if there could be a postfix operator + QString sTok; + int iEnd = ExtractToken ( m_pParser->ValidOprtChars(), sTok, m_iPos ); + if ( iEnd == m_iPos ) + { + return false; + } - // iteraterate over all postfix operator strings - funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); - for ( ; it != m_pPostOprtDef->rend(); ++it ) - { - if ( sTok.indexOf ( it->first ) != 0 ) - continue; + // iteraterate over all postfix operator strings + funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); + for ( ; it != m_pPostOprtDef->rend(); ++it ) + { + if ( sTok.indexOf ( it->first ) != 0 ) + { + continue; + } - a_Tok.Set ( it->second, sTok ); - m_iPos += it->first.length(); + a_Tok.Set ( it->second, sTok ); + m_iPos += it->first.length(); - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; - return true; - } + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN; + return true; + } - return false; + return false; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check whether the token at a given position is a value token. * @@ -764,54 +851,58 @@ bool QmuParserTokenReader::IsPostOpTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) { - assert ( m_pConstDef ); - assert ( m_pParser ); + assert ( m_pConstDef ); + assert ( m_pParser ); - QString strTok; - qreal fVal ( 0 ); - int iEnd ( 0 ); + QString strTok; + qreal fVal ( 0 ); + int iEnd ( 0 ); - // 2.) Check for user defined constant - // Read everything that could be a constant name - iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); - if ( iEnd != m_iPos ) - { - valmap_type::const_iterator item = m_pConstDef->find ( strTok ); - if ( item != m_pConstDef->end() ) - { - m_iPos = iEnd; - a_Tok.SetVal ( item->second, strTok ); + // 2.) Check for user defined constant + // Read everything that could be a constant name + iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd != m_iPos ) + { + valmap_type::const_iterator item = m_pConstDef->find ( strTok ); + if ( item != m_pConstDef->end() ) + { + m_iPos = iEnd; + a_Tok.SetVal ( item->second, strTok ); - if ( m_iSynFlags & noVAL ) - Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); + if ( m_iSynFlags & noVAL ) + { + Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); + } - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; - return true; - } - } + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + } - // 3.call the value recognition functions provided by the user - // Call user defined value recognition functions - std::list::const_iterator item = m_vIdentFun.begin(); - for ( item = m_vIdentFun.begin(); item != m_vIdentFun.end(); ++item ) - { - int iStart = m_iPos; - if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 ) - { - strTok = m_strFormula.mid ( iStart, m_iPos ); - if ( m_iSynFlags & noVAL ) - Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); + // 3.call the value recognition functions provided by the user + // Call user defined value recognition functions + std::list::const_iterator item = m_vIdentFun.begin(); + for ( item = m_vIdentFun.begin(); item != m_vIdentFun.end(); ++item ) + { + int iStart = m_iPos; + if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 ) + { + strTok = m_strFormula.mid ( iStart, m_iPos ); + if ( m_iSynFlags & noVAL ) + { + Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); + } - a_Tok.SetVal ( fVal, strTok ); - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; - return true; - } - } + a_Tok.SetVal ( fVal, strTok ); + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; + return true; + } + } - return false; + return false; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check wheter a token at a given position is a variable token. * @param a_Tok [out] If a variable token has been found it will be placed here. @@ -819,64 +910,82 @@ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok ) { - if ( !m_pVarDef->size() ) - return false; + if ( m_pVarDef->size() == false) + { + return false; + } - QString strTok; - int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); - if ( iEnd == m_iPos ) - return false; + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd == m_iPos ) + { + return false; + } - varmap_type::const_iterator item = m_pVarDef->find ( strTok ); - if ( item == m_pVarDef->end() ) - return false; + varmap_type::const_iterator item = m_pVarDef->find ( strTok ); + if ( item == m_pVarDef->end() ) + { + return false; + } - if ( m_iSynFlags & noVAR ) - Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); + if ( m_iSynFlags & noVAR ) + { + Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); + } - m_pParser->OnDetectVar ( m_strFormula, m_iPos, iEnd ); + m_pParser->OnDetectVar ( m_strFormula, m_iPos, iEnd ); - m_iPos = iEnd; - a_Tok.SetVar ( item->second, strTok ); - m_UsedVar[item->first] = item->second; // Add variable to used-var-list + m_iPos = iEnd; + a_Tok.SetVar ( item->second, strTok ); + m_UsedVar[item->first] = item->second; // Add variable to used-var-list - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR; + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR; // Zur Info hier die SynFlags von IsVal(): // m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; - return true; + return true; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- bool QmuParserTokenReader::IsStrVarTok ( token_type &a_Tok ) { - if ( !m_pStrVarDef || !m_pStrVarDef->size() ) - return false; + if ( m_pStrVarDef == false || m_pStrVarDef->size() == false) + { + return false; + } - QString strTok; - int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); - if ( iEnd == m_iPos ) - return false; + QString strTok; + int iEnd = ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ); + if ( iEnd == m_iPos ) + { + return false; + } - strmap_type::const_iterator item = m_pStrVarDef->find ( strTok ); - if ( item == m_pStrVarDef->end() ) - return false; + strmap_type::const_iterator item = m_pStrVarDef->find ( strTok ); + if ( item == m_pStrVarDef->end() ) + { + return false; + } - if ( m_iSynFlags & noSTR ) - Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); + if ( m_iSynFlags & noSTR ) + { + Error ( ecUNEXPECTED_VAR, m_iPos, strTok ); + } - m_iPos = iEnd; - if ( !m_pParser->m_vStringVarBuf.size() ) - Error ( ecINTERNAL_ERROR ); + m_iPos = iEnd; + if ( m_pParser->m_vStringVarBuf.size() == false) + { + Error ( ecINTERNAL_ERROR ); + } - a_Tok.SetString ( m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() ); + a_Tok.SetString ( m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() ); - m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP ); - return true; + m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP ); + return true; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check wheter a token at a given position is an undefined variable. * @@ -886,52 +995,52 @@ bool QmuParserTokenReader::IsStrVarTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) { - QString strTok; - int iEnd ( ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ) ); - if ( iEnd == m_iPos ) - { - return false; - } + QString strTok; + int iEnd ( ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ) ); + if ( iEnd == m_iPos ) + { + return false; + } - if ( m_iSynFlags & noVAR ) - { - // 20061021 added token string strTok instead of a_Tok.GetAsString() as the - // token identifier. - // related bug report: - // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 - Error ( ecUNEXPECTED_VAR, m_iPos - a_Tok.GetAsString().length(), strTok ); - } + if ( m_iSynFlags & noVAR ) + { + // 20061021 added token string strTok instead of a_Tok.GetAsString() as the + // token identifier. + // related bug report: + // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979 + Error ( ecUNEXPECTED_VAR, m_iPos - a_Tok.GetAsString().length(), strTok ); + } - // If a factory is available implicitely create new variables - if ( m_pFactory ) - { - qreal *fVar = m_pFactory ( strTok, m_pFactoryData ); - a_Tok.SetVar ( fVar, strTok ); + // If a factory is available implicitely create new variables + if ( m_pFactory ) + { + qreal *fVar = m_pFactory ( strTok, m_pFactoryData ); + a_Tok.SetVar ( fVar, strTok ); - // Do not use m_pParser->DefineVar( strTok, fVar ); - // in order to define the new variable, it will clear the - // m_UsedVar array which will kill previousely defined variables - // from the list - // This is safe because the new variable can never override an existing one - // because they are checked first! - ( *m_pVarDef ) [strTok] = fVar; - m_UsedVar[strTok] = fVar; // Add variable to used-var-list - } - else - { - a_Tok.SetVar ( &m_fZero, strTok ); - m_UsedVar[strTok] = 0; // Add variable to used-var-list - } + // Do not use m_pParser->DefineVar( strTok, fVar ); + // in order to define the new variable, it will clear the + // m_UsedVar array which will kill previousely defined variables + // from the list + // This is safe because the new variable can never override an existing one + // because they are checked first! + ( *m_pVarDef ) [strTok] = fVar; + m_UsedVar[strTok] = fVar; // Add variable to used-var-list + } + else + { + a_Tok.SetVar ( &m_fZero, strTok ); + m_UsedVar[strTok] = 0; // Add variable to used-var-list + } - m_iPos = iEnd; + m_iPos = iEnd; - // Call the variable factory in order to let it define a new parser variable - m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR; - return true; + // Call the variable factory in order to let it define a new parser variable + m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR; + return true; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Check wheter a token at a given position is a string. * @param a_Tok [out] If a variable token has been found it will be placed here. @@ -941,38 +1050,47 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsString ( token_type &a_Tok ) { - if ( m_strFormula[m_iPos] != '"' ) - return false; + if ( m_strFormula[m_iPos] != '"' ) + { + return false; + } - QString strBuf ( m_strFormula[m_iPos + 1] ); - int iEnd ( 0 ), iSkip ( 0 ); + QString strBuf ( m_strFormula[m_iPos + 1] ); + int iEnd ( 0 ), iSkip ( 0 ); - // parser over escaped '\"' end replace them with '"' - for ( iEnd = strBuf.indexOf ( "\"" ); iEnd != 0 && iEnd != -1; iEnd = strBuf.indexOf ( "\"", iEnd ) ) - { - if ( strBuf[iEnd - 1] != '\\' ) break; - strBuf.replace ( iEnd - 1, 2, "\"" ); - iSkip++; - } + // parser over escaped '\"' end replace them with '"' + for ( iEnd = strBuf.indexOf ( "\"" ); iEnd != 0 && iEnd != -1; iEnd = strBuf.indexOf ( "\"", iEnd ) ) + { + if ( strBuf[iEnd - 1] != '\\' ) + { + break; + } + strBuf.replace ( iEnd - 1, 2, "\"" ); + iSkip++; + } - if ( iEnd == -1 ) - Error ( ecUNTERMINATED_STRING, m_iPos, "\"" ); + if ( iEnd == -1 ) + { + Error ( ecUNTERMINATED_STRING, m_iPos, "\"" ); + } - QString strTok = strBuf.mid ( 0, iEnd ); + QString strTok = strBuf.mid ( 0, iEnd ); - if ( m_iSynFlags & noSTR ) - Error ( ecUNEXPECTED_STR, m_iPos, strTok ); + if ( m_iSynFlags & noSTR ) + { + Error ( ecUNEXPECTED_STR, m_iPos, strTok ); + } - m_pParser->m_vStringBuf.push_back ( strTok ); // Store string in internal buffer - a_Tok.SetString ( strTok, m_pParser->m_vStringBuf.size() ); + m_pParser->m_vStringBuf.push_back ( strTok ); // Store string in internal buffer + a_Tok.SetString ( strTok, m_pParser->m_vStringBuf.size() ); - m_iPos += strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen - m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); + m_iPos += strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen + m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND ); - return true; + return true; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- /** * @brief Create an error containing the parse error position. * @@ -985,19 +1103,18 @@ bool QmuParserTokenReader::IsString ( token_type &a_Tok ) */ void QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const { - m_pParser->Error ( a_iErrc, a_iPos, a_sTok ); + m_pParser->Error ( a_iErrc, a_iPos, a_sTok ); } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void QmuParserTokenReader::SetArgSep ( char_type cArgSep ) { - m_cArgSep = cArgSep; + m_cArgSep = cArgSep; } -//---------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- QChar QmuParserTokenReader::GetArgSep() const { - return m_cArgSep; + return m_cArgSep; } } // namespace qmu - diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 8abf62de6..8bf7a3efc 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -1,156 +1,154 @@ -/*************************************************************************************************** - ** - ** Original work Copyright (C) 2013 Ingo Berg - ** Modified work Copyright 2014 Roman Telezhynskyi - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy of this - ** software and associated documentation files (the "Software"), to deal in the Software - ** without restriction, including without limitation the rights to use, copy, modify, - ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - ** permit persons to whom the Software is furnished to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all copies or - ** substantial portions of the Software. - ** - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ** - ******************************************************************************************************/ - -#ifndef QMUPARSERTOKENREADER_H -#define QMUPARSERTOKENREADER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qmuparserdef.h" -#include "qmuparsertoken.h" - -/** @file - @brief This file contains the parser token reader definition. -*/ - - -namespace qmu -{ - // Forward declaration - class QmuParserBase; - - /** @brief Token reader for the ParserBase class. - - */ - class QmuParserTokenReader - { - private: - - typedef QmuParserToken token_type; - - public: - - QmuParserTokenReader(QmuParserBase *a_pParent); - QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const; - - void AddValIdent(identfun_type a_pCallback); - void SetVarCreator(facfun_type a_pFactory, void *pUserData); - void SetFormula(const QString &a_strFormula); - void SetArgSep(char_type cArgSep); - - int GetPos() const; - const QString &GetExpr() const; - varmap_type& GetUsedVar(); - QChar GetArgSep() const; - - void IgnoreUndefVar(bool bIgnore); - void ReInit(); - token_type ReadNextToken(); - - private: - - /** @brief Syntax codes. - - The syntax codes control the syntax check done during the first time parsing of - the expression string. They are flags that indicate which tokens are allowed next - if certain tokens are identified. - */ - enum ESynCodes - { - noBO = 1 << 0, ///< to avoid i.e. "cos(7)(" - noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()" - noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14" - noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a" - noARG_SEP = 1 << 4, ///< to avoid i.e. ",," or "+," ... - noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin" - noOPT = 1 << 6, ///< to avoid i.e. "(+)" - noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!" - noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4" - noEND = 1 << 9, ///< to avoid unexpected end of formula - noSTR = 1 << 10, ///< to block numeric arguments on string functions - noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7" - noIF = 1 << 12, - noELSE = 1 << 13, - sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP, - noANY = ~0 ///< All of he above flags set - }; - - QmuParserTokenReader(const QmuParserTokenReader &a_Reader); - QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader); - void Assign(const QmuParserTokenReader &a_Reader); - - void SetParent(QmuParserBase *a_pParent); - int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const; - int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; - - bool IsBuiltIn(token_type &a_Tok); - bool IsArgSep(token_type &a_Tok); - bool IsEOF(token_type &a_Tok); - bool IsInfixOpTok(token_type &a_Tok); - bool IsFunTok(token_type &a_Tok); - bool IsPostOpTok(token_type &a_Tok); - bool IsOprt(token_type &a_Tok); - bool IsValTok(token_type &a_Tok); - bool IsVarTok(token_type &a_Tok); - bool IsStrVarTok(token_type &a_Tok); - bool IsUndefVarTok(token_type &a_Tok); - bool IsString(token_type &a_Tok); - void Error(EErrorCodes a_iErrc, - int a_iPos = -1, - const QString &a_sTok = QString() ) const; - - token_type& SaveBeforeReturn(const token_type &tok); - - QmuParserBase *m_pParser; - QString m_strFormula; - int m_iPos; - int m_iSynFlags; - bool m_bIgnoreUndefVar; - - const funmap_type *m_pFunDef; - const funmap_type *m_pPostOprtDef; - const funmap_type *m_pInfixOprtDef; - const funmap_type *m_pOprtDef; - const valmap_type *m_pConstDef; - const strmap_type *m_pStrVarDef; - varmap_type *m_pVarDef; ///< The only non const pointer to parser internals - facfun_type m_pFactory; - void *m_pFactoryData; - std::list m_vIdentFun; ///< Value token identification function - varmap_type m_UsedVar; - qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables - int m_iBrackets; - token_type m_lastTok; - QChar m_cArgSep; ///< The character used for separating function arguments - }; -} // namespace qmu - -#endif - - +/*************************************************************************************************** + ** + ** Original work Copyright (C) 2013 Ingo Berg + ** Modified work Copyright 2014 Roman Telezhynskyi + ** + ** Permission is hereby granted, free of charge, to any person obtaining a copy of this + ** software and associated documentation files (the "Software"), to deal in the Software + ** without restriction, including without limitation the rights to use, copy, modify, + ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + ** permit persons to whom the Software is furnished to do so, subject to the following conditions: + ** + ** The above copyright notice and this permission notice shall be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ** + ******************************************************************************************************/ + +#ifndef QMUPARSERTOKENREADER_H +#define QMUPARSERTOKENREADER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qmuparserdef.h" +#include "qmuparsertoken.h" + +/** @file + @brief This file contains the parser token reader definition. +*/ + + +namespace qmu +{ + // Forward declaration + class QmuParserBase; + + /** @brief Token reader for the ParserBase class. + + */ + class QmuParserTokenReader + { + private: + + typedef QmuParserToken token_type; + + public: + + QmuParserTokenReader(QmuParserBase *a_pParent); + QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const; + + void AddValIdent(identfun_type a_pCallback); + void SetVarCreator(facfun_type a_pFactory, void *pUserData); + void SetFormula(const QString &a_strFormula); + void SetArgSep(char_type cArgSep); + + int GetPos() const; + const QString &GetExpr() const; + varmap_type& GetUsedVar(); + QChar GetArgSep() const; + + void IgnoreUndefVar(bool bIgnore); + void ReInit(); + token_type ReadNextToken(); + + private: + /** + * @brief Syntax codes. + * + * The syntax codes control the syntax check done during the first time parsing of + * the expression string. They are flags that indicate which tokens are allowed next + * if certain tokens are identified. + */ + enum ESynCodes + { + noBO = 1 << 0, ///< to avoid i.e. "cos(7)(" + noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()" + noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14" + noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a" + noARG_SEP = 1 << 4, ///< to avoid i.e. ",," or "+," ... + noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin" + noOPT = 1 << 6, ///< to avoid i.e. "(+)" + noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!" + noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4" + noEND = 1 << 9, ///< to avoid unexpected end of formula + noSTR = 1 << 10, ///< to block numeric arguments on string functions + noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7" + noIF = 1 << 12, + noELSE = 1 << 13, + sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP, + noANY = ~0 ///< All of he above flags set + }; + + QmuParserTokenReader(const QmuParserTokenReader &a_Reader); + QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader); + void Assign(const QmuParserTokenReader &a_Reader); + + void SetParent(QmuParserBase *a_pParent); + int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const; + int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; + + bool IsBuiltIn(token_type &a_Tok); + bool IsArgSep(token_type &a_Tok); + bool IsEOF(token_type &a_Tok); + bool IsInfixOpTok(token_type &a_Tok); + bool IsFunTok(token_type &a_Tok); + bool IsPostOpTok(token_type &a_Tok); + bool IsOprt(token_type &a_Tok); + bool IsValTok(token_type &a_Tok); + bool IsVarTok(token_type &a_Tok); + bool IsStrVarTok(token_type &a_Tok); + bool IsUndefVarTok(token_type &a_Tok); + bool IsString(token_type &a_Tok); + void Error(EErrorCodes a_iErrc, + int a_iPos = -1, + const QString &a_sTok = QString() ) const; + + token_type& SaveBeforeReturn(const token_type &tok); + + QmuParserBase *m_pParser; + QString m_strFormula; + int m_iPos; + int m_iSynFlags; + bool m_bIgnoreUndefVar; + + const funmap_type *m_pFunDef; + const funmap_type *m_pPostOprtDef; + const funmap_type *m_pInfixOprtDef; + const funmap_type *m_pOprtDef; + const valmap_type *m_pConstDef; + const strmap_type *m_pStrVarDef; + varmap_type *m_pVarDef; ///< The only non const pointer to parser internals + facfun_type m_pFactory; + void *m_pFactoryData; + std::list m_vIdentFun; ///< Value token identification function + varmap_type m_UsedVar; + qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables + int m_iBrackets; + token_type m_lastTok; + QChar m_cArgSep; ///< The character used for separating function arguments + }; +} // namespace qmu + +#endif From 79ef0e914e28127a03f4adcf16347997733a8c77 Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 2 May 2014 11:09:10 +0300 Subject: [PATCH 18/26] CppCheck. --HG-- branch : feature --- src/app/container/vcontainer.cpp | 1 + src/app/tools/drawTools/vabstractspline.cpp | 2 ++ src/libs/qmuparser/qmuparser.cpp | 1 + src/libs/qmuparser/qmuparserbase.cpp | 32 ++++++++++++----- src/libs/qmuparser/qmuparserbase.h | 6 ++-- src/libs/qmuparser/qmuparserbytecode.cpp | 5 +++ src/libs/qmuparser/qmuparserbytecode.h | 38 ++++++++++----------- src/libs/qmuparser/qmuparsercallback.cpp | 3 +- src/libs/qmuparser/qmuparsererror.cpp | 6 ++-- src/libs/qmuparser/qmuparsererror.h | 2 +- src/libs/qmuparser/qmuparsertest.cpp | 4 ++- src/libs/qmuparser/qmuparsertest.h | 21 +++++++++--- src/libs/qmuparser/qmuparsertokenreader.cpp | 5 ++- 13 files changed, 86 insertions(+), 40 deletions(-) diff --git a/src/app/container/vcontainer.cpp b/src/app/container/vcontainer.cpp index e3d954f42..d8c0f4ca8 100644 --- a/src/app/container/vcontainer.cpp +++ b/src/app/container/vcontainer.cpp @@ -106,6 +106,7 @@ void VContainer::setData(const VContainer &data) details = *data.DataDetails(); } +// cppcheck-suppress unusedFunction const VGObject *VContainer::GetGObject(quint32 id)const { return GetObject(gObjects, id); diff --git a/src/app/tools/drawTools/vabstractspline.cpp b/src/app/tools/drawTools/vabstractspline.cpp index 3f4ce2cdc..9ca601d57 100644 --- a/src/app/tools/drawTools/vabstractspline.cpp +++ b/src/app/tools/drawTools/vabstractspline.cpp @@ -73,12 +73,14 @@ void VAbstractSpline::SetFactor(qreal factor) RefreshGeometry(); } +// cppcheck-suppress unusedFunction void VAbstractSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine())/factor)); } +// cppcheck-suppress unusedFunction void VAbstractSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 09919f9c4..96fc7b9c7 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -372,6 +372,7 @@ void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) * * http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 */ +// cppcheck-suppress unusedFunction qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const { qreal fRes(0), diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 3b29c6396..14b3487f7 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -153,6 +153,7 @@ void QmuParserBase::Assign(const QmuParserBase &a_Parser) * By default muparser uses the "C" locale. The decimal separator of this * locale is overwritten by the one provided here. */ +// cppcheck-suppress unusedFunction void QmuParserBase::SetDecSep(char_type cDecSep) { char_type cThousandsSep = std::use_facet< change_dec_sep >(s_locale).thousands_sep(); @@ -168,6 +169,7 @@ void QmuParserBase::SetDecSep(char_type cDecSep) * By default muparser uses the "C" locale. The thousands separator of this * locale is overwritten by the one provided here. */ +// cppcheck-suppress unusedFunction void QmuParserBase::SetThousandsSep(char_type cThousandsSep) { char_type cDecSep = std::use_facet< change_dec_sep >(s_locale).decimal_point(); @@ -180,6 +182,7 @@ void QmuParserBase::SetThousandsSep(char_type cThousandsSep) * * The default locale used "." as decimal separator, no thousands separator and "," as function argument separator. */ +// cppcheck-suppress unusedFunction void QmuParserBase::ResetLocale() { s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); @@ -231,7 +234,8 @@ void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) * * Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS are returned only if eInfo==pviFULL. */ -QString QmuParserBase::GetVersion(EParserVersionInfo eInfo) const +// cppcheck-suppress unusedFunction +QString QmuParserBase::GetVersion(EParserVersionInfo eInfo) { QString versionInfo; QTextStream ss(&versionInfo); @@ -294,6 +298,7 @@ void QmuParserBase::AddValIdent(identfun_type a_pCallback) * @param a_pFactory A pointer to the variable factory. * @param pUserData A user defined context pointer. */ +// cppcheck-suppress unusedFunction void QmuParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData) { m_pTokenReader->SetVarCreator(a_pFactory, pUserData); @@ -529,7 +534,7 @@ void QmuParserBase::SetExpr(const QString &a_sExpr) * @brief Get the default symbols used for the built in operators. * @sa c_DefaultOprt */ -const QStringList &QmuParserBase::GetOprtDef() const +const QStringList &QmuParserBase::GetOprtDef() { return c_DefaultOprt; } @@ -611,6 +616,7 @@ void QmuParserBase::DefinePostfixOprt(const QString &a_sName, fun_type1 a_pFun, * * Calls the virtual functions InitFun(), InitConst() and InitOprt(). */ +// cppcheck-suppress unusedFunction void QmuParserBase::Init() { InitCharSets(); @@ -668,6 +674,7 @@ void QmuParserBase::DefineOprt( const QString &a_sName, fun_type2 a_pFun, unsign * @param [in] a_strName The name of the constant. * @param [in] a_strVal the value of the constant. */ +// cppcheck-suppress unusedFunction void QmuParserBase::DefineStrConst(const QString &a_strName, const QString &a_strVal) { // Test if a constant with that names already exists @@ -930,13 +937,13 @@ const varmap_type& QmuParserBase::GetUsedVar() const m_pParseFormula = &QmuParserBase::ParseString; m_pTokenReader->IgnoreUndefVar(false); } - catch (exception_type &e) + catch (const exception_type &e) { // Make sure to stay in string parse mode, dont call ReInit() // because it deletes the array with the used variables m_pParseFormula = &QmuParserBase::ParseString; m_pTokenReader->IgnoreUndefVar(false); - throw e; + throw; } return m_pTokenReader->GetUsedVar(); } @@ -1780,8 +1787,8 @@ void QmuParserBase::CreateRPN() const QStack stOpt, stVal; QStack stArgCount; token_type opta, opt; // for storing operators - token_type val, tval; // for storing value - string_type strBuf; // buffer for string function arguments + //token_type val, tval; // for storing value + //string_type strBuf; // buffer for string function arguments ReInit(); @@ -2074,6 +2081,7 @@ void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QStr * * Resets the parser to string parsing mode by calling #ReInit. */ +// cppcheck-suppress unusedFunction void QmuParserBase::ClearVar() { m_VarDef.clear(); @@ -2103,6 +2111,7 @@ void QmuParserBase::RemoveVar(const QString &a_strVarName) * @post Resets the parser to string parsing mode. * @throw nothrow */ +// cppcheck-suppress unusedFunction void QmuParserBase::ClearFun() { m_FunDef.clear(); @@ -2142,6 +2151,7 @@ void QmuParserBase::ClearPostfixOprt() * @post Resets the parser to string parsing mode. * @throw nothrow */ +// cppcheck-suppress unusedFunction void QmuParserBase::ClearOprt() { m_OprtDef.clear(); @@ -2154,6 +2164,7 @@ void QmuParserBase::ClearOprt() * @post Resets the parser to string parser mode. * @throw nothrow */ +// cppcheck-suppress unusedFunction void QmuParserBase::ClearInfixOprt() { m_InfixOprtDef.clear(); @@ -2180,6 +2191,7 @@ void QmuParserBase::EnableOptimizer(bool a_bIsOn) * * This function is for debug purposes only! */ +// cppcheck-suppress unusedFunction void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) { QmuParserBase::g_DbgDumpCmdCode = bDumpCmd; @@ -2410,6 +2422,7 @@ qreal* QmuParserBase::Eval(int &nStackSize) const * If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). There mey be more than one return * value. This function returns the number of available results. */ +// cppcheck-suppress unusedFunction int QmuParserBase::GetNumResults() const { return m_nFinalResultIdx; @@ -2438,7 +2451,7 @@ qreal QmuParserBase::Eval() const } //--------------------------------------------------------------------------------------------------------------------- -void QmuParserBase::Eval(qreal *results, int nBulkSize) +void QmuParserBase::Eval(qreal *results, int nBulkSize) const { CreateRPN(); @@ -2452,7 +2465,10 @@ void QmuParserBase::Eval(qreal *results, int nBulkSize) #endif int nMaxThreads = qMin(omp_get_max_threads(), s_MaxNumOpenMPThreads); - int nThreadID, ct=0; + // cppcheck-suppress variableScope + int nThreadID; + // cppcheck-suppress unreadVariable + int ct=0; omp_set_num_threads(nMaxThreads); #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 7b7ac88ca..dd6721892 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -70,7 +70,7 @@ public: static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); qreal Eval() const; qreal* Eval(int &nStackSize) const; - void Eval(qreal *results, int nBulkSize); + void Eval(qreal *results, int nBulkSize) const; int GetNumResults() const; void SetExpr(const QString &a_sExpr); void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); @@ -102,8 +102,8 @@ public: const valmap_type& GetConst() const; const QString& GetExpr() const; const funmap_type& GetFunDef() const; - QString GetVersion(EParserVersionInfo eInfo = pviFULL) const; - const QStringList& GetOprtDef() const; + static QString GetVersion(EParserVersionInfo eInfo = pviFULL); + static const QStringList& GetOprtDef(); void DefineNameChars(const QString &a_szCharset); void DefineOprtChars(const QString &a_szCharset); void DefineInfixOprtChars(const QString &a_szCharset); diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 296d89c53..1a0e79dda 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -39,6 +39,7 @@ namespace qmu /** * @brief Bytecode default constructor. */ +// cppcheck-suppress uninitMemberVar QmuParserByteCode::QmuParserByteCode() :m_iStackPos(0), m_iMaxStackSize(0), m_vRPN(), m_bEnableOptimizer(true) { @@ -51,6 +52,7 @@ QmuParserByteCode::QmuParserByteCode() * * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) */ +// cppcheck-suppress uninitMemberVar QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) :m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN), m_bEnableOptimizer(true) @@ -64,6 +66,7 @@ QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode) * * Implemented in Terms of Assign(const QParserByteCode &a_ByteCode) */ +// cppcheck-suppress operatorEqVarError QmuParserByteCode& QmuParserByteCode::operator=(const QmuParserByteCode &a_ByteCode) { Assign(a_ByteCode); @@ -92,6 +95,7 @@ void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) m_iStackPos = a_ByteCode.m_iStackPos; m_vRPN = a_ByteCode.m_vRPN; m_iMaxStackSize = a_ByteCode.m_iMaxStackSize; + m_bEnableOptimizer = a_ByteCode.m_bEnableOptimizer; } //--------------------------------------------------------------------------------------------------------------------- @@ -793,6 +797,7 @@ std::size_t QmuParserByteCode::GetMaxStackSize() const /** * @brief Returns the number of entries in the bytecode. */ +// cppcheck-suppress unusedFunction std::size_t QmuParserByteCode::GetSize() const { return m_vRPN.size(); diff --git a/src/libs/qmuparser/qmuparserbytecode.h b/src/libs/qmuparser/qmuparserbytecode.h index 51c4f518d..032c41108 100644 --- a/src/libs/qmuparser/qmuparserbytecode.h +++ b/src/libs/qmuparser/qmuparserbytecode.h @@ -80,25 +80,6 @@ struct SToken */ class QmuParserByteCode { -private: - /** @brief Token type for internal use only. */ - typedef QmuParserToken token_type; - - /** @brief Token vector for storing the RPN. */ - typedef QVector rpn_type; - - /** @brief Position in the Calculation array. */ - unsigned m_iStackPos; - - /** @brief Maximum size needed for the stack. */ - std::size_t m_iMaxStackSize; - - /** @brief The actual rpn storage. */ - rpn_type m_vRPN; - - bool m_bEnableOptimizer; - - void ConstantFolding(ECmdCode a_Oprt); public: QmuParserByteCode(); QmuParserByteCode(const QmuParserByteCode &a_ByteCode); @@ -119,6 +100,25 @@ public: std::size_t GetSize() const; const SToken* GetBase() const; void AsciiDump(); +private: + /** @brief Token type for internal use only. */ + typedef QmuParserToken token_type; + + /** @brief Token vector for storing the RPN. */ + typedef QVector rpn_type; + + /** @brief Position in the Calculation array. */ + unsigned m_iStackPos; + + /** @brief Maximum size needed for the stack. */ + std::size_t m_iMaxStackSize; + + /** @brief The actual rpn storage. */ + rpn_type m_vRPN; + + bool m_bEnableOptimizer; + + void ConstantFolding(ECmdCode a_Oprt); }; } // namespace qmu #endif diff --git a/src/libs/qmuparser/qmuparsercallback.cpp b/src/libs/qmuparser/qmuparsercallback.cpp index 139d91092..bb3ea9b94 100644 --- a/src/libs/qmuparser/qmuparsercallback.cpp +++ b/src/libs/qmuparser/qmuparsercallback.cpp @@ -332,11 +332,12 @@ QmuParserCallback* QmuParserCallback::Clone() const //--------------------------------------------------------------------------------------------------------------------- /** - * @brief Return tru if the function is conservative. + * @brief Return true if the function is conservative. * * Conservative functions return always the same result for the same argument. * @throw nothrow */ +// cppcheck-suppress unusedFunction bool QmuParserCallback::IsOptimizable() const { return m_bAllowOpti; diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index ab5c237cb..9fd28bb5c 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -29,6 +29,7 @@ namespace qmu const QmuParserErrorMsg QmuParserErrorMsg::m_Instance; //--------------------------------------------------------------------------------------------------------------------- +// cppcheck-suppress unusedFunction const QmuParserErrorMsg& QmuParserErrorMsg::Instance() { return m_Instance; @@ -225,11 +226,11 @@ QmuParserError::~QmuParserError() void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ) { QString strResult; - int iPos ( 0 ), iNext ( 0 ); + int iPos ( 0 ); for ( ;; ) { - iNext = strSource.indexOf ( strFind, iPos ); + int iNext = strSource.indexOf ( strFind, iPos ); strResult.append ( strSource.mid ( iPos, iNext - iPos ) ); if ( iNext == -1 ) @@ -248,6 +249,7 @@ void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFi /** * @brief Reset the erro object. */ +// cppcheck-suppress unusedFunction void QmuParserError::Reset() { m_strMsg.clear(); diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index 645fba258..2a86e2829 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -148,7 +148,7 @@ private: /** * @brief Replace all ocuurences of a substring with another string. */ - void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ); + static void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith ); void Reset(); }; diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 95305cdc5..cd9644cde 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -1065,6 +1065,7 @@ void QmuParserTester::AddTest ( testfun_type a_pFun ) } //--------------------------------------------------------------------------------------------------------------------- +// cppcheck-suppress unusedFunction void QmuParserTester::Run() { int iStat = 0; @@ -1179,6 +1180,7 @@ int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1 var = a_fVar1; fVal[0] = p.Eval(); + // cppcheck-suppress redundantAssignment var = a_fVar2; fVal[1] = p.Eval(); @@ -1404,7 +1406,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass /** * @brief Internal error in test class Test is going to be aborted. */ -void Q_NORETURN QmuParserTester::Abort() const +void Q_NORETURN QmuParserTester::Abort() { qDebug() << "Test failed (internal error in test class)"; while ( getchar() == false); diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index 648e6fb9c..ffa838ed8 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -61,9 +61,10 @@ private: void AddTest ( testfun_type a_pFun ); // Test Double Parser - int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ); - int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 ); - int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true ); + static int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass ); + static int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, + double a_fVar2 ); + static int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true ); // Multiarg callbacks static qreal f1of1 ( qreal v ) @@ -279,20 +280,32 @@ private: // Custom value recognition static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ); + // cppcheck-suppress functionStatic int TestNames(); + // cppcheck-suppress functionStatic int TestSyntax(); + // cppcheck-suppress functionStatic int TestMultiArg(); + // cppcheck-suppress functionStatic int TestPostFix(); + // cppcheck-suppress functionStatic int TestExpression(); + // cppcheck-suppress functionStatic int TestInfixOprt(); + // cppcheck-suppress functionStatic int TestBinOprt(); + // cppcheck-suppress functionStatic int TestVarConst(); + // cppcheck-suppress functionStatic int TestInterface(); + // cppcheck-suppress functionStatic int TestException(); + // cppcheck-suppress functionStatic int TestStrArg(); + // cppcheck-suppress functionStatic int TestIfThenElse(); - void Abort() const; + static void Abort(); }; } // namespace Test } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 485bdbda0..074621d53 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -101,6 +101,9 @@ void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) m_pFactoryData = a_Reader.m_pFactoryData; m_iBrackets = a_Reader.m_iBrackets; m_cArgSep = a_Reader.m_cArgSep; + + m_fZero = 0; + m_lastTok = token_type(); } //--------------------------------------------------------------------------------------------------------------------- @@ -363,7 +366,7 @@ int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_ { #if defined(_UNICODE) const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); - const std::wstring a_szCharSetstd = a_szCharSet.toStdWString(); + const std::wstring a_szCharSetStd = a_szCharSet.toStdWString(); #else const std::string m_strFormulaStd = m_strFormula.toStdString(); const std::string a_szCharSetStd = a_szCharSet.toStdString(); From 9ca9455c804dd1e609c0fb2e059f8b22c0f66add Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 2 May 2014 11:43:02 +0300 Subject: [PATCH 19/26] For nothrow methods set Q_DECL_NOEXCEPT. --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.cpp | 28 ++++++++++----------- src/libs/qmuparser/qmuparserbase.h | 28 ++++++++++----------- src/libs/qmuparser/qmuparserbytecode.cpp | 10 ++++---- src/libs/qmuparser/qmuparserbytecode.h | 10 ++++---- src/libs/qmuparser/qmuparsercallback.cpp | 8 +++--- src/libs/qmuparser/qmuparsercallback.h | 8 +++--- src/libs/qmuparser/qmuparsertoken.h | 4 +-- src/libs/qmuparser/qmuparsertokenreader.cpp | 20 +++++++-------- src/libs/qmuparser/qmuparsertokenreader.h | 20 +++++++-------- 9 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 14b3487f7..045ce9548 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -95,7 +95,7 @@ QmuParserBase::~QmuParserBase() * @return *this * @throw nothrow */ -QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) +QmuParserBase& QmuParserBase::operator=(const QmuParserBase &a_Parser) Q_DECL_NOEXCEPT { Assign(a_Parser); return *this; @@ -198,7 +198,7 @@ void QmuParserBase::ResetLocale() * @post m_pTokenReader.get()!=0 * @throw nothrow */ -void QmuParserBase::InitTokenReader() +void QmuParserBase::InitTokenReader() Q_DECL_NOEXCEPT { m_pTokenReader.reset(new token_reader_type(this)); } @@ -210,7 +210,7 @@ void QmuParserBase::InitTokenReader() * Clear bytecode, reset the token reader. * @throw nothrow */ -void QmuParserBase::ReInit() const +void QmuParserBase::ReInit() const Q_DECL_NOEXCEPT { m_pParseFormula = &QmuParserBase::ParseString; m_vStringBuf.clear(); @@ -977,7 +977,7 @@ const valmap_type& QmuParserBase::GetConst() const * parser functions. String functions are not part of this map. The Prototype definition is encapsulated in objects * of the class FunProt one per parser function each associated with function names via a map construct. */ -const funmap_type& QmuParserBase::GetFunDef() const +const funmap_type& QmuParserBase::GetFunDef() const Q_DECL_NOEXCEPT { return m_FunDef; } @@ -2082,7 +2082,7 @@ void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QStr * Resets the parser to string parsing mode by calling #ReInit. */ // cppcheck-suppress unusedFunction -void QmuParserBase::ClearVar() +void QmuParserBase::ClearVar() Q_DECL_NOEXCEPT { m_VarDef.clear(); ReInit(); @@ -2095,7 +2095,7 @@ void QmuParserBase::ClearVar() * * Removes a variable if it exists. If the Variable does not exist nothing will be done. */ -void QmuParserBase::RemoveVar(const QString &a_strVarName) +void QmuParserBase::RemoveVar(const QString &a_strVarName) Q_DECL_NOEXCEPT { varmap_type::iterator item = m_VarDef.find(a_strVarName); if (item!=m_VarDef.end()) @@ -2112,7 +2112,7 @@ void QmuParserBase::RemoveVar(const QString &a_strVarName) * @throw nothrow */ // cppcheck-suppress unusedFunction -void QmuParserBase::ClearFun() +void QmuParserBase::ClearFun() Q_DECL_NOEXCEPT { m_FunDef.clear(); ReInit(); @@ -2126,7 +2126,7 @@ void QmuParserBase::ClearFun() * @post Resets the parser to string parsing mode. * @throw nothrow */ -void QmuParserBase::ClearConst() +void QmuParserBase::ClearConst() Q_DECL_NOEXCEPT { m_ConstDef.clear(); m_StrVarDef.clear(); @@ -2139,7 +2139,7 @@ void QmuParserBase::ClearConst() * @post Resets the parser to string parsing mode. * @throw nothrow */ -void QmuParserBase::ClearPostfixOprt() +void QmuParserBase::ClearPostfixOprt() Q_DECL_NOEXCEPT { m_PostOprtDef.clear(); ReInit(); @@ -2152,7 +2152,7 @@ void QmuParserBase::ClearPostfixOprt() * @throw nothrow */ // cppcheck-suppress unusedFunction -void QmuParserBase::ClearOprt() +void QmuParserBase::ClearOprt() Q_DECL_NOEXCEPT { m_OprtDef.clear(); ReInit(); @@ -2165,7 +2165,7 @@ void QmuParserBase::ClearOprt() * @throw nothrow */ // cppcheck-suppress unusedFunction -void QmuParserBase::ClearInfixOprt() +void QmuParserBase::ClearInfixOprt() Q_DECL_NOEXCEPT { m_InfixOprtDef.clear(); ReInit(); @@ -2177,7 +2177,7 @@ void QmuParserBase::ClearInfixOprt() * @post Resets the parser to string parser mode. * @throw nothrow */ -void QmuParserBase::EnableOptimizer(bool a_bIsOn) +void QmuParserBase::EnableOptimizer(bool a_bIsOn) Q_DECL_NOEXCEPT { m_vRPN.EnableOptimizer(a_bIsOn); ReInit(); @@ -2208,7 +2208,7 @@ void QmuParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack) * manually one by one. It is not possible to disable built in operators selectively. This function will Reinitialize * the parser by calling ReInit(). */ -void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) +void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) Q_DECL_NOEXCEPT { m_bBuiltInOp = a_bIsOn; ReInit(); @@ -2220,7 +2220,7 @@ void QmuParserBase::EnableBuiltInOprt(bool a_bIsOn) * @return #m_bBuiltInOp; true if built in operators are enabled. * @throw nothrow */ -bool QmuParserBase::HasBuiltInOprt() const +bool QmuParserBase::HasBuiltInOprt() const Q_DECL_NOEXCEPT { return m_bBuiltInOp; } diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index dd6721892..b85aa8813 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -64,7 +64,7 @@ public: QmuParserBase(); QmuParserBase(const QmuParserBase &a_Parser); - QmuParserBase& operator=(const QmuParserBase &a_Parser); + QmuParserBase& operator=(const QmuParserBase &a_Parser) Q_DECL_NOEXCEPT; virtual ~QmuParserBase(); static void EnableDebugDump(bool bDumpCmd, bool bDumpStack); @@ -77,9 +77,9 @@ public: void SetDecSep(char_type cDecSep); void SetThousandsSep(char_type cThousandsSep = 0); void ResetLocale(); - void EnableOptimizer(bool a_bIsOn=true); - void EnableBuiltInOprt(bool a_bIsOn=true); - bool HasBuiltInOprt() const; + void EnableOptimizer(bool a_bIsOn=true) Q_DECL_NOEXCEPT; + void EnableBuiltInOprt(bool a_bIsOn=true) Q_DECL_NOEXCEPT; + bool HasBuiltInOprt() const Q_DECL_NOEXCEPT; void AddValIdent(identfun_type a_pCallback); void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0, EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false); @@ -90,18 +90,18 @@ public: void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); // Clear user defined variables, constants or functions - void ClearVar(); - void ClearFun(); - void ClearConst(); - void ClearInfixOprt(); - void ClearPostfixOprt(); - void ClearOprt(); - void RemoveVar(const QString &a_strVarName); + void ClearVar() Q_DECL_NOEXCEPT; + void ClearFun() Q_DECL_NOEXCEPT; + void ClearConst() Q_DECL_NOEXCEPT; + void ClearInfixOprt() Q_DECL_NOEXCEPT; + void ClearPostfixOprt() Q_DECL_NOEXCEPT; + void ClearOprt() Q_DECL_NOEXCEPT; + void RemoveVar(const QString &a_strVarName) Q_DECL_NOEXCEPT; const varmap_type& GetUsedVar() const; const varmap_type& GetVar() const; const valmap_type& GetConst() const; const QString& GetExpr() const; - const funmap_type& GetFunDef() const; + const funmap_type& GetFunDef() const Q_DECL_NOEXCEPT; static QString GetVersion(EParserVersionInfo eInfo = pviFULL); static const QStringList& GetOprtDef(); void DefineNameChars(const QString &a_szCharset); @@ -235,8 +235,8 @@ private: mutable int m_nFinalResultIdx; void Assign(const QmuParserBase &a_Parser); - void InitTokenReader(); - void ReInit() const; + void InitTokenReader() Q_DECL_NOEXCEPT; + void ReInit() const Q_DECL_NOEXCEPT; void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback, funmap_type &a_Storage, const QString &a_szCharSet ); void ApplyRemainingOprt(QStack &a_stOpt, QStack &a_stVal) const; diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 1a0e79dda..696163501 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -104,7 +104,7 @@ void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode) * @param a_pVar Pointer to be added. * @throw nothrow */ -void QmuParserByteCode::AddVar(qreal *a_pVar) +void QmuParserByteCode::AddVar(qreal *a_pVar) Q_DECL_NOEXCEPT { ++m_iStackPos; m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); @@ -132,7 +132,7 @@ void QmuParserByteCode::AddVar(qreal *a_pVar) * @param a_pVal Value to be added. * @throw nothrow */ -void QmuParserByteCode::AddVal(qreal a_fVal) +void QmuParserByteCode::AddVal(qreal a_fVal) Q_DECL_NOEXCEPT { ++m_iStackPos; m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast(m_iStackPos)); @@ -623,7 +623,7 @@ void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc) * A string function entry consists of the stack position of the return value, followed by a cmSTRFUNC code, the * function pointer and an index into the string buffer maintained by the parser. */ -void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) +void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) Q_DECL_NOEXCEPT { m_iStackPos = m_iStackPos - a_iArgc + 1; @@ -643,7 +643,7 @@ void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iI * * @throw nothrow */ -void QmuParserByteCode::Finalize() +void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT { SToken tok; tok.Cmd = cmEND; @@ -812,7 +812,7 @@ std::size_t QmuParserByteCode::GetSize() const * The name of this function is a violation of my own coding guidelines but this way it's more in line with the STL * functions thus more intuitive. */ -void QmuParserByteCode::clear() +void QmuParserByteCode::clear() Q_DECL_NOEXCEPT { m_vRPN.clear(); m_iStackPos = 0; diff --git a/src/libs/qmuparser/qmuparserbytecode.h b/src/libs/qmuparser/qmuparserbytecode.h index 032c41108..8c5153987 100644 --- a/src/libs/qmuparser/qmuparserbytecode.h +++ b/src/libs/qmuparser/qmuparserbytecode.h @@ -85,17 +85,17 @@ public: QmuParserByteCode(const QmuParserByteCode &a_ByteCode); QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); void Assign(const QmuParserByteCode &a_ByteCode); - void AddVar(qreal *a_pVar); - void AddVal(qreal a_fVal); + void AddVar(qreal *a_pVar) Q_DECL_NOEXCEPT; + void AddVal(qreal a_fVal) Q_DECL_NOEXCEPT; void AddOp(ECmdCode a_Oprt); void AddIfElse(ECmdCode a_Oprt); void AddAssignOp(qreal *a_pVar); void AddFun(generic_fun_type a_pFun, int a_iArgc); void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); - void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); + void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) Q_DECL_NOEXCEPT; void EnableOptimizer(bool bStat); - void Finalize(); - void clear(); + void Finalize() Q_DECL_NOEXCEPT; + void clear() Q_DECL_NOEXCEPT; std::size_t GetMaxStackSize() const; std::size_t GetSize() const; const SToken* GetBase() const; diff --git a/src/libs/qmuparser/qmuparsercallback.cpp b/src/libs/qmuparser/qmuparsercallback.cpp index bb3ea9b94..2af42b991 100644 --- a/src/libs/qmuparser/qmuparsercallback.cpp +++ b/src/libs/qmuparser/qmuparsercallback.cpp @@ -338,7 +338,7 @@ QmuParserCallback* QmuParserCallback::Clone() const * @throw nothrow */ // cppcheck-suppress unusedFunction -bool QmuParserCallback::IsOptimizable() const +bool QmuParserCallback::IsOptimizable() const Q_DECL_NOEXCEPT { return m_bAllowOpti; } @@ -352,7 +352,7 @@ bool QmuParserCallback::IsOptimizable() const * @throw nothrow * @return #pFun */ -void* QmuParserCallback::GetAddr() const +void* QmuParserCallback::GetAddr() const Q_DECL_NOEXCEPT { return m_pFun; } @@ -379,7 +379,7 @@ ETypeCode QmuParserCallback::GetType() const * * Only valid if the callback token is an operator token (binary or infix). */ -int QmuParserCallback::GetPri() const +int QmuParserCallback::GetPri() const Q_DECL_NOEXCEPT { return m_iPri; } @@ -391,7 +391,7 @@ int QmuParserCallback::GetPri() const * * Only valid if the callback token is a binary operator token. */ -EOprtAssociativity QmuParserCallback::GetAssociativity() const +EOprtAssociativity QmuParserCallback::GetAssociativity() const Q_DECL_NOEXCEPT { return m_eOprtAsct; } diff --git a/src/libs/qmuparser/qmuparsercallback.h b/src/libs/qmuparser/qmuparsercallback.h index 2c876bf79..4d45fb8f2 100644 --- a/src/libs/qmuparser/qmuparsercallback.h +++ b/src/libs/qmuparser/qmuparsercallback.h @@ -79,12 +79,12 @@ public: QmuParserCallback(const QmuParserCallback &a_Fun); QmuParserCallback* Clone() const; - bool IsOptimizable() const; - void* GetAddr() const; + bool IsOptimizable() const Q_DECL_NOEXCEPT; + void* GetAddr() const Q_DECL_NOEXCEPT; ECmdCode GetCode() const; ETypeCode GetType() const; - int GetPri() const; - EOprtAssociativity GetAssociativity() const; + int GetPri() const Q_DECL_NOEXCEPT; + EOprtAssociativity GetAssociativity() const Q_DECL_NOEXCEPT; int GetArgc() const; private: void *m_pFun; ///< Pointer to the callback function, casted to void diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 815de0194..92a2722c3 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -270,7 +270,7 @@ public: * @return #m_iType * @throw nothrow */ - ECmdCode GetCode() const + ECmdCode GetCode() const Q_DECL_NOEXCEPT { if ( m_pCallback.get() ) { @@ -510,7 +510,7 @@ public: * @throw nothrow * @sa m_strTok */ - const TString& GetAsString() const + const TString& GetAsString() const Q_DECL_NOEXCEPT { return m_strTok; } diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 074621d53..8dcafb9cc 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -63,7 +63,7 @@ QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reade * @param a_Reader Object to copy to this token reader. * @throw nothrow */ -QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenReader &a_Reader ) +QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenReader &a_Reader ) Q_DECL_NOEXCEPT { if ( &a_Reader != this ) { @@ -80,7 +80,7 @@ QmuParserTokenReader& QmuParserTokenReader::operator= ( const QmuParserTokenRead * @param a_Reader Object from which the state should be copied. * @throw nothrow */ -void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) +void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) Q_DECL_NOEXCEPT { m_pParser = a_Reader.m_pParser; m_strFormula = a_Reader.m_strFormula; @@ -135,7 +135,7 @@ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) * @return A new QParserTokenReader object. * @throw nothrow */ -QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const +QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const Q_DECL_NOEXCEPT { std::unique_ptr ptr ( new QmuParserTokenReader ( *this ) ); ptr->SetParent ( a_pParent ); @@ -175,7 +175,7 @@ void QmuParserTokenReader::SetVarCreator ( facfun_type a_pFactory, void *pUserDa * @return #m_iPos * @throw nothrow */ -int QmuParserTokenReader::GetPos() const +int QmuParserTokenReader::GetPos() const Q_DECL_NOEXCEPT { return m_iPos; } @@ -187,7 +187,7 @@ int QmuParserTokenReader::GetPos() const * @return #m_strFormula * @throw nothrow */ -const QString& QmuParserTokenReader::GetExpr() const +const QString& QmuParserTokenReader::GetExpr() const Q_DECL_NOEXCEPT { return m_strFormula; } @@ -237,7 +237,7 @@ void QmuParserTokenReader::IgnoreUndefVar ( bool bIgnore ) * @throw nothrow * @sa ESynCodes */ -void QmuParserTokenReader::ReInit() +void QmuParserTokenReader::ReInit() Q_DECL_NOEXCEPT { m_iPos = 0; m_iSynFlags = sfSTART_OF_LINE; @@ -362,7 +362,7 @@ void QmuParserTokenReader::SetParent ( QmuParserBase *a_pParent ) * @return The Position of the first character not listed in a_szCharSet. * @throw nothrow */ -int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_sTok, int a_iPos ) const +int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_sTok, int a_iPos ) const Q_DECL_NOEXCEPT { #if defined(_UNICODE) const std::wstring m_strFormulaStd = m_strFormula.toStdWString(); @@ -599,7 +599,7 @@ bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok ) * @throw nothrow * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok */ -bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) +bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) Q_DECL_NOEXCEPT { #if defined(_UNICODE) const char_type* szFormula = m_strFormula.toStdWString().c_str(); @@ -996,7 +996,7 @@ bool QmuParserTokenReader::IsStrVarTok ( token_type &a_Tok ) * @return true if a variable token has been found. * @throw nothrow */ -bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) +bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) Q_DECL_NOEXCEPT { QString strTok; int iEnd ( ExtractToken ( m_pParser->ValidNameChars(), strTok, m_iPos ) ); @@ -1051,7 +1051,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok * @throw nothrow */ -bool QmuParserTokenReader::IsString ( token_type &a_Tok ) +bool QmuParserTokenReader::IsString ( token_type &a_Tok ) Q_DECL_NOEXCEPT { if ( m_strFormula[m_iPos] != '"' ) { diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 8bf7a3efc..93af5ad12 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -57,20 +57,20 @@ namespace qmu public: QmuParserTokenReader(QmuParserBase *a_pParent); - QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const; + QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const Q_DECL_NOEXCEPT; void AddValIdent(identfun_type a_pCallback); void SetVarCreator(facfun_type a_pFactory, void *pUserData); void SetFormula(const QString &a_strFormula); void SetArgSep(char_type cArgSep); - int GetPos() const; - const QString &GetExpr() const; + int GetPos() const Q_DECL_NOEXCEPT; + const QString &GetExpr() const Q_DECL_NOEXCEPT; varmap_type& GetUsedVar(); QChar GetArgSep() const; void IgnoreUndefVar(bool bIgnore); - void ReInit(); + void ReInit() Q_DECL_NOEXCEPT; token_type ReadNextToken(); private: @@ -102,16 +102,16 @@ namespace qmu }; QmuParserTokenReader(const QmuParserTokenReader &a_Reader); - QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader); - void Assign(const QmuParserTokenReader &a_Reader); + QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; + void Assign(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; void SetParent(QmuParserBase *a_pParent); - int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const; + int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const Q_DECL_NOEXCEPT; int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; bool IsBuiltIn(token_type &a_Tok); bool IsArgSep(token_type &a_Tok); - bool IsEOF(token_type &a_Tok); + bool IsEOF(token_type &a_Tok) Q_DECL_NOEXCEPT; bool IsInfixOpTok(token_type &a_Tok); bool IsFunTok(token_type &a_Tok); bool IsPostOpTok(token_type &a_Tok); @@ -119,8 +119,8 @@ namespace qmu bool IsValTok(token_type &a_Tok); bool IsVarTok(token_type &a_Tok); bool IsStrVarTok(token_type &a_Tok); - bool IsUndefVarTok(token_type &a_Tok); - bool IsString(token_type &a_Tok); + bool IsUndefVarTok(token_type &a_Tok) Q_DECL_NOEXCEPT; + bool IsString(token_type &a_Tok) Q_DECL_NOEXCEPT; void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_sTok = QString() ) const; From bdb788e7a7fb89e56e7ca37b56cd492b0eaa4ce2 Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 2 May 2014 14:11:30 +0300 Subject: [PATCH 20/26] Highlight start of method. --HG-- branch : feature --- src/app/container/calculator.cpp | 19 +++- src/app/container/vcontainer.cpp | 40 +++++++- src/app/container/vincrement.cpp | 6 +- src/app/container/vmeasurement.cpp | 17 ++-- src/app/dialogs/app/configdialog.cpp | 6 ++ src/app/dialogs/app/dialoghistory.cpp | 11 +++ src/app/dialogs/app/dialogincrements.cpp | 20 ++++ .../app/dialogindividualmeasurements.cpp | 9 ++ src/app/dialogs/app/dialogmeasurements.cpp | 5 + .../dialogs/app/dialogpatternproperties.cpp | 4 + .../app/dialogstandardmeasurements.cpp | 8 ++ src/app/dialogs/app/pages.cpp | 11 ++- src/app/dialogs/tools/dialogalongline.cpp | 9 ++ src/app/dialogs/tools/dialogarc.cpp | 21 ++++ src/app/dialogs/tools/dialogbisector.cpp | 10 ++ src/app/dialogs/tools/dialogcutarc.cpp | 7 ++ src/app/dialogs/tools/dialogcutspline.cpp | 7 ++ src/app/dialogs/tools/dialogcutsplinepath.cpp | 7 ++ src/app/dialogs/tools/dialogdetail.cpp | 11 +++ src/app/dialogs/tools/dialogendline.cpp | 9 ++ src/app/dialogs/tools/dialogheight.cpp | 9 ++ src/app/dialogs/tools/dialogline.cpp | 8 +- src/app/dialogs/tools/dialoglineintersect.cpp | 15 +++ src/app/dialogs/tools/dialognormal.cpp | 10 ++ .../dialogs/tools/dialogpointofcontact.cpp | 8 ++ .../tools/dialogpointofintersection.cpp | 7 ++ src/app/dialogs/tools/dialogshoulderpoint.cpp | 10 ++ src/app/dialogs/tools/dialogsinglepoint.cpp | 5 + src/app/dialogs/tools/dialogspline.cpp | 13 +++ src/app/dialogs/tools/dialogsplinepath.cpp | 15 ++- src/app/dialogs/tools/dialogtool.cpp | 48 ++++++++++ src/app/dialogs/tools/dialogtriangle.cpp | 9 ++ src/app/dialogs/tools/dialoguniondetails.cpp | 6 ++ src/app/exception/vexception.cpp | 10 +- src/app/exception/vexceptionbadid.cpp | 1 + .../exception/vexceptionconversionerror.cpp | 7 +- .../exception/vexceptionemptyparameter.cpp | 8 +- src/app/exception/vexceptionobjecterror.cpp | 8 +- src/app/exception/vexceptionwrongid.cpp | 8 +- src/app/geometry/varc.cpp | 19 +++- src/app/geometry/vdetail.cpp | 25 ++++- src/app/geometry/vequidistant.cpp | 10 ++ src/app/geometry/vgobject.cpp | 21 ++-- src/app/geometry/vnodedetail.cpp | 13 ++- src/app/geometry/vpointf.cpp | 17 ++-- src/app/geometry/vspline.cpp | 40 ++++++-- src/app/geometry/vsplinepath.cpp | 23 ++++- src/app/geometry/vsplinepoint.cpp | 11 ++- src/app/main.cpp | 2 + src/app/mainwindow.cpp | 95 +++++++++++++++++++ src/app/tablewindow.cpp | 25 ++++- src/app/tools/drawTools/vabstractspline.cpp | 9 ++ src/app/tools/drawTools/vdrawtool.cpp | 8 ++ src/app/tools/drawTools/vtoolalongline.cpp | 12 +++ src/app/tools/drawTools/vtoolarc.cpp | 19 ++++ src/app/tools/drawTools/vtoolbisector.cpp | 13 +++ src/app/tools/drawTools/vtoolcutarc.cpp | 14 +++ src/app/tools/drawTools/vtoolcutspline.cpp | 15 +++ .../tools/drawTools/vtoolcutsplinepath.cpp | 15 +++ src/app/tools/drawTools/vtoolendline.cpp | 10 ++ src/app/tools/drawTools/vtoolheight.cpp | 11 +++ src/app/tools/drawTools/vtoolline.cpp | 18 ++++ .../tools/drawTools/vtoollineintersect.cpp | 12 +++ src/app/tools/drawTools/vtoollinepoint.cpp | 4 + src/app/tools/drawTools/vtoolnormal.cpp | 13 +++ src/app/tools/drawTools/vtoolpoint.cpp | 14 +++ .../tools/drawTools/vtoolpointofcontact.cpp | 13 +++ .../drawTools/vtoolpointofintersection.cpp | 11 +++ .../tools/drawTools/vtoolshoulderpoint.cpp | 13 +++ src/app/tools/drawTools/vtoolsinglepoint.cpp | 13 +++ src/app/tools/drawTools/vtoolspline.cpp | 11 +++ src/app/tools/drawTools/vtoolsplinepath.cpp | 16 ++++ src/app/tools/drawTools/vtooltriangle.cpp | 12 +++ src/app/tools/nodeDetails/vabstractnode.cpp | 4 + src/app/tools/nodeDetails/vnodearc.cpp | 10 ++ src/app/tools/nodeDetails/vnodepoint.cpp | 14 ++- src/app/tools/nodeDetails/vnodespline.cpp | 10 ++ src/app/tools/nodeDetails/vnodesplinepath.cpp | 10 ++ src/app/tools/vabstracttool.cpp | 12 +++ src/app/tools/vdatatool.cpp | 3 + src/app/tools/vtooldetail.cpp | 18 ++++ src/app/tools/vtooluniondetails.cpp | 15 +++ src/app/widgets/doubledelegate.cpp | 5 + src/app/widgets/textdelegate.cpp | 7 ++ src/app/widgets/vapplication.cpp | 11 ++- src/app/widgets/vcontrolpointspline.cpp | 6 ++ src/app/widgets/vgraphicssimpletextitem.cpp | 6 ++ src/app/widgets/vitem.cpp | 17 ++-- src/app/widgets/vmaingraphicsscene.cpp | 14 ++- src/app/widgets/vmaingraphicsview.cpp | 7 ++ src/app/widgets/vsimplearc.cpp | 4 + src/app/widgets/vsimplespline.cpp | 5 + src/app/widgets/vsimplesplinepath.cpp | 7 +- src/app/widgets/vtablegraphicsview.cpp | 9 ++ src/app/xml/vdomdocument.cpp | 21 +++- src/app/xml/vindividualmeasurements.cpp | 21 +++- src/app/xml/vpattern.cpp | 44 ++++++++- src/app/xml/vstandardmeasurements.cpp | 9 +- src/app/xml/vtoolrecord.cpp | 8 +- 99 files changed, 1216 insertions(+), 100 deletions(-) diff --git a/src/app/container/calculator.cpp b/src/app/container/calculator.cpp index 6ea776396..99bb14854 100644 --- a/src/app/container/calculator.cpp +++ b/src/app/container/calculator.cpp @@ -38,6 +38,7 @@ #define FINISHED 10 #define EOL 9 +//--------------------------------------------------------------------------------------------------------------------- qreal Calculator::eval(QString prog, QString *errorMsg) { this->errorMsg = errorMsg; @@ -53,6 +54,7 @@ qreal Calculator::eval(QString prog, QString *errorMsg) return result; } +//--------------------------------------------------------------------------------------------------------------------- qreal Calculator::get_exp() { qreal result = 0; @@ -67,7 +69,7 @@ qreal Calculator::get_exp() return result; } - +//--------------------------------------------------------------------------------------------------------------------- void Calculator::level2(qreal *result) { QChar op; @@ -82,6 +84,7 @@ void Calculator::level2(qreal *result) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::level3(qreal *result) { QChar op; @@ -97,6 +100,7 @@ void Calculator::level3(qreal *result) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::level4(qreal *result) { qreal hold; @@ -110,6 +114,7 @@ void Calculator::level4(qreal *result) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::level5(qreal *result) { QChar op; @@ -127,6 +132,7 @@ void Calculator::level5(qreal *result) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::level6(qreal *result) { if ((token[0] == '(') && (token_type == DELIMITER)) @@ -142,6 +148,7 @@ void Calculator::level6(qreal *result) primitive(result); } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::primitive(qreal *result) { QString str; @@ -164,6 +171,7 @@ void Calculator::primitive(qreal *result) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::arith(QChar o, qreal *r, qreal *h) { qreal t;//, ex; @@ -194,6 +202,7 @@ void Calculator::arith(QChar o, qreal *r, qreal *h) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::unary(QChar o, qreal *r) { if (o=='-') @@ -202,6 +211,7 @@ void Calculator::unary(QChar o, qreal *r) } } +//--------------------------------------------------------------------------------------------------------------------- qreal Calculator::find_var(QString s) { bool ok = false; @@ -215,6 +225,7 @@ qreal Calculator::find_var(QString s) return value; } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::serror(qint32 error) { QString e[]= @@ -230,6 +241,7 @@ void Calculator::serror(qint32 error) qDebug()</*%^=()", c) || c=='\n' || c=='\r' || c=='\0') @@ -249,6 +262,7 @@ bool Calculator::isdelim(QChar c) return false; } +//--------------------------------------------------------------------------------------------------------------------- bool Calculator::iswhite(QChar c) { if (c==' ' || c=='\t') @@ -261,6 +275,7 @@ bool Calculator::iswhite(QChar c) } } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::get_token() { QString *temp; @@ -355,11 +370,13 @@ void Calculator::get_token() return; } +//--------------------------------------------------------------------------------------------------------------------- bool Calculator::StrChr(QString string, QChar c) { return string.contains(c, Qt::CaseInsensitive); } +//--------------------------------------------------------------------------------------------------------------------- void Calculator::putback() { QString t; diff --git a/src/app/container/vcontainer.cpp b/src/app/container/vcontainer.cpp index d8c0f4ca8..3ec01bc55 100644 --- a/src/app/container/vcontainer.cpp +++ b/src/app/container/vcontainer.cpp @@ -34,20 +34,22 @@ quint32 VContainer::_id = 0; +//--------------------------------------------------------------------------------------------------------------------- VContainer::VContainer() :_size(50), sizeName("Сг"), _height(176), heightName("P"), gObjects(QHash()), measurements(QHash()), increments(QHash()), lengthLines(QHash()), lineAngles(QHash()), lengthSplines(QHash()), lengthArcs(QHash()), details(QHash()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VContainer &VContainer::operator =(const VContainer &data) { setData(data); return *this; } +//--------------------------------------------------------------------------------------------------------------------- VContainer::VContainer(const VContainer &data) :_size(50), sizeName("Сг"), _height(176), heightName("P"), gObjects(QHash()), measurements(QHash()), increments(QHash()), @@ -57,12 +59,14 @@ VContainer::VContainer(const VContainer &data) setData(data); } +//--------------------------------------------------------------------------------------------------------------------- VContainer::~VContainer() { qDeleteAll(gObjects); gObjects.clear(); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::setData(const VContainer &data) { _size = data.size(); @@ -106,12 +110,14 @@ void VContainer::setData(const VContainer &data) details = *data.DataDetails(); } +//--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction const VGObject *VContainer::GetGObject(quint32 id)const { return GetObject(gObjects, id); } +//--------------------------------------------------------------------------------------------------------------------- template const val VContainer::GetObject(const QHash &obj, key id) const { @@ -125,6 +131,7 @@ const val VContainer::GetObject(const QHash &obj, key id) const } } +//--------------------------------------------------------------------------------------------------------------------- template val VContainer::GetVariable(const QHash &obj, key id) const { @@ -138,52 +145,61 @@ val VContainer::GetVariable(const QHash &obj, key id) const } } +//--------------------------------------------------------------------------------------------------------------------- const VMeasurement VContainer::GetMeasurement(const QString &name) const { Q_ASSERT(name.isEmpty()==false); return GetVariable(measurements, name); } +//--------------------------------------------------------------------------------------------------------------------- const VIncrement VContainer::GetIncrement(const QString& name) const { Q_ASSERT(name.isEmpty()==false); return GetVariable(increments, name); } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::GetLine(const QString &name) const { Q_ASSERT(name.isEmpty()==false); return GetVariable(lengthLines, name); } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::GetLengthArc(const QString &name) const { Q_ASSERT(name.isEmpty()==false); return GetVariable(lengthArcs, name); } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::GetLengthSpline(const QString &name) const { Q_ASSERT(name.isEmpty()==false); return GetVariable(lengthSplines, name); } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::GetLineAngle(const QString &name) const { Q_ASSERT(name.isEmpty()==false); return GetVariable(lineAngles, name); } +//--------------------------------------------------------------------------------------------------------------------- const VDetail VContainer::GetDetail(quint32 id) const { return GetVariable(details, id); } +//--------------------------------------------------------------------------------------------------------------------- quint32 VContainer::AddGObject(VGObject *obj) { return AddObject(gObjects, obj); } +//--------------------------------------------------------------------------------------------------------------------- quint32 VContainer::AddDetail(VDetail detail) { quint32 id = getNextId(); @@ -191,17 +207,20 @@ quint32 VContainer::AddDetail(VDetail detail) return id; } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::AddIncrement(const QString &name, VIncrement incr) { increments[name] = incr; } +//--------------------------------------------------------------------------------------------------------------------- quint32 VContainer::getNextId() { _id++; return _id; } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::UpdateId(quint32 newId) { if (newId > _id) @@ -210,6 +229,7 @@ void VContainer::UpdateId(quint32 newId) } } +//--------------------------------------------------------------------------------------------------------------------- template void VContainer::UpdateObject(QHash &obj, const quint32 &id, val point) { @@ -225,24 +245,28 @@ void VContainer::UpdateObject(QHash &obj, const quint32 &id, val p UpdateId(id); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::AddLengthSpline(const QString &name, const qreal &value) { Q_ASSERT(name.isEmpty() == false); lengthSplines[name] = value; } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::AddLengthArc(const quint32 &id) { const VArc * arc = GeometricObject(id); lengthArcs[arc->name()] = qApp->fromPixel(arc->GetLength()); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::AddLineAngle(const QString &name, const qreal &value) { Q_ASSERT(name.isEmpty() == false); lineAngles[name] = value; } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::GetValueStandardTableRow(const QString& name) const { const VMeasurement m = GetMeasurement(name); @@ -256,6 +280,7 @@ qreal VContainer::GetValueStandardTableRow(const QString& name) const } } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::GetValueIncrementTableRow(const QString& name) const { const VIncrement icr = GetIncrement(name); @@ -269,6 +294,7 @@ qreal VContainer::GetValueIncrementTableRow(const QString& name) const } } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::Clear() { _id = 0; @@ -282,6 +308,7 @@ void VContainer::Clear() ClearGObjects(); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::ClearGObjects() { if (gObjects.size()>0) @@ -291,6 +318,7 @@ void VContainer::ClearGObjects() gObjects.clear(); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::ClearCalculationGObjects() { if (gObjects.size()>0) @@ -308,6 +336,7 @@ void VContainer::ClearCalculationGObjects() } } +//--------------------------------------------------------------------------------------------------------------------- qreal VContainer::FindVar(const QString &name, bool *ok)const { if (sizeName == name) @@ -354,6 +383,7 @@ qreal VContainer::FindVar(const QString &name, bool *ok)const return 0; } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::AddLine(const quint32 &firstPointId, const quint32 &secondPointId) { QString nameLine = GetNameLine(firstPointId, secondPointId); @@ -364,6 +394,7 @@ void VContainer::AddLine(const quint32 &firstPointId, const quint32 &secondPoint AddLineAngle(nameLine, QLineF(first->toQPointF(), second->toQPointF()).angle()); } +//--------------------------------------------------------------------------------------------------------------------- template quint32 VContainer::AddObject(QHash &obj, val value) { @@ -374,6 +405,7 @@ quint32 VContainer::AddObject(QHash &obj, val value) return id; } +//--------------------------------------------------------------------------------------------------------------------- QString VContainer::GetNameLine(const quint32 &firstPoint, const quint32 &secondPoint) const { const VPointF *first = GeometricObject(firstPoint); @@ -382,6 +414,7 @@ QString VContainer::GetNameLine(const quint32 &firstPoint, const quint32 &second return QString("Line_%1_%2").arg(first->name(), second->name()); } +//--------------------------------------------------------------------------------------------------------------------- QString VContainer::GetNameLineAngle(const quint32 &firstPoint, const quint32 &secondPoint) const { const VPointF *first = GeometricObject(firstPoint); @@ -390,11 +423,13 @@ QString VContainer::GetNameLineAngle(const quint32 &firstPoint, const quint32 &s return QString("AngleLine_%1_%2").arg(first->name(), second->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::UpdateGObject(quint32 id, VGObject* obj) { UpdateObject(gObjects, id, obj); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::UpdateDetail(quint32 id, const VDetail &detail) { Q_ASSERT_X(id > 0, Q_FUNC_INFO, "id <= 0"); @@ -402,6 +437,7 @@ void VContainer::UpdateDetail(quint32 id, const VDetail &detail) UpdateId(id); } +//--------------------------------------------------------------------------------------------------------------------- void VContainer::AddLengthLine(const QString &name, const qreal &value) { Q_ASSERT(name.isEmpty() == false); diff --git a/src/app/container/vincrement.cpp b/src/app/container/vincrement.cpp index 83ef32a48..13f1f6da3 100644 --- a/src/app/container/vincrement.cpp +++ b/src/app/container/vincrement.cpp @@ -28,17 +28,21 @@ #include "vincrement.h" +//--------------------------------------------------------------------------------------------------------------------- VIncrement::VIncrement() :id(0), base(0), ksize(50.0), kheight(176.0), description(QString()){} VIncrement::VIncrement(quint32 id, qreal base, qreal ksize, qreal kheight, QString description) - :id(id), base(base), ksize(ksize), kheight(kheight), description(description){} + :id(id), base(base), ksize(ksize), kheight(kheight), description(description) +{} +//--------------------------------------------------------------------------------------------------------------------- qreal VIncrement::GetValue() const { return base; } +//--------------------------------------------------------------------------------------------------------------------- qreal VIncrement::GetValue(const qreal &size, const qreal &height) const { const qreal k_size = ( size - 50.0 ) / 2.0; diff --git a/src/app/container/vmeasurement.cpp b/src/app/container/vmeasurement.cpp index 2200c5cad..e39460e61 100644 --- a/src/app/container/vmeasurement.cpp +++ b/src/app/container/vmeasurement.cpp @@ -28,33 +28,32 @@ #include "vmeasurement.h" +//--------------------------------------------------------------------------------------------------------------------- VMeasurement::VMeasurement() :base(0), ksize(50.0), kheight(176.0), gui_text(QString()), number(QString()), virtualM(false), _tagName(QString()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- VMeasurement::VMeasurement(const qreal &base, const qreal &ksize, const qreal &kgrowth, const QString &gui_text, const QString &number, const QString &tagName) :base(base), ksize(ksize), kheight(kgrowth), gui_text(gui_text), number(number), virtualM(false), _tagName(tagName) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- VMeasurement::VMeasurement(const qreal &base, const QString &gui_text, const QString &number, const QString &tagName) :base(base), ksize(50.0), kheight(176.0), gui_text(gui_text), number(number), virtualM(false), _tagName(tagName) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- qreal VMeasurement::GetValue() const { return base; } +//--------------------------------------------------------------------------------------------------------------------- qreal VMeasurement::GetValue(const qreal &size, const qreal &height) const { const qreal k_size = ( size - 50.0 ) / 2.0; diff --git a/src/app/dialogs/app/configdialog.cpp b/src/app/dialogs/app/configdialog.cpp index c1bfacfbe..49d978f9d 100644 --- a/src/app/dialogs/app/configdialog.cpp +++ b/src/app/dialogs/app/configdialog.cpp @@ -28,6 +28,7 @@ #include "configdialog.h" +//--------------------------------------------------------------------------------------------------------------------- ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent), contentsWidget(nullptr), pagesWidget(nullptr), configurationPage(nullptr), patternPage(nullptr) { @@ -76,6 +77,7 @@ ConfigDialog::ConfigDialog(QWidget *parent) : setWindowTitle(tr("Config Dialog")); } +//--------------------------------------------------------------------------------------------------------------------- void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) { if (current == false) @@ -85,6 +87,7 @@ void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previou pagesWidget->setCurrentIndex(contentsWidget->row(current)); } +//--------------------------------------------------------------------------------------------------------------------- void ConfigDialog::closeEvent(QCloseEvent *event) { if (result() == QDialog::Accepted) @@ -94,6 +97,7 @@ void ConfigDialog::closeEvent(QCloseEvent *event) event->accept(); } +//--------------------------------------------------------------------------------------------------------------------- void ConfigDialog::createIcons() { QListWidgetItem *configButton = new QListWidgetItem(contentsWidget); @@ -111,6 +115,7 @@ void ConfigDialog::createIcons() connect(contentsWidget, &QListWidget::currentItemChanged, this, &ConfigDialog::changePage); } +//--------------------------------------------------------------------------------------------------------------------- void ConfigDialog::Apply() { switch (contentsWidget->currentRow()) @@ -127,6 +132,7 @@ void ConfigDialog::Apply() setResult(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void ConfigDialog::Ok() { Apply(); diff --git a/src/app/dialogs/app/dialoghistory.cpp b/src/app/dialogs/app/dialoghistory.cpp index d21274707..a6c452fe3 100644 --- a/src/app/dialogs/app/dialoghistory.cpp +++ b/src/app/dialogs/app/dialoghistory.cpp @@ -38,6 +38,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- DialogHistory::DialogHistory(VContainer *data, VPattern *doc, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogHistory), doc(doc), cursorRow(0), cursorToolRecordRow(0) @@ -55,11 +56,13 @@ DialogHistory::DialogHistory(VContainer *data, VPattern *doc, QWidget *parent) ShowPoint(); } +//--------------------------------------------------------------------------------------------------------------------- DialogHistory::~DialogHistory() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::DialogAccepted() { QTableWidgetItem *item = ui->tableWidget->item(cursorToolRecordRow, 0); @@ -68,6 +71,7 @@ void DialogHistory::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::cellClicked(int row, int column) { if (column == 0) @@ -96,6 +100,7 @@ void DialogHistory::cellClicked(int row, int column) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::ChangedCursor(quint32 id) { for (qint32 i = 0; i< ui->tableWidget->rowCount(); ++i) @@ -112,12 +117,14 @@ void DialogHistory::ChangedCursor(quint32 id) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::UpdateHistory() { FillTable(); InitialTable(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::FillTable() { ui->tableWidget->clear(); @@ -165,6 +172,7 @@ void DialogHistory::FillTable() ui->tableWidget->verticalHeader()->setDefaultSectionSize(20); } +//--------------------------------------------------------------------------------------------------------------------- QString DialogHistory::Record(const VToolRecord &tool) { const QDomElement domElement = doc->elementById(QString().setNum(tool.getId())); @@ -407,6 +415,7 @@ QString DialogHistory::Record(const VToolRecord &tool) return QString(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::InitialTable() { ui->tableWidget->setSortingEnabled(false); @@ -414,6 +423,7 @@ void DialogHistory::InitialTable() ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Tool"))); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::ShowPoint() { QVector *history = doc->getHistory(); @@ -428,6 +438,7 @@ void DialogHistory::ShowPoint() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogHistory::closeEvent(QCloseEvent *event) { QTableWidgetItem *item = ui->tableWidget->item(cursorToolRecordRow, 0); diff --git a/src/app/dialogs/app/dialogincrements.cpp b/src/app/dialogs/app/dialogincrements.cpp index 4b0552647..d700c1d2e 100644 --- a/src/app/dialogs/app/dialogincrements.cpp +++ b/src/app/dialogs/app/dialogincrements.cpp @@ -40,6 +40,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogIncrements), data(data), doc(doc), row(0), column(0), m(nullptr) { @@ -135,6 +136,7 @@ DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *par connect(ui->toolButtonOpenMeasurements, &QToolButton::clicked, this, &DialogIncrements::OpenTable); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::FillMeasurements() { const QHash *table = data->DataMeasurements(); @@ -212,6 +214,7 @@ void DialogIncrements::FillMeasurements() ui->tableWidgetMeasurements->resizeRowsToContents(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::FillIncrements() { const QHash *increments = data->DataIncrements(); @@ -279,6 +282,7 @@ void DialogIncrements::FillIncrements() ui->tableWidgetIncrement->setCurrentCell( row, column ); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::FillLengthLines() { const QHash *linesTable = data->DataLengthLines(); @@ -314,6 +318,7 @@ void DialogIncrements::FillLengthLines() ui->tableWidgetLines->verticalHeader()->setDefaultSectionSize(20); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::FillLengthSplines() { const QHash *splinesTable = data->DataLengthSplines(); @@ -349,6 +354,7 @@ void DialogIncrements::FillLengthSplines() ui->tableWidgetSplines->verticalHeader()->setDefaultSectionSize(20); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::FillLengthArcs() { const QHash *arcsTable = data->DataLengthArcs(); @@ -384,6 +390,7 @@ void DialogIncrements::FillLengthArcs() ui->tableWidgetArcs->resizeRowsToContents(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::FullUpdateFromFile() { disconnect(ui->tableWidgetMeasurements, &QTableWidget::cellChanged, this, &DialogIncrements::MeasurementChanged); @@ -406,6 +413,7 @@ void DialogIncrements::FullUpdateFromFile() FillLengthArcs(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::SaveGivenName() { m->setGivenName(ui->lineEditGivenName->text()); @@ -415,6 +423,7 @@ void DialogIncrements::SaveGivenName() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::SaveFamilyName() { @@ -425,6 +434,7 @@ void DialogIncrements::SaveFamilyName() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::SaveEmail() { m->setMail(ui->lineEditMail->text()); @@ -434,6 +444,7 @@ void DialogIncrements::SaveEmail() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::SaveSex(int index) { m->setSex(m->StrToGender(ui->comboBoxSex->itemData(index).toString())); @@ -443,6 +454,7 @@ void DialogIncrements::SaveSex(int index) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::SaveBirthDate(const QDate & date) { m->setBirthDate(date); @@ -452,6 +464,7 @@ void DialogIncrements::SaveBirthDate(const QDate & date) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::OpenTable() { QString text = tr("Measurements use different units than pattern. This pattern required measurements in %1") @@ -539,6 +552,7 @@ void DialogIncrements::OpenTable() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::clickedToolButtonAdd() { ui->tableWidgetIncrement->setFocus(Qt::OtherFocusReason); @@ -599,6 +613,7 @@ void DialogIncrements::clickedToolButtonAdd() emit haveLiteChange(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::clickedToolButtonRemove() { disconnect(ui->tableWidgetIncrement, &QTableWidget::cellChanged, this, @@ -624,6 +639,7 @@ void DialogIncrements::clickedToolButtonRemove() emit haveLiteChange(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::AddIncrementToFile(const quint32 &id, const QString &name, const qreal &base, const qreal &ksize, const qreal &kheight, const QString &description) { @@ -640,6 +656,7 @@ void DialogIncrements::AddIncrementToFile(const quint32 &id, const QString &name list.at(0).appendChild(element); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::IncrementChanged ( qint32 row, qint32 column ) { @@ -694,6 +711,7 @@ void DialogIncrements::IncrementChanged ( qint32 row, qint32 column ) emit haveLiteChange(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::MeasurementChanged(qint32 row, qint32 column) { switch (column) @@ -740,12 +758,14 @@ void DialogIncrements::MeasurementChanged(qint32 row, qint32 column) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIncrements::closeEvent(QCloseEvent *event) { emit DialogClosed(QDialog::Accepted); event->accept(); } +//--------------------------------------------------------------------------------------------------------------------- DialogIncrements::~DialogIncrements() { delete ui; diff --git a/src/app/dialogs/app/dialogindividualmeasurements.cpp b/src/app/dialogs/app/dialogindividualmeasurements.cpp index e112a3012..4a096907d 100644 --- a/src/app/dialogs/app/dialogindividualmeasurements.cpp +++ b/src/app/dialogs/app/dialogindividualmeasurements.cpp @@ -36,6 +36,7 @@ #include "../../widgets/vapplication.h" #include +//--------------------------------------------------------------------------------------------------------------------- DialogIndividualMeasurements::DialogIndividualMeasurements(VContainer *data, const QString &patternPieceName, QWidget *parent) : QDialog(parent), ui(new Ui::DialogIndividualMeasurements), _name(patternPieceName), _tablePath(QString()), @@ -67,11 +68,13 @@ DialogIndividualMeasurements::DialogIndividualMeasurements(VContainer *data, con connect(ui->toolButtonOpenNew, &QToolButton::clicked, this, &DialogIndividualMeasurements::NewTable); } +//--------------------------------------------------------------------------------------------------------------------- DialogIndividualMeasurements::~DialogIndividualMeasurements() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::DialogAccepted() { _name = ui->lineEditName->text(); @@ -125,6 +128,7 @@ void DialogIndividualMeasurements::DialogAccepted() accept(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::DialogRejected() { _name.clear(); @@ -132,6 +136,7 @@ void DialogIndividualMeasurements::DialogRejected() reject(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::CheckState() { bool flagName = false; @@ -187,6 +192,7 @@ void DialogIndividualMeasurements::CheckState() bOk->setEnabled(flagName && flagPath && flagLang); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::LoadIndividualTables() { QStringList filters; @@ -236,6 +242,7 @@ void DialogIndividualMeasurements::LoadIndividualTables() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::OpenTable() { const QString filter(tr("Individual measurements (*.vit)")); @@ -259,6 +266,7 @@ void DialogIndividualMeasurements::OpenTable() CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::NewTable() { QString dir = QDir::homePath()+"/measurements.vit"; @@ -281,6 +289,7 @@ void DialogIndividualMeasurements::NewTable() CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogIndividualMeasurements::InitUnits() { ui->comboBoxUnits->addItem(tr("centimeter"), QVariant(VDomDocument::UnitsToStr(Valentina::Cm))); diff --git a/src/app/dialogs/app/dialogmeasurements.cpp b/src/app/dialogs/app/dialogmeasurements.cpp index 621e87f60..30b7d2967 100644 --- a/src/app/dialogs/app/dialogmeasurements.cpp +++ b/src/app/dialogs/app/dialogmeasurements.cpp @@ -29,6 +29,7 @@ #include "dialogmeasurements.h" #include "ui_dialogmeasurements.h" +//--------------------------------------------------------------------------------------------------------------------- DialogMeasurements::DialogMeasurements(QWidget *parent) : QDialog(parent), ui(new Ui::DialogMeasurements), result(Measurements::Individual) { @@ -37,22 +38,26 @@ DialogMeasurements::DialogMeasurements(QWidget *parent) : connect(ui->toolButtonIndividual, &QToolButton::clicked, this, &DialogMeasurements::IndividualMeasurements); } +//--------------------------------------------------------------------------------------------------------------------- DialogMeasurements::~DialogMeasurements() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- Measurements::Type DialogMeasurements::type() const { return result; } +//--------------------------------------------------------------------------------------------------------------------- void DialogMeasurements::StandardMeasurements() { result = Measurements::Standard; accept(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogMeasurements::IndividualMeasurements() { result = Measurements::Individual; diff --git a/src/app/dialogs/app/dialogpatternproperties.cpp b/src/app/dialogs/app/dialogpatternproperties.cpp index 5843bb240..bc0efe0e0 100644 --- a/src/app/dialogs/app/dialogpatternproperties.cpp +++ b/src/app/dialogs/app/dialogpatternproperties.cpp @@ -31,6 +31,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- DialogPatternProperties::DialogPatternProperties(VPattern *doc, QWidget *parent) : QDialog(parent), ui(new Ui::DialogPatternProperties), doc(doc) { @@ -61,11 +62,13 @@ DialogPatternProperties::DialogPatternProperties(VPattern *doc, QWidget *parent) connect(this, &DialogPatternProperties::haveChange, this->doc, &VPattern::haveLiteChange); } +//--------------------------------------------------------------------------------------------------------------------- DialogPatternProperties::~DialogPatternProperties() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogPatternProperties::Apply() { Write("notes", ui->plainTextEditTechNotes->document()->toPlainText()); @@ -75,6 +78,7 @@ void DialogPatternProperties::Apply() close(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPatternProperties::Write(const QString &tagName, const QString &text) const { QDomNodeList nodeList = doc->elementsByTagName(tagName); diff --git a/src/app/dialogs/app/dialogstandardmeasurements.cpp b/src/app/dialogs/app/dialogstandardmeasurements.cpp index 4a189bb2b..bc8a538c4 100644 --- a/src/app/dialogs/app/dialogstandardmeasurements.cpp +++ b/src/app/dialogs/app/dialogstandardmeasurements.cpp @@ -33,6 +33,7 @@ #include "../../widgets/vapplication.h" #include +//--------------------------------------------------------------------------------------------------------------------- DialogStandardMeasurements::DialogStandardMeasurements(VContainer *data, const QString &patternPieceName, QWidget *parent) : QDialog(parent), ui(new Ui::DialogStandardMeasurements), data(data), _name(patternPieceName), _tablePath(QString()) @@ -58,21 +59,25 @@ DialogStandardMeasurements::DialogStandardMeasurements(VContainer *data, const Q connect(ui->lineEditName, &QLineEdit::textChanged, this, &DialogStandardMeasurements::CheckState); } +//--------------------------------------------------------------------------------------------------------------------- DialogStandardMeasurements::~DialogStandardMeasurements() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- QString DialogStandardMeasurements::name() const { return _name; } +//--------------------------------------------------------------------------------------------------------------------- QString DialogStandardMeasurements::tablePath() const { return _tablePath; } +//--------------------------------------------------------------------------------------------------------------------- void DialogStandardMeasurements::DialogAccepted() { _name = ui->lineEditName->text(); @@ -96,6 +101,7 @@ void DialogStandardMeasurements::DialogAccepted() accept(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogStandardMeasurements::DialogRejected() { _name.clear(); @@ -103,6 +109,7 @@ void DialogStandardMeasurements::DialogRejected() reject(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogStandardMeasurements::CheckState() { bool flagName = false; @@ -126,6 +133,7 @@ void DialogStandardMeasurements::CheckState() bOk->setEnabled(flagTable && flagName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogStandardMeasurements::LoadStandardTables() { QStringList filters; diff --git a/src/app/dialogs/app/pages.cpp b/src/app/dialogs/app/pages.cpp index 50521eea4..476c941da 100644 --- a/src/app/dialogs/app/pages.cpp +++ b/src/app/dialogs/app/pages.cpp @@ -30,6 +30,7 @@ #include "../../options.h" #include "../../widgets/vapplication.h" +//--------------------------------------------------------------------------------------------------------------------- ConfigurationPage::ConfigurationPage(QWidget *parent): QWidget(parent), autoSaveCheck(0), autoTime(0), langCombo(0), osOptionCheck(0), langChanged(false) { @@ -43,6 +44,7 @@ ConfigurationPage::ConfigurationPage(QWidget *parent): setLayout(mainLayout); } +//--------------------------------------------------------------------------------------------------------------------- void ConfigurationPage::Apply() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -61,11 +63,13 @@ void ConfigurationPage::Apply() } } +//--------------------------------------------------------------------------------------------------------------------- void ConfigurationPage::LangChenged() { langChanged = true; } +//--------------------------------------------------------------------------------------------------------------------- QGroupBox *ConfigurationPage::SaveGroup() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -101,6 +105,7 @@ QGroupBox *ConfigurationPage::SaveGroup() return saveGroup; } +//--------------------------------------------------------------------------------------------------------------------- QGroupBox *ConfigurationPage::LangGroup() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -168,7 +173,7 @@ QGroupBox *ConfigurationPage::LangGroup() return langGroup; } - +//--------------------------------------------------------------------------------------------------------------------- PatternPage::PatternPage(QWidget *parent): QWidget(parent), userName(0), graphOutputCheck(0), undoneCount(0) { @@ -184,6 +189,7 @@ PatternPage::PatternPage(QWidget *parent): setLayout(mainLayout); } +//--------------------------------------------------------------------------------------------------------------------- void PatternPage::Apply() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -193,6 +199,7 @@ void PatternPage::Apply() settings.setValue("pattern/undone", undoneCount->value()); } +//--------------------------------------------------------------------------------------------------------------------- QGroupBox *PatternPage::UserGroup() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -219,6 +226,7 @@ QGroupBox *PatternPage::UserGroup() return userGroup; } +//--------------------------------------------------------------------------------------------------------------------- QGroupBox *PatternPage::GraphOutputGroup() { // QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -240,6 +248,7 @@ QGroupBox *PatternPage::GraphOutputGroup() return graphOutputGroup; } +//--------------------------------------------------------------------------------------------------------------------- QGroupBox *PatternPage::UndoneGroup() { // QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), diff --git a/src/app/dialogs/tools/dialogalongline.cpp b/src/app/dialogs/tools/dialogalongline.cpp index 539909950..c6f643d9d 100644 --- a/src/app/dialogs/tools/dialogalongline.cpp +++ b/src/app/dialogs/tools/dialogalongline.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogAlongLine::DialogAlongLine(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogAlongLine), number(0), pointName(QString()), typeLine(QString()), formula(QString()), firstPointId(0), secondPointId(0) @@ -59,11 +60,13 @@ DialogAlongLine::DialogAlongLine(const VContainer *data, QWidget *parent) connect(listWidget, &QListWidget::itemDoubleClicked, this, &DialogTool::PutVal); } +//--------------------------------------------------------------------------------------------------------------------- DialogAlongLine::~DialogAlongLine() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -90,6 +93,7 @@ void DialogAlongLine::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -100,28 +104,33 @@ void DialogAlongLine::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::setSecondPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxSecondPoint, secondPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::setFirstPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxFirstPoint, firstPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogAlongLine::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialogarc.cpp b/src/app/dialogs/tools/dialogarc.cpp index dc9d5e6c1..1344a1d52 100644 --- a/src/app/dialogs/tools/dialogarc.cpp +++ b/src/app/dialogs/tools/dialogarc.cpp @@ -32,6 +32,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- DialogArc::DialogArc(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogArc), flagRadius(false), flagF1(false), flagF2(false), timerRadius(nullptr), timerF1(nullptr), timerF2(nullptr), center(0), radius(QString()), f1(QString()), f2(QString()) @@ -68,35 +69,41 @@ DialogArc::DialogArc(const VContainer *data, QWidget *parent) connect(ui->lineEditF2, &QLineEdit::textChanged, this, &DialogArc::F2Changed); } +//--------------------------------------------------------------------------------------------------------------------- DialogArc::~DialogArc() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::SetCenter(const quint32 &value) { center = value; ChangeCurrentData(ui->comboBoxBasePoint, center); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::SetF2(const QString &value) { f2 = value; ui->lineEditF2->setText(f2); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::SetF1(const QString &value) { f1 = value; ui->lineEditF1->setText(f1); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::SetRadius(const QString &value) { radius = value; ui->lineEditRadius->setText(radius); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -109,6 +116,7 @@ void DialogArc::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::DialogAccepted() { radius = ui->lineEditRadius->text(); @@ -118,6 +126,7 @@ void DialogArc::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::ValChenged(int row) { if (ui->listWidget->count() == 0) @@ -135,68 +144,80 @@ void DialogArc::ValChenged(int row) DialogTool::ValChenged(row); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::PutRadius() { PutValHere(ui->lineEditRadius, ui->listWidget); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::PutF1() { PutValHere(ui->lineEditF1, ui->listWidget); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::PutF2() { PutValHere(ui->lineEditF2, ui->listWidget); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::LineAngles() { ShowLineAngles(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::RadiusChanged() { labelEditFormula = ui->labelEditRadius; ValFormulaChanged(flagRadius, ui->lineEditRadius, timerRadius); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::F1Changed() { labelEditFormula = ui->labelEditF1; ValFormulaChanged(flagF1, ui->lineEditF1, timerF1); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::F2Changed() { labelEditFormula = ui->labelEditF2; ValFormulaChanged(flagF2, ui->lineEditF2, timerF2); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::CheckState() { Q_CHECK_PTR(bOk); bOk->setEnabled(flagRadius && flagF1 && flagF2); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::EvalRadius() { labelEditFormula = ui->labelEditRadius; Eval(ui->lineEditRadius, flagRadius, timerRadius, ui->labelResultRadius); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::EvalF1() { labelEditFormula = ui->labelEditF1; Eval(ui->lineEditF1, flagF1, timerF1, ui->labelResultF1); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::EvalF2() { labelEditFormula = ui->labelEditF2; Eval(ui->lineEditF2, flagF2, timerF2, ui->labelResultF2); } +//--------------------------------------------------------------------------------------------------------------------- void DialogArc::ShowLineAngles() { disconnect(ui->listWidget, &QListWidget::currentRowChanged, this, &DialogArc::ValChenged); diff --git a/src/app/dialogs/tools/dialogbisector.cpp b/src/app/dialogs/tools/dialogbisector.cpp index 9fd74a8b0..35050a844 100644 --- a/src/app/dialogs/tools/dialogbisector.cpp +++ b/src/app/dialogs/tools/dialogbisector.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogBisector::DialogBisector(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogBisector), number(0), pointName(QString()), typeLine(QString()), formula(QString()), firstPointId(0), secondPointId(0), thirdPointId(0) @@ -59,11 +60,13 @@ DialogBisector::DialogBisector(const VContainer *data, QWidget *parent) connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogBisector::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogBisector::~DialogBisector() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -108,39 +111,46 @@ void DialogBisector::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::setPointName(const QString &value) { pointName = value; ui->lineEditNamePoint->setText(pointName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::setFirstPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxFirstPoint, firstPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::setSecondPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxSecondPoint, secondPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::setThirdPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxThirdPoint, thirdPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogBisector::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); diff --git a/src/app/dialogs/tools/dialogcutarc.cpp b/src/app/dialogs/tools/dialogcutarc.cpp index 3239bb371..55844e496 100644 --- a/src/app/dialogs/tools/dialogcutarc.cpp +++ b/src/app/dialogs/tools/dialogcutarc.cpp @@ -29,6 +29,7 @@ #include "dialogcutarc.h" #include "ui_dialogcutarc.h" +//--------------------------------------------------------------------------------------------------------------------- DialogCutArc::DialogCutArc(const VContainer *data, QWidget *parent) : DialogTool(data, parent), ui(new Ui::DialogCutArc), pointName(QString()), formula(QString()), arcId(0) { @@ -54,11 +55,13 @@ DialogCutArc::DialogCutArc(const VContainer *data, QWidget *parent) : connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogCutArc::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogCutArc::~DialogCutArc() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutArc::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Arc) @@ -70,6 +73,7 @@ void DialogCutArc::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutArc::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -78,17 +82,20 @@ void DialogCutArc::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutArc::setArcId(const quint32 &value, const quint32 &id) { setCurrentArcId(ui->comboBoxArc, arcId, value, id, ComboMode::CutArc); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutArc::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutArc::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialogcutspline.cpp b/src/app/dialogs/tools/dialogcutspline.cpp index 9ff85d2b1..1730ba10e 100644 --- a/src/app/dialogs/tools/dialogcutspline.cpp +++ b/src/app/dialogs/tools/dialogcutspline.cpp @@ -29,6 +29,7 @@ #include "dialogcutspline.h" #include "ui_dialogcutspline.h" +//--------------------------------------------------------------------------------------------------------------------- DialogCutSpline::DialogCutSpline(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogCutSpline), pointName(QString()), formula(QString()), splineId(0) { @@ -53,28 +54,33 @@ DialogCutSpline::DialogCutSpline(const VContainer *data, QWidget *parent) connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogCutSpline::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogCutSpline::~DialogCutSpline() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSpline::setPointName(const QString &value) { pointName = value; ui->lineEditNamePoint->setText(pointName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSpline::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSpline::setSplineId(const quint32 &value, const quint32 &id) { setCurrentSplineId(ui->comboBoxSpline, splineId, value, id, ComboMode::CutSpline); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSpline::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Spline) @@ -86,6 +92,7 @@ void DialogCutSpline::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSpline::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); diff --git a/src/app/dialogs/tools/dialogcutsplinepath.cpp b/src/app/dialogs/tools/dialogcutsplinepath.cpp index 4b6a51174..fee2d8f04 100644 --- a/src/app/dialogs/tools/dialogcutsplinepath.cpp +++ b/src/app/dialogs/tools/dialogcutsplinepath.cpp @@ -29,6 +29,7 @@ #include "dialogcutsplinepath.h" #include "ui_dialogcutsplinepath.h" +//--------------------------------------------------------------------------------------------------------------------- DialogCutSplinePath::DialogCutSplinePath(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogCutSplinePath), pointName(QString()), formula(QString()), splinePathId(0) @@ -54,28 +55,33 @@ DialogCutSplinePath::DialogCutSplinePath(const VContainer *data, QWidget *parent connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogCutSplinePath::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogCutSplinePath::~DialogCutSplinePath() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSplinePath::setPointName(const QString &value) { pointName = value; ui->lineEditNamePoint->setText(pointName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSplinePath::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSplinePath::setSplinePathId(const quint32 &value, const quint32 &id) { setCurrentSplinePathId(ui->comboBoxSplinePath, splinePathId, value, id, ComboMode::CutSpline); } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSplinePath::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::SplinePath) @@ -87,6 +93,7 @@ void DialogCutSplinePath::ChoosedObject(quint32 id, const Valentina::Scenes &typ } } +//--------------------------------------------------------------------------------------------------------------------- void DialogCutSplinePath::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); diff --git a/src/app/dialogs/tools/dialogdetail.cpp b/src/app/dialogs/tools/dialogdetail.cpp index 5cef2bfee..8b156c4ed 100644 --- a/src/app/dialogs/tools/dialogdetail.cpp +++ b/src/app/dialogs/tools/dialogdetail.cpp @@ -31,6 +31,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- DialogDetail::DialogDetail(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(), details(VDetail()), supplement(true), closed(true) { @@ -62,6 +63,7 @@ DialogDetail::DialogDetail(const VContainer *data, QWidget *parent) connect(ui.toolButtonDelete, &QToolButton::clicked, this, &DialogDetail::DeleteItem); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type != Valentina::Line && type != Valentina::Detail) @@ -89,6 +91,7 @@ void DialogDetail::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::DialogAccepted() { details.Clear(); @@ -105,6 +108,7 @@ void DialogDetail::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::NewItem(quint32 id, const Valentina::Tools &typeTool, const NodeDetail::NodeDetails &typeNode, qreal mx, qreal my) { @@ -158,6 +162,7 @@ void DialogDetail::NewItem(quint32 id, const Valentina::Tools &typeTool, const N this, &DialogDetail::BiasYChanged); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::setDetails(const VDetail &value) { details = value; @@ -178,6 +183,7 @@ void DialogDetail::setDetails(const VDetail &value) ui.toolButtonDelete->setEnabled(true); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::BiasXChanged(qreal d) { qint32 row = ui.listWidget->currentRow(); @@ -188,6 +194,7 @@ void DialogDetail::BiasXChanged(qreal d) item->setData(Qt::UserRole, QVariant::fromValue(node)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::BiasYChanged(qreal d) { qint32 row = ui.listWidget->currentRow(); @@ -198,6 +205,7 @@ void DialogDetail::BiasYChanged(qreal d) item->setData(Qt::UserRole, QVariant::fromValue(node)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::ClickedSeams(bool checked) { supplement = checked; @@ -205,11 +213,13 @@ void DialogDetail::ClickedSeams(bool checked) ui.spinBoxSeams->setEnabled(checked); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::ClickedClosed(bool checked) { closed = checked; } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::ObjectChanged(int row) { if (ui.listWidget->count() == 0) @@ -222,6 +232,7 @@ void DialogDetail::ObjectChanged(int row) ui.spinBoxBiasY->setValue(static_cast(qApp->fromPixel(node.getMy()))); } +//--------------------------------------------------------------------------------------------------------------------- void DialogDetail::DeleteItem() { qint32 row = ui.listWidget->currentRow(); diff --git a/src/app/dialogs/tools/dialogendline.cpp b/src/app/dialogs/tools/dialogendline.cpp index c096433f9..b9b1b4279 100644 --- a/src/app/dialogs/tools/dialogendline.cpp +++ b/src/app/dialogs/tools/dialogendline.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogEndLine::DialogEndLine(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogEndLine), pointName(QString()), typeLine(QString()), formula(QString()), angle(0), basePointId(0) @@ -59,6 +60,7 @@ DialogEndLine::DialogEndLine(const VContainer *data, QWidget *parent) connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogEndLine::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -70,35 +72,41 @@ void DialogEndLine::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::setPointName(const QString &value) { pointName = value; ui->lineEditNamePoint->setText(pointName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::setAngle(const qreal &value) { angle = value; ui->doubleSpinBoxAngle->setValue(angle); } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::setBasePointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxBasePoint, basePointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogEndLine::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -109,6 +117,7 @@ void DialogEndLine::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- DialogEndLine::~DialogEndLine() { delete ui; diff --git a/src/app/dialogs/tools/dialogheight.cpp b/src/app/dialogs/tools/dialogheight.cpp index ac3e1f437..455479962 100644 --- a/src/app/dialogs/tools/dialogheight.cpp +++ b/src/app/dialogs/tools/dialogheight.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogHeight::DialogHeight(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogHeight), number(0), pointName(QString()), typeLine(QString()), basePointId(0), p1LineId(0), p2LineId(0) @@ -48,41 +49,48 @@ DialogHeight::DialogHeight(const VContainer *data, QWidget *parent) connect(ui->lineEditNamePoint, &QLineEdit::textChanged, this, &DialogHeight::NamePointChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogHeight::~DialogHeight() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::setPointName(const QString &value) { pointName = value; ui->lineEditNamePoint->setText(pointName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::setBasePointId(const quint32 &value, const quint32 &id) { basePointId = value; setCurrentPointId(ui->comboBoxBasePoint, basePointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::setP1LineId(const quint32 &value, const quint32 &id) { p1LineId = value; setCurrentPointId(ui->comboBoxP1Line, p1LineId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::setP2LineId(const quint32 &value, const quint32 &id) { p2LineId = value; setCurrentPointId(ui->comboBoxP2Line, p2LineId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -115,6 +123,7 @@ void DialogHeight::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogHeight::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); diff --git a/src/app/dialogs/tools/dialogline.cpp b/src/app/dialogs/tools/dialogline.cpp index 78d2d3f05..a87a5410c 100644 --- a/src/app/dialogs/tools/dialogline.cpp +++ b/src/app/dialogs/tools/dialogline.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogLine::DialogLine(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogLine), number(0), firstPoint(0), secondPoint(0), typeLine(QString()) { @@ -44,11 +45,13 @@ DialogLine::DialogLine(const VContainer *data, QWidget *parent) number = 0; } +//--------------------------------------------------------------------------------------------------------------------- DialogLine::~DialogLine() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogLine::setSecondPoint(const quint32 &value) { secondPoint = value; @@ -60,12 +63,14 @@ void DialogLine::setSecondPoint(const quint32 &value) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogLine::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLine::setFirstPoint(const quint32 &value) { firstPoint = value; @@ -77,7 +82,7 @@ void DialogLine::setFirstPoint(const quint32 &value) } } - +//--------------------------------------------------------------------------------------------------------------------- void DialogLine::DialogAccepted() { qint32 index = ui->comboBoxFirstPoint->currentIndex(); @@ -88,6 +93,7 @@ void DialogLine::DialogAccepted() DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLine::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) diff --git a/src/app/dialogs/tools/dialoglineintersect.cpp b/src/app/dialogs/tools/dialoglineintersect.cpp index a1e3fb66b..9951ee884 100644 --- a/src/app/dialogs/tools/dialoglineintersect.cpp +++ b/src/app/dialogs/tools/dialoglineintersect.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogLineIntersect::DialogLineIntersect(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogLineIntersect), number(0), pointName(QString()), p1Line1(0), p2Line1(0), p1Line2(0), p2Line2(0), flagPoint(true) @@ -49,11 +50,13 @@ DialogLineIntersect::DialogLineIntersect(const VContainer *data, QWidget *parent connect(ui->lineEditNamePoint, &QLineEdit::textChanged, this, &DialogLineIntersect::NamePointChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogLineIntersect::~DialogLineIntersect() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -127,6 +130,7 @@ void DialogLineIntersect::ChoosedObject(quint32 id, const Valentina::Scenes &typ } } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -137,6 +141,7 @@ void DialogLineIntersect::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::P1Line1Changed( int index) { p1Line1 = qvariant_cast(ui->comboBoxP1Line1->itemData(index)); @@ -144,6 +149,7 @@ void DialogLineIntersect::P1Line1Changed( int index) CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::P2Line1Changed(int index) { p2Line1 = qvariant_cast(ui->comboBoxP2Line1->itemData(index)); @@ -151,6 +157,7 @@ void DialogLineIntersect::P2Line1Changed(int index) CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::P1Line2Changed(int index) { p1Line2 = qvariant_cast(ui->comboBoxP1Line2->itemData(index)); @@ -158,6 +165,7 @@ void DialogLineIntersect::P1Line2Changed(int index) CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::P2Line2Changed(int index) { p2Line2 = qvariant_cast(ui->comboBoxP2Line2->itemData(index)); @@ -165,12 +173,14 @@ void DialogLineIntersect::P2Line2Changed(int index) CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::CheckState() { Q_CHECK_PTR(bOk); bOk->setEnabled(flagName && flagPoint); } +//--------------------------------------------------------------------------------------------------------------------- bool DialogLineIntersect::CheckIntersecion() { const VPointF *p1L1 = data->GeometricObject(p1Line1); @@ -192,30 +202,35 @@ bool DialogLineIntersect::CheckIntersecion() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::setP2Line2(const quint32 &value) { p2Line2 = value; ChangeCurrentData(ui->comboBoxP2Line2, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::setP1Line2(const quint32 &value) { p1Line2 = value; ChangeCurrentData(ui->comboBoxP1Line2, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::setP2Line1(const quint32 &value) { p2Line1 = value; ChangeCurrentData(ui->comboBoxP2Line1, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::setP1Line1(const quint32 &value) { p1Line1 = value; ChangeCurrentData(ui->comboBoxP1Line1, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogLineIntersect::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialognormal.cpp b/src/app/dialogs/tools/dialognormal.cpp index 851cd40a3..81ebf9dd3 100644 --- a/src/app/dialogs/tools/dialognormal.cpp +++ b/src/app/dialogs/tools/dialognormal.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogNormal::DialogNormal(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogNormal), number(0), pointName(QString()), typeLine(QString()), formula(QString()), angle(0), firstPointId(0), secondPointId(0) @@ -60,11 +61,13 @@ DialogNormal::DialogNormal(const VContainer *data, QWidget *parent) connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogNormal::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogNormal::~DialogNormal() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -91,6 +94,7 @@ void DialogNormal::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -102,34 +106,40 @@ void DialogNormal::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::setSecondPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxSecondPoint, secondPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::setFirstPointId(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxFirstPoint, firstPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::setAngle(const qreal &value) { angle = value; ui->doubleSpinBoxAngle->setValue(angle); } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogNormal::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialogpointofcontact.cpp b/src/app/dialogs/tools/dialogpointofcontact.cpp index 7f024a6d9..55237da5b 100644 --- a/src/app/dialogs/tools/dialogpointofcontact.cpp +++ b/src/app/dialogs/tools/dialogpointofcontact.cpp @@ -30,6 +30,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogPointOfContact::DialogPointOfContact(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(), number(0), pointName(QString()), radius(QString()), center(0), firstPoint(0), secondPoint(0) @@ -87,6 +88,7 @@ DialogPointOfContact::DialogPointOfContact(const VContainer *data, QWidget *pare connect(ui.lineEditFormula, &QLineEdit::textChanged, this, &DialogPointOfContact::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -131,6 +133,7 @@ void DialogPointOfContact::ChoosedObject(quint32 id, const Valentina::Scenes &ty } } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::DialogAccepted() { pointName = ui.lineEditNamePoint->text(); @@ -141,28 +144,33 @@ void DialogPointOfContact::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::setSecondPoint(const quint32 &value, const quint32 &id) { setCurrentPointId(ui.comboBoxSecondPoint, secondPoint, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::setFirstPoint(const quint32 &value, const quint32 &id) { setCurrentPointId(ui.comboBoxFirstPoint, firstPoint, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::setCenter(const quint32 &value, const quint32 &id) { setCurrentPointId(ui.comboBoxCenter, center, value, id); center = value; } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::setRadius(const QString &value) { radius = value; ui.lineEditFormula->setText(radius); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfContact::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialogpointofintersection.cpp b/src/app/dialogs/tools/dialogpointofintersection.cpp index 52297d452..82538e73c 100644 --- a/src/app/dialogs/tools/dialogpointofintersection.cpp +++ b/src/app/dialogs/tools/dialogpointofintersection.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogPointOfIntersection::DialogPointOfIntersection(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogPointOfIntersection), number(0), pointName(QString()), firstPointId(0), secondPointId(0) @@ -47,17 +48,20 @@ DialogPointOfIntersection::DialogPointOfIntersection(const VContainer *data, QWi connect(ui->lineEditNamePoint, &QLineEdit::textChanged, this, &DialogPointOfIntersection::NamePointChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogPointOfIntersection::~DialogPointOfIntersection() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfIntersection::setSecondPointId(const quint32 &value, const quint32 &id) { secondPointId = value; setCurrentPointId(ui->comboBoxSecondPoint, secondPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfIntersection::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -91,6 +95,7 @@ void DialogPointOfIntersection::ChoosedObject(quint32 id, const Valentina::Scene } } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfIntersection::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -99,12 +104,14 @@ void DialogPointOfIntersection::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfIntersection::setFirstPointId(const quint32 &value, const quint32 &id) { firstPointId = value; setCurrentPointId(ui->comboBoxFirstPoint, firstPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogPointOfIntersection::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialogshoulderpoint.cpp b/src/app/dialogs/tools/dialogshoulderpoint.cpp index 21ae6e598..65fb7f069 100644 --- a/src/app/dialogs/tools/dialogshoulderpoint.cpp +++ b/src/app/dialogs/tools/dialogshoulderpoint.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogShoulderPoint::DialogShoulderPoint(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogShoulderPoint), number(0), pointName(QString()), typeLine(QString()), formula(QString()), p1Line(0), p2Line(0), pShoulder(0) @@ -60,11 +61,13 @@ DialogShoulderPoint::DialogShoulderPoint(const VContainer *data, QWidget *parent connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogShoulderPoint::FormulaChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogShoulderPoint::~DialogShoulderPoint() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -109,6 +112,7 @@ void DialogShoulderPoint::ChoosedObject(quint32 id, const Valentina::Scenes &typ } } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -120,33 +124,39 @@ void DialogShoulderPoint::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::setPShoulder(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxPShoulder, pShoulder, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::setP2Line(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxP2Line, p2Line, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::setP1Line(const quint32 &value, const quint32 &id) { setCurrentPointId(ui->comboBoxP1Line, p1Line, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::setFormula(const QString &value) { formula = value; ui->lineEditFormula->setText(formula); } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::setTypeLine(const QString &value) { typeLine = value; SetupTypeLine(ui->comboBoxLineType, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogShoulderPoint::setPointName(const QString &value) { pointName = value; diff --git a/src/app/dialogs/tools/dialogsinglepoint.cpp b/src/app/dialogs/tools/dialogsinglepoint.cpp index 2df4c0f8e..80d5c8fb0 100644 --- a/src/app/dialogs/tools/dialogsinglepoint.cpp +++ b/src/app/dialogs/tools/dialogsinglepoint.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogSinglePoint::DialogSinglePoint(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogSinglePoint), name(QString()), point(QPointF()) @@ -47,6 +48,7 @@ DialogSinglePoint::DialogSinglePoint(const VContainer *data, QWidget *parent) connect(ui->lineEditName, &QLineEdit::textChanged, this, &DialogSinglePoint::NamePointChanged); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSinglePoint::mousePress(const QPointF &scenePos) { if (isInitialized == false) @@ -62,6 +64,7 @@ void DialogSinglePoint::mousePress(const QPointF &scenePos) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogSinglePoint::DialogAccepted() { point = QPointF(qApp->toPixel(ui->doubleSpinBoxX->value()), qApp->toPixel(ui->doubleSpinBoxY->value())); @@ -69,6 +72,7 @@ void DialogSinglePoint::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSinglePoint::setData(const QString &name, const QPointF &point) { this->name = name; @@ -79,6 +83,7 @@ void DialogSinglePoint::setData(const QString &name, const QPointF &point) ui->doubleSpinBoxY->setValue(qApp->fromPixel(point.y())); } +//--------------------------------------------------------------------------------------------------------------------- DialogSinglePoint::~DialogSinglePoint() { delete ui; diff --git a/src/app/dialogs/tools/dialogspline.cpp b/src/app/dialogs/tools/dialogspline.cpp index 615834b03..1030aea47 100644 --- a/src/app/dialogs/tools/dialogspline.cpp +++ b/src/app/dialogs/tools/dialogspline.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogSpline::DialogSpline(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogSpline), number(0), p1(0), p4(0), angle1(0), angle2(0), kAsm1(1), kAsm2(1), kCurve(1) @@ -42,16 +43,19 @@ DialogSpline::DialogSpline(const VContainer *data, QWidget *parent) FillComboBoxPoints(ui->comboBoxP4); } +//--------------------------------------------------------------------------------------------------------------------- DialogSpline::~DialogSpline() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- quint32 DialogSpline::getP1() const { return p1; } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -93,6 +97,7 @@ void DialogSpline::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::DialogAccepted() { p1 = getCurrentObjectId(ui->comboBoxP1); @@ -105,48 +110,56 @@ void DialogSpline::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setKCurve(const qreal &value) { kCurve = value; ui->doubleSpinBoxKcurve->setValue(value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setKAsm2(const qreal &value) { kAsm2 = value; ui->doubleSpinBoxKasm2->setValue(value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setKAsm1(const qreal &value) { kAsm1 = value; ui->doubleSpinBoxKasm1->setValue(value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setAngle2(const qreal &value) { angle2 = value; ui->spinBoxAngle2->setValue(static_cast(value)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setAngle1(const qreal &value) { angle1 = value; ui->spinBoxAngle1->setValue(static_cast(value)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setP4(const quint32 &value) { p4 = value; ChangeCurrentData(ui->comboBoxP4, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSpline::setP1(const quint32 &value) { p1 = value; ChangeCurrentData(ui->comboBoxP1, value); } +//--------------------------------------------------------------------------------------------------------------------- quint32 DialogSpline::getP4() const { return p4; diff --git a/src/app/dialogs/tools/dialogsplinepath.cpp b/src/app/dialogs/tools/dialogsplinepath.cpp index 8fc9c5960..67b732663 100644 --- a/src/app/dialogs/tools/dialogsplinepath.cpp +++ b/src/app/dialogs/tools/dialogsplinepath.cpp @@ -32,6 +32,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogSplinePath::DialogSplinePath(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogSplinePath), path(VSplinePath()) { @@ -54,11 +55,13 @@ DialogSplinePath::DialogSplinePath(const VContainer *data, QWidget *parent) this, &DialogSplinePath::KAsm2Changed); } +//--------------------------------------------------------------------------------------------------------------------- DialogSplinePath::~DialogSplinePath() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::SetPath(const VSplinePath &value) { this->path = value; @@ -71,7 +74,7 @@ void DialogSplinePath::SetPath(const VSplinePath &value) ui->doubleSpinBoxKcurve->setValue(path.getKCurve()); } - +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -82,6 +85,7 @@ void DialogSplinePath::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::DialogAccepted() { path.Clear(); @@ -95,6 +99,7 @@ void DialogSplinePath::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::PointChanged(int row) { if (ui->listWidget->count() == 0) @@ -107,6 +112,7 @@ void DialogSplinePath::PointChanged(int row) EnableFields(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::currentPointChanged(int index) { quint32 id = qvariant_cast(ui->comboBoxPoint->itemData(index)); @@ -120,6 +126,7 @@ void DialogSplinePath::currentPointChanged(int index) item->setData(Qt::UserRole, QVariant::fromValue(p)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::Angle1Changed(qreal index) { qint32 row = ui->listWidget->currentRow(); @@ -131,6 +138,7 @@ void DialogSplinePath::Angle1Changed(qreal index) item->setData(Qt::UserRole, QVariant::fromValue(p)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::Angle2Changed(qreal index) { qint32 row = ui->listWidget->currentRow(); @@ -142,6 +150,7 @@ void DialogSplinePath::Angle2Changed(qreal index) item->setData(Qt::UserRole, QVariant::fromValue(p)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::KAsm1Changed(qreal d) { qint32 row = ui->listWidget->currentRow(); @@ -151,6 +160,7 @@ void DialogSplinePath::KAsm1Changed(qreal d) item->setData(Qt::UserRole, QVariant::fromValue(p)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::KAsm2Changed(qreal d) { qint32 row = ui->listWidget->currentRow(); @@ -160,6 +170,7 @@ void DialogSplinePath::KAsm2Changed(qreal d) item->setData(Qt::UserRole, QVariant::fromValue(p)); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::NewItem(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2) { const VPointF *point = data->GeometricObject(id); @@ -178,6 +189,7 @@ void DialogSplinePath::NewItem(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm EnableFields(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::DataPoint(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2) { disconnect(ui->comboBoxPoint, static_cast(&QComboBox::currentIndexChanged), @@ -209,6 +221,7 @@ void DialogSplinePath::DataPoint(quint32 id, qreal kAsm1, qreal angle1, qreal kA this, &DialogSplinePath::KAsm2Changed); } +//--------------------------------------------------------------------------------------------------------------------- void DialogSplinePath::EnableFields() { ui->doubleSpinBoxKasm1->setEnabled(true); diff --git a/src/app/dialogs/tools/dialogtool.cpp b/src/app/dialogs/tools/dialogtool.cpp index e9294d7f1..c10df30c0 100644 --- a/src/app/dialogs/tools/dialogtool.cpp +++ b/src/app/dialogs/tools/dialogtool.cpp @@ -33,6 +33,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogTool::DialogTool(const VContainer *data, QWidget *parent) :QDialog(parent), data(data), isInitialized(false), flagName(true), flagFormula(true), timerFormula(nullptr), bOk(nullptr), spinBoxAngle(nullptr), lineEditFormula(nullptr), listWidget(nullptr), @@ -51,12 +52,14 @@ DialogTool::DialogTool(const VContainer *data, QWidget *parent) setWindowFlags(flags | Qt::WindowStaysOnTopHint); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::closeEvent(QCloseEvent *event) { DialogClosed(QDialog::Rejected); event->accept(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::showEvent(QShowEvent *event) { QDialog::showEvent( event ); @@ -71,6 +74,7 @@ void DialogTool::showEvent(QShowEvent *event) isInitialized = true;//first show windows are held } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FillComboBoxPoints(QComboBox *box, const quint32 &id) const { Q_CHECK_PTR(box); @@ -93,6 +97,7 @@ void DialogTool::FillComboBoxPoints(QComboBox *box, const quint32 &id) const FillList(box, list); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FillComboBoxArcs(QComboBox *box, const quint32 &id, ComboMode::ComboBoxCutArc cut) const { Q_CHECK_PTR(box); @@ -130,6 +135,7 @@ void DialogTool::FillComboBoxArcs(QComboBox *box, const quint32 &id, ComboMode:: FillList(box, list); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FillComboBoxSplines(QComboBox *box, const quint32 &id, ComboMode::ComboBoxCutSpline cut) const { Q_CHECK_PTR(box); @@ -167,6 +173,7 @@ void DialogTool::FillComboBoxSplines(QComboBox *box, const quint32 &id, ComboMod FillList(box, list); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FillComboBoxSplinesPath(QComboBox *box, const quint32 &id, ComboMode::ComboBoxCutSpline cut) const { Q_CHECK_PTR(box); @@ -204,6 +211,7 @@ void DialogTool::FillComboBoxSplinesPath(QComboBox *box, const quint32 &id, Comb FillList(box, list); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FillComboBoxTypeLine(QComboBox *box) const { Q_CHECK_PTR(box); @@ -211,6 +219,7 @@ void DialogTool::FillComboBoxTypeLine(QComboBox *box) const box->setCurrentIndex(1); } +//--------------------------------------------------------------------------------------------------------------------- QString DialogTool::GetTypeLine(const QComboBox *box) const { switch (lineStyles.indexOf(box->currentText())) @@ -239,6 +248,7 @@ QString DialogTool::GetTypeLine(const QComboBox *box) const } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::SetupTypeLine(QComboBox *box, const QString &value) { QStringList styles = VAbstractTool::Styles(); @@ -249,6 +259,7 @@ void DialogTool::SetupTypeLine(QComboBox *box, const QString &value) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ChangeCurrentText(QComboBox *box, const QString &value) { qint32 index = box->findText(value); @@ -262,6 +273,7 @@ void DialogTool::ChangeCurrentText(QComboBox *box, const QString &value) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ChangeCurrentData(QComboBox *box, const quint32 &value) const { qint32 index = box->findData(value); @@ -271,6 +283,7 @@ void DialogTool::ChangeCurrentData(QComboBox *box, const quint32 &value) const } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::PutValHere(QLineEdit *lineEdit, QListWidget *listWidget) { Q_CHECK_PTR(lineEdit); @@ -283,6 +296,7 @@ void DialogTool::PutValHere(QLineEdit *lineEdit, QListWidget *listWidget) lineEdit->setCursorPosition(pos + item->text().size()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer *timer) { Q_CHECK_PTR(edit); @@ -300,6 +314,7 @@ void DialogTool::ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer *timer) timer->start(1000); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::Eval(QLineEdit *edit, bool &flag, QTimer *timer, QLabel *label) { Q_CHECK_PTR(edit); @@ -335,6 +350,7 @@ void DialogTool::Eval(QLineEdit *edit, bool &flag, QTimer *timer, QLabel *label) labelEditFormula->setPalette(palette); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::setCurrentPointId(QComboBox *box, quint32 &pointId, const quint32 &value, const quint32 &id) const { Q_CHECK_PTR(box); @@ -343,6 +359,7 @@ void DialogTool::setCurrentPointId(QComboBox *box, quint32 &pointId, const quint ChangeCurrentData(box, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::setCurrentSplineId(QComboBox *box, quint32 &splineId, const quint32 &value, const quint32 &id, ComboMode::ComboBoxCutSpline cut) const { @@ -352,6 +369,7 @@ void DialogTool::setCurrentSplineId(QComboBox *box, quint32 &splineId, const qui ChangeCurrentData(box, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::setCurrentArcId(QComboBox *box, quint32 &arcId, const quint32 &value, const quint32 &id, ComboMode::ComboBoxCutArc cut) const { @@ -361,6 +379,7 @@ void DialogTool::setCurrentArcId(QComboBox *box, quint32 &arcId, const quint32 & ChangeCurrentData(box, value); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::setCurrentSplinePathId(QComboBox *box, quint32 &splinePathId, const quint32 &value, const quint32 &id, ComboMode::ComboBoxCutSpline cut) const { @@ -370,6 +389,7 @@ void DialogTool::setCurrentSplinePathId(QComboBox *box, quint32 &splinePathId, c ChangeCurrentData(box, value); } +//--------------------------------------------------------------------------------------------------------------------- quint32 DialogTool::getCurrentObjectId(QComboBox *box) const { Q_CHECK_PTR(box); @@ -385,6 +405,7 @@ quint32 DialogTool::getCurrentObjectId(QComboBox *box) const } } +//--------------------------------------------------------------------------------------------------------------------- bool DialogTool::ChoosedPoint(const quint32 &id, QComboBox *box, const QString &toolTip) { Q_CHECK_PTR(box); @@ -400,6 +421,7 @@ bool DialogTool::ChoosedPoint(const quint32 &id, QComboBox *box, const QString & return false; } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FillList(QComboBox *box, const QMap &list) const { Q_CHECK_PTR(box); @@ -413,18 +435,21 @@ void DialogTool::FillList(QComboBox *box, const QMap &list) co } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::CheckState() { Q_CHECK_PTR(bOk); bOk->setEnabled(flagFormula && flagName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ChoosedObject(quint32 id, const Valentina::Scenes &type) { Q_UNUSED(id); Q_UNUSED(type); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::NamePointChanged() { Q_CHECK_PTR(labelEditNamePoint); @@ -450,16 +475,19 @@ void DialogTool::NamePointChanged() CheckState(); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::DialogAccepted() { emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::DialogRejected() { emit DialogClosed(QDialog::Rejected); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::FormulaChanged() { QLineEdit* edit = qobject_cast(sender()); @@ -469,54 +497,63 @@ void DialogTool::FormulaChanged() } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowUp() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(90); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowDown() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(270); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowLeft() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(180); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowRight() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(0); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowLeftUp() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(135); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowLeftDown() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(225); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowRightUp() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(45); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ArrowRightDown() { Q_CHECK_PTR(spinBoxAngle); spinBoxAngle->setValue(315); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::EvalFormula() { Q_CHECK_PTR(lineEditFormula); @@ -524,6 +561,7 @@ void DialogTool::EvalFormula() Eval(lineEditFormula, flagFormula, timerFormula, labelResultCalculation); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::SizeHeight() { Q_CHECK_PTR(listWidget); @@ -544,36 +582,43 @@ void DialogTool::SizeHeight() listWidget->setCurrentRow (0); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::Measurements() { ShowVariable(data->DataMeasurements()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::LengthLines() { ShowVariable(data->DataLengthLines()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::LengthArcs() { ShowVariable(data->DataLengthArcs()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::LengthCurves() { ShowVariable(data->DataLengthSplines()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::Increments() { ShowVariable(data->DataIncrements()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::PutHere() { PutValHere(lineEditFormula, listWidget); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::PutVal(QListWidgetItem *item) { Q_CHECK_PTR(lineEditFormula); @@ -585,6 +630,7 @@ void DialogTool::PutVal(QListWidgetItem *item) lineEditFormula->setCursorPosition(pos + item->text().size()); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::ValChenged(int row) { Q_CHECK_PTR(listWidget); @@ -653,6 +699,7 @@ void DialogTool::ValChenged(int row) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTool::UpdateList() { Q_CHECK_PTR(radioButtonSizeGrowth); @@ -688,6 +735,7 @@ void DialogTool::UpdateList() } } +//--------------------------------------------------------------------------------------------------------------------- template void DialogTool::ShowVariable(const QHash *var) { diff --git a/src/app/dialogs/tools/dialogtriangle.cpp b/src/app/dialogs/tools/dialogtriangle.cpp index 83604fd70..9a1ebb5ce 100644 --- a/src/app/dialogs/tools/dialogtriangle.cpp +++ b/src/app/dialogs/tools/dialogtriangle.cpp @@ -31,6 +31,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- DialogTriangle::DialogTriangle(const VContainer *data, QWidget *parent) :DialogTool(data, parent), ui(new Ui::DialogTriangle), number(0), pointName(QString()), axisP1Id(0), axisP2Id(0), firstPointId(0), secondPointId(0) @@ -49,11 +50,13 @@ DialogTriangle::DialogTriangle(const VContainer *data, QWidget *parent) connect(ui->lineEditNamePoint, &QLineEdit::textChanged, this, &DialogTriangle::NamePointChanged); } +//--------------------------------------------------------------------------------------------------------------------- DialogTriangle::~DialogTriangle() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (type == Valentina::Point) @@ -91,6 +94,7 @@ void DialogTriangle::ChoosedObject(quint32 id, const Valentina::Scenes &type) } } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::DialogAccepted() { pointName = ui->lineEditNamePoint->text(); @@ -101,30 +105,35 @@ void DialogTriangle::DialogAccepted() emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::setPointName(const QString &value) { pointName = value; ui->lineEditNamePoint->setText(pointName); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::setSecondPointId(const quint32 &value, const quint32 &id) { secondPointId = value; setCurrentPointId(ui->comboBoxSecondPoint, secondPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::setFirstPointId(const quint32 &value, const quint32 &id) { firstPointId = value; setCurrentPointId(ui->comboBoxFirstPoint, firstPointId, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::setAxisP2Id(const quint32 &value, const quint32 &id) { axisP2Id = value; setCurrentPointId(ui->comboBoxAxisP2, axisP2Id, value, id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogTriangle::setAxisP1Id(const quint32 &value, const quint32 &id) { axisP1Id = value; diff --git a/src/app/dialogs/tools/dialoguniondetails.cpp b/src/app/dialogs/tools/dialoguniondetails.cpp index 1bc93d7ae..d9a7135ce 100644 --- a/src/app/dialogs/tools/dialoguniondetails.cpp +++ b/src/app/dialogs/tools/dialoguniondetails.cpp @@ -29,6 +29,7 @@ #include "dialoguniondetails.h" #include "ui_dialoguniondetails.h" +//--------------------------------------------------------------------------------------------------------------------- DialogUnionDetails::DialogUnionDetails(const VContainer *data, QWidget *parent) : DialogTool(data, parent), ui(new Ui::DialogUnionDetails), indexD1(0), indexD2(0), d1(0), d2(0), numberD(0), numberP(0), p1(0), p2(0) @@ -37,11 +38,13 @@ DialogUnionDetails::DialogUnionDetails(const VContainer *data, QWidget *parent) InitOkCansel(ui); } +//--------------------------------------------------------------------------------------------------------------------- DialogUnionDetails::~DialogUnionDetails() { delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void DialogUnionDetails::ChoosedObject(quint32 id, const Valentina::Scenes &type) { if (numberD == 0) @@ -54,11 +57,13 @@ void DialogUnionDetails::ChoosedObject(quint32 id, const Valentina::Scenes &type } } +//--------------------------------------------------------------------------------------------------------------------- void DialogUnionDetails::DialogAccepted() { emit DialogClosed(QDialog::Accepted); } +//--------------------------------------------------------------------------------------------------------------------- bool DialogUnionDetails::CheckObject(const quint32 &id, const quint32 &idDetail) const { if (idDetail == 0) @@ -69,6 +74,7 @@ bool DialogUnionDetails::CheckObject(const quint32 &id, const quint32 &idDetail) return det.Containes(id); } +//--------------------------------------------------------------------------------------------------------------------- void DialogUnionDetails::ChoosedDetail(const quint32 &id, const Valentina::Scenes &type, quint32 &idDetail, ptrdiff_t &index) { diff --git a/src/app/exception/vexception.cpp b/src/app/exception/vexception.cpp index aaffd3e54..5cbc0192c 100644 --- a/src/app/exception/vexception.cpp +++ b/src/app/exception/vexception.cpp @@ -31,22 +31,24 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- VException::VException(const QString &what):QException(), what(what), moreInfo(QString()) { Q_ASSERT_X(what.isEmpty() == false, Q_FUNC_INFO, "Error message is empty"); } +//--------------------------------------------------------------------------------------------------------------------- VException::VException(const VException &e):what(e.What()), moreInfo(e.MoreInformation()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- QString VException::ErrorMessage() const { QString error = QString("Exception: %1").arg(what); return error; } +//--------------------------------------------------------------------------------------------------------------------- void VException::CriticalMessageBox(const QString &situation, QWidget * parent) const { QMessageBox msgBox(parent); @@ -67,6 +69,7 @@ void VException::CriticalMessageBox(const QString &situation, QWidget * parent) msgBox.exec(); } +//--------------------------------------------------------------------------------------------------------------------- void VException::AddMoreInformation(const QString &info) { if (info.isEmpty()) @@ -76,6 +79,7 @@ void VException::AddMoreInformation(const QString &info) moreInfo = QString("%1\n%2").arg(moreInfo, info); } +//--------------------------------------------------------------------------------------------------------------------- QString VException::MoreInfo(const QString &detInfo) const { if (moreInfo.isEmpty() == false) diff --git a/src/app/exception/vexceptionbadid.cpp b/src/app/exception/vexceptionbadid.cpp index 39106eea9..a392a9650 100644 --- a/src/app/exception/vexceptionbadid.cpp +++ b/src/app/exception/vexceptionbadid.cpp @@ -28,6 +28,7 @@ #include "vexceptionbadid.h" +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionBadId::ErrorMessage() const { QString error; diff --git a/src/app/exception/vexceptionconversionerror.cpp b/src/app/exception/vexceptionconversionerror.cpp index cdbebbc77..0ab8f1dbd 100644 --- a/src/app/exception/vexceptionconversionerror.cpp +++ b/src/app/exception/vexceptionconversionerror.cpp @@ -28,18 +28,19 @@ #include "vexceptionconversionerror.h" +//--------------------------------------------------------------------------------------------------------------------- VExceptionConversionError::VExceptionConversionError(const QString &what, const QString &str) :VException(what), str(str) { Q_ASSERT_X(str.isEmpty() == false, Q_FUNC_INFO, "Error converting string is empty"); } +//--------------------------------------------------------------------------------------------------------------------- VExceptionConversionError::VExceptionConversionError(const VExceptionConversionError &e) :VException(e), str(e.String()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionConversionError::ErrorMessage() const { QString error = QString("ExceptionConversionError: %1 %2").arg(what, str); diff --git a/src/app/exception/vexceptionemptyparameter.cpp b/src/app/exception/vexceptionemptyparameter.cpp index 0f8ce145e..ff37f6c55 100644 --- a/src/app/exception/vexceptionemptyparameter.cpp +++ b/src/app/exception/vexceptionemptyparameter.cpp @@ -30,6 +30,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- VExceptionEmptyParameter::VExceptionEmptyParameter(const QString &what, const QString &name, const QDomElement &domElement) : VException(what), name(name), tagText(QString()), tagName(QString()), lineNumber(-1) @@ -42,18 +43,19 @@ VExceptionEmptyParameter::VExceptionEmptyParameter(const QString &what, const QS lineNumber = domElement.lineNumber(); } +//--------------------------------------------------------------------------------------------------------------------- VExceptionEmptyParameter::VExceptionEmptyParameter(const VExceptionEmptyParameter &e) :VException(e), name(e.Name()), tagText(e.TagText()), tagName(e.TagName()), lineNumber(e.LineNumber()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionEmptyParameter::ErrorMessage() const { QString error = QString("ExceptionEmptyParameter: %1 %2").arg(what, name); return error; } +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionEmptyParameter::DetailedInformation() const { return MoreInfo(QString("tag: %1 in line %2\nFull tag:\n%3").arg(tagName).arg(lineNumber).arg(tagText)); diff --git a/src/app/exception/vexceptionobjecterror.cpp b/src/app/exception/vexceptionobjecterror.cpp index 61b0867c9..2b99226d6 100644 --- a/src/app/exception/vexceptionobjecterror.cpp +++ b/src/app/exception/vexceptionobjecterror.cpp @@ -29,6 +29,7 @@ #include "vexceptionobjecterror.h" #include +//--------------------------------------------------------------------------------------------------------------------- VExceptionObjectError::VExceptionObjectError(const QString &what, const QDomElement &domElement) :VException(what), tagText(QString()), tagName(QString()), lineNumber(-1) { @@ -39,18 +40,19 @@ VExceptionObjectError::VExceptionObjectError(const QString &what, const QDomElem lineNumber = domElement.lineNumber(); } +//--------------------------------------------------------------------------------------------------------------------- VExceptionObjectError::VExceptionObjectError(const VExceptionObjectError &e) :VException(e), tagText(e.TagText()), tagName(e.TagName()), lineNumber(e.LineNumber()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionObjectError::ErrorMessage() const { QString error = QString("ExceptionObjectError: %1").arg(what); return error; } +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionObjectError::DetailedInformation() const { return MoreInfo(QString("tag: %1 in line %2\n%3").arg(tagName).arg(lineNumber).arg(tagText)); diff --git a/src/app/exception/vexceptionwrongid.cpp b/src/app/exception/vexceptionwrongid.cpp index 5eff5cf81..5877e8614 100644 --- a/src/app/exception/vexceptionwrongid.cpp +++ b/src/app/exception/vexceptionwrongid.cpp @@ -29,6 +29,7 @@ #include "vexceptionwrongid.h" #include +//--------------------------------------------------------------------------------------------------------------------- VExceptionWrongId::VExceptionWrongId(const QString &what, const QDomElement &domElement) :VException(what), tagText(QString()), tagName(QString()), lineNumber(-1) { @@ -39,18 +40,19 @@ VExceptionWrongId::VExceptionWrongId(const QString &what, const QDomElement &dom lineNumber = domElement.lineNumber(); } +//--------------------------------------------------------------------------------------------------------------------- VExceptionWrongId::VExceptionWrongId(const VExceptionWrongId &e) :VException(e), tagText(e.TagText()), tagName(e.TagName()), lineNumber(e.LineNumber()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionWrongId::ErrorMessage() const { QString error = QString("ExceptionWrongId: %1").arg(what); return error; } +//--------------------------------------------------------------------------------------------------------------------- QString VExceptionWrongId::DetailedInformation() const { return MoreInfo(QString("tag: %1 in line %2\nFull tag:\n%3").arg(tagName).arg(lineNumber).arg(tagText)); diff --git a/src/app/geometry/varc.cpp b/src/app/geometry/varc.cpp index c81506f13..9d3441b0b 100644 --- a/src/app/geometry/varc.cpp +++ b/src/app/geometry/varc.cpp @@ -33,12 +33,13 @@ class QRectF; +//--------------------------------------------------------------------------------------------------------------------- VArc::VArc () :VGObject(GObject::Arc), f1(0), formulaF1(QString()), f2(0), formulaF2(QString()), radius(0), formulaRadius(QString()), center(VPointF()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VArc::VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1, qreal f2, QString formulaF2, quint32 idObject, Valentina::Draws mode) : VGObject(GObject::Arc, idObject, mode), f1(f1), formulaF1(formulaF1), f2(f2), formulaF2(formulaF2), @@ -47,13 +48,14 @@ VArc::VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QStri _name = QString ("Arc_%1").arg(this->GetCenter().name()); } +//--------------------------------------------------------------------------------------------------------------------- VArc::VArc(const VArc &arc) : VGObject(arc), f1(arc.GetF1()), formulaF1(arc.GetFormulaF1()), f2(arc.GetF2()), formulaF2(arc.GetFormulaF2()), radius(arc.GetRadius()), formulaRadius(arc.GetFormulaRadius()), center(arc.GetCenter()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VArc &VArc::operator =(const VArc &arc) { VGObject::operator=(arc); @@ -67,11 +69,13 @@ VArc &VArc::operator =(const VArc &arc) return *this; } +//--------------------------------------------------------------------------------------------------------------------- qreal VArc::GetLength() const { return (M_PI * radius)/180 * AngleArc(); } +//--------------------------------------------------------------------------------------------------------------------- QPointF VArc::GetP1() const { QPointF p1 ( GetCenter().x () + radius, GetCenter().y () ); @@ -80,6 +84,7 @@ QPointF VArc::GetP1() const return centerP1.p2(); } +//--------------------------------------------------------------------------------------------------------------------- QPointF VArc::GetP2 () const { QPointF p2 ( GetCenter().x () + radius, GetCenter().y () ); @@ -88,6 +93,7 @@ QPointF VArc::GetP2 () const return centerP2.p2(); } +//--------------------------------------------------------------------------------------------------------------------- QPainterPath VArc::GetPath() const { QPainterPath path; @@ -108,6 +114,7 @@ QPainterPath VArc::GetPath() const return path; } +//--------------------------------------------------------------------------------------------------------------------- qreal VArc::AngleArc() const { QLineF l1(0, 0, 100, 100); @@ -117,6 +124,7 @@ qreal VArc::AngleArc() const return l1.angleTo(l2); } +//--------------------------------------------------------------------------------------------------------------------- QVector VArc::GetPoints() const { QVector points; @@ -140,11 +148,13 @@ QVector VArc::GetPoints() const return points; } +//--------------------------------------------------------------------------------------------------------------------- QString VArc::name() const { return _name; } +//--------------------------------------------------------------------------------------------------------------------- QPointF VArc::CutArc(const qreal &length, VArc &arc1, VArc &arc2) const { //Always need return two arcs, so we must correct wrong length. @@ -174,6 +184,7 @@ QPointF VArc::CutArc(const qreal &length, VArc &arc1, VArc &arc2) const return line.p2(); } +//--------------------------------------------------------------------------------------------------------------------- void VArc::setId(const quint32 &id) { _id = id; diff --git a/src/app/geometry/vdetail.cpp b/src/app/geometry/vdetail.cpp index 0ae8ed608..604a9b429 100644 --- a/src/app/geometry/vdetail.cpp +++ b/src/app/geometry/vdetail.cpp @@ -29,10 +29,13 @@ #include "vdetail.h" #include +//--------------------------------------------------------------------------------------------------------------------- VDetail::VDetail() :_id(0), nodes(QVector()), name(QString()), mx(0), my(0), seamAllowance(true), closed(true), - width(10){} + width(10) +{} +//--------------------------------------------------------------------------------------------------------------------- VDetail::VDetail(const QString &name, const QVector &nodes) :_id(0), nodes(QVector()), name(name), mx(0), my(0), seamAllowance(true), closed(true), width(10) @@ -40,10 +43,13 @@ VDetail::VDetail(const QString &name, const QVector &nodes) this->nodes = nodes; } +//--------------------------------------------------------------------------------------------------------------------- VDetail::VDetail(const VDetail &detail) :_id(0), nodes(detail.getNodes()), name(detail.getName()), mx(detail.getMx()), my(detail.getMy()), - seamAllowance(detail.getSeamAllowance()), closed(detail.getClosed()), width(detail.getWidth()){} + seamAllowance(detail.getSeamAllowance()), closed(detail.getClosed()), width(detail.getWidth()) +{} +//--------------------------------------------------------------------------------------------------------------------- VDetail &VDetail::operator =(const VDetail &detail) { _id = detail.id(); @@ -57,6 +63,7 @@ VDetail &VDetail::operator =(const VDetail &detail) return *this; } +//--------------------------------------------------------------------------------------------------------------------- void VDetail::Clear() { nodes.clear(); @@ -68,11 +75,13 @@ void VDetail::Clear() width = 10; } +//--------------------------------------------------------------------------------------------------------------------- void VDetail::ClearNodes() { nodes.clear(); } +//--------------------------------------------------------------------------------------------------------------------- bool VDetail::Containes(const quint32 &id) const { for (ptrdiff_t i = 0; i < nodes.size(); ++i) @@ -86,31 +95,37 @@ bool VDetail::Containes(const quint32 &id) const return false; } +//--------------------------------------------------------------------------------------------------------------------- VNodeDetail &VDetail::operator [](ptrdiff_t indx) { return nodes[indx]; } +//--------------------------------------------------------------------------------------------------------------------- const VNodeDetail &VDetail::at(ptrdiff_t indx) const { return nodes[indx]; } +//--------------------------------------------------------------------------------------------------------------------- ptrdiff_t VDetail::indexOfNode(const quint32 &id) const { return indexOfNode(nodes, id); } +//--------------------------------------------------------------------------------------------------------------------- quint32 VDetail::id() const { return _id; } +//--------------------------------------------------------------------------------------------------------------------- void VDetail::setId(const quint32 &id) { _id = id; } +//--------------------------------------------------------------------------------------------------------------------- bool VDetail::OnEdge(const quint32 &p1, const quint32 &p2) const { QVector list = listNodePoint(); @@ -148,6 +163,7 @@ bool VDetail::OnEdge(const quint32 &p1, const quint32 &p2) const } } +//--------------------------------------------------------------------------------------------------------------------- ptrdiff_t VDetail::Edge(const quint32 &p1, const quint32 &p2) const { if (OnEdge(p1, p2) == false) @@ -172,6 +188,7 @@ ptrdiff_t VDetail::Edge(const quint32 &p1, const quint32 &p2) const } } +//--------------------------------------------------------------------------------------------------------------------- void VDetail::NodeOnEdge(const quint32 &index, VNodeDetail &p1, VNodeDetail &p2) const { QVector list = listNodePoint(); @@ -191,6 +208,7 @@ void VDetail::NodeOnEdge(const quint32 &index, VNodeDetail &p1, VNodeDetail &p2) } } +//--------------------------------------------------------------------------------------------------------------------- VDetail VDetail::RemoveEdge(const quint32 &index) const { VDetail det(*this); @@ -233,6 +251,7 @@ VDetail VDetail::RemoveEdge(const quint32 &index) const return det; } +//--------------------------------------------------------------------------------------------------------------------- QList VDetail::Missing(const VDetail &det) const { QList list; @@ -256,6 +275,7 @@ QList VDetail::Missing(const VDetail &det) const return list; } +//--------------------------------------------------------------------------------------------------------------------- QVector VDetail::listNodePoint() const { QVector list; @@ -269,6 +289,7 @@ QVector VDetail::listNodePoint() const return list; } +//--------------------------------------------------------------------------------------------------------------------- ptrdiff_t VDetail::indexOfNode(const QVector &list, const quint32 &id) { for (ptrdiff_t i = 0; i < list.size(); ++i) diff --git a/src/app/geometry/vequidistant.cpp b/src/app/geometry/vequidistant.cpp index 255cd7f27..c80f34324 100644 --- a/src/app/geometry/vequidistant.cpp +++ b/src/app/geometry/vequidistant.cpp @@ -30,6 +30,7 @@ #include "../widgets/vapplication.h" #include +//--------------------------------------------------------------------------------------------------------------------- QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer *data) const { Q_CHECK_PTR(data); @@ -159,6 +160,7 @@ QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer return path; } +//--------------------------------------------------------------------------------------------------------------------- qreal VEquidistant::GetLengthContour(const QVector &contour, const QVector &newPoints) { qreal length = 0; @@ -172,6 +174,7 @@ qreal VEquidistant::GetLengthContour(const QVector &contour, const QVec return length; } +//--------------------------------------------------------------------------------------------------------------------- QVector VEquidistant::biasPoints(const QVector &points, const qreal &mx, const qreal &my) { QVector p; @@ -185,6 +188,7 @@ QVector VEquidistant::biasPoints(const QVector &points, const return p; } +//--------------------------------------------------------------------------------------------------------------------- QVector VEquidistant::CorrectEquidistantPoints(const QVector &points) { QVector correctPoints; @@ -230,6 +234,7 @@ QVector VEquidistant::CorrectEquidistantPoints(const QVector & return correctPoints; } +//--------------------------------------------------------------------------------------------------------------------- QPainterPath VEquidistant::Equidistant(QVector points, const Detail::Equidistant &eqv, const qreal &width) { @@ -297,6 +302,7 @@ QPainterPath VEquidistant::Equidistant(QVector points, const Detail::Eq return ekv; } +//--------------------------------------------------------------------------------------------------------------------- QVector VEquidistant::CheckLoops(const QVector &points) { QVector ekvPoints; @@ -355,6 +361,7 @@ QVector VEquidistant::CheckLoops(const QVector &points) return ekvPoints; } +//--------------------------------------------------------------------------------------------------------------------- QVector VEquidistant::GetReversePoint(const QVector &points) { Q_ASSERT(points.size() > 0); @@ -366,6 +373,7 @@ QVector VEquidistant::GetReversePoint(const QVector &points) return reversePoints; } +//--------------------------------------------------------------------------------------------------------------------- QVector VEquidistant::EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width) { Q_ASSERT(width > 0); @@ -415,6 +423,7 @@ QVector VEquidistant::EkvPoint(const QLineF &line1, const QLineF &line2 return points; } +//--------------------------------------------------------------------------------------------------------------------- QLineF VEquidistant::ParallelLine(const QLineF &line, qreal width) { Q_ASSERT(width > 0); @@ -423,6 +432,7 @@ QLineF VEquidistant::ParallelLine(const QLineF &line, qreal width) return paralel; } +//--------------------------------------------------------------------------------------------------------------------- QPointF VEquidistant::SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width) { Q_ASSERT(width > 0); diff --git a/src/app/geometry/vgobject.cpp b/src/app/geometry/vgobject.cpp index 4002472ed..767dcc217 100644 --- a/src/app/geometry/vgobject.cpp +++ b/src/app/geometry/vgobject.cpp @@ -28,21 +28,22 @@ #include "vgobject.h" +//--------------------------------------------------------------------------------------------------------------------- VGObject::VGObject() :_id(0), type(GObject::Point), idObject(0), _name(QString()), mode(Valentina::Calculation) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VGObject::VGObject(const GObject::Type &type, const quint32 &idObject, const Valentina::Draws &mode) :_id(0), type(type), idObject(idObject), _name(QString()), mode(mode) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VGObject::VGObject(const VGObject &obj) :_id(obj.id()), type(obj.getType()), idObject(obj.getIdObject()), _name(obj.name()), mode(obj.getMode()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VGObject &VGObject::operator=(const VGObject &obj) { this->_id = obj.id(); @@ -53,21 +54,25 @@ VGObject &VGObject::operator=(const VGObject &obj) return *this; } +//--------------------------------------------------------------------------------------------------------------------- quint32 VGObject::getIdObject() const { return idObject; } +//--------------------------------------------------------------------------------------------------------------------- void VGObject::setIdObject(const quint32 &value) { idObject = value; } +//--------------------------------------------------------------------------------------------------------------------- QString VGObject::name() const { return _name; } +//--------------------------------------------------------------------------------------------------------------------- void VGObject::setName(const QString &name) { _name = name; @@ -78,21 +83,25 @@ Valentina::Draws VGObject::getMode() const return mode; } +//--------------------------------------------------------------------------------------------------------------------- void VGObject::setMode(const Valentina::Draws &value) { mode = value; } +//--------------------------------------------------------------------------------------------------------------------- GObject::Type VGObject::getType() const { return type; } +//--------------------------------------------------------------------------------------------------------------------- quint32 VGObject::id() const { return _id; } +//--------------------------------------------------------------------------------------------------------------------- void VGObject::setId(const quint32 &id) { _id = id; diff --git a/src/app/geometry/vnodedetail.cpp b/src/app/geometry/vnodedetail.cpp index 3c52ab31f..02159fb4d 100644 --- a/src/app/geometry/vnodedetail.cpp +++ b/src/app/geometry/vnodedetail.cpp @@ -28,15 +28,22 @@ #include "vnodedetail.h" +//--------------------------------------------------------------------------------------------------------------------- VNodeDetail::VNodeDetail() - :id(0), typeTool(Valentina::NodePoint), typeNode(NodeDetail::Contour), mx(0), my(0){} + :id(0), typeTool(Valentina::NodePoint), typeNode(NodeDetail::Contour), mx(0), my(0) +{} +//--------------------------------------------------------------------------------------------------------------------- VNodeDetail::VNodeDetail(quint32 id, Valentina::Tools typeTool, NodeDetail::NodeDetails typeNode, qreal mx, qreal my) - :id(id), typeTool(typeTool), typeNode(typeNode), mx(mx), my(my){} + :id(id), typeTool(typeTool), typeNode(typeNode), mx(mx), my(my) +{} +//--------------------------------------------------------------------------------------------------------------------- VNodeDetail::VNodeDetail(const VNodeDetail &node) - :id(node.getId()), typeTool(node.getTypeTool()), typeNode(node.getTypeNode()), mx(node.getMx()), my(node.getMy()){} + :id(node.getId()), typeTool(node.getTypeTool()), typeNode(node.getTypeNode()), mx(node.getMx()), my(node.getMy()) +{} +//--------------------------------------------------------------------------------------------------------------------- VNodeDetail &VNodeDetail::operator =(const VNodeDetail &node) { id = node.getId(); diff --git a/src/app/geometry/vpointf.cpp b/src/app/geometry/vpointf.cpp index 81ecfb5f3..c47f9e0d0 100644 --- a/src/app/geometry/vpointf.cpp +++ b/src/app/geometry/vpointf.cpp @@ -28,27 +28,26 @@ #include "vpointf.h" +//--------------------------------------------------------------------------------------------------------------------- VPointF::VPointF(qreal x, qreal y, QString name, qreal mx, qreal my, quint32 idObject, Valentina::Draws mode) :VGObject(GObject::Point, idObject, mode), _mx(mx), _my(my), _x(x), _y(y) { this->_name = name; } +//--------------------------------------------------------------------------------------------------------------------- VPointF::VPointF() :VGObject(GObject::Point, 0, Valentina::Calculation), _mx(0), _my(0), _x(0), _y(0) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- VPointF::VPointF(const VPointF &point) :VGObject(point), _mx(point.mx()), _my(point.my()), _x(point.x()), _y(point.y()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- VPointF::VPointF(const QPointF &point) :VGObject(VPointF()), _mx(0), _my(0), _x(point.x()), _y(point.y()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- VPointF &VPointF::operator =(const VPointF &point) { VGObject::operator=(point); diff --git a/src/app/geometry/vspline.cpp b/src/app/geometry/vspline.cpp index 23cd0ae63..f3a8d935e 100644 --- a/src/app/geometry/vspline.cpp +++ b/src/app/geometry/vspline.cpp @@ -30,15 +30,20 @@ #include +//--------------------------------------------------------------------------------------------------------------------- VSpline::VSpline() :VGObject(GObject::Spline), p1(VPointF()), p2(QPointF()), p3(QPointF()), p4(VPointF()), angle1(0), angle2(0), - kAsm1(1), kAsm2(1), kCurve(1){} + kAsm1(1), kAsm2(1), kCurve(1) +{} +//--------------------------------------------------------------------------------------------------------------------- VSpline::VSpline ( const VSpline & spline ) :VGObject(spline), p1(spline.GetP1 ()), p2(spline.GetP2 ()), p3(spline.GetP3 ()), p4(spline.GetP4 ()), angle1(spline.GetAngle1 ()), angle2(spline.GetAngle2 ()), kAsm1(spline.GetKasm1()), kAsm2(spline.GetKasm2()), - kCurve(spline.GetKcurve()){} + kCurve(spline.GetKcurve()) +{} +//--------------------------------------------------------------------------------------------------------------------- VSpline::VSpline (VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve, quint32 idObject, Valentina::Draws mode) :VGObject(GObject::Spline, idObject, mode), p1(p1), p2(QPointF()), p3(QPointF()), p4(p4), angle1(angle1), @@ -67,6 +72,7 @@ VSpline::VSpline (VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm this->p3 = p4p3.p2(); } +//--------------------------------------------------------------------------------------------------------------------- VSpline::VSpline (VPointF p1, QPointF p2, QPointF p3, VPointF p4, qreal kCurve, quint32 idObject, Valentina::Draws mode) :VGObject(GObject::Spline, idObject, mode), p1(p1), p2(p2), p3(p3), p4(p4), angle1(0), angle2(0), kAsm1(1), kAsm2(1), kCurve(1) @@ -91,16 +97,19 @@ VSpline::VSpline (VPointF p1, QPointF p2, QPointF p3, VPointF p4, qreal kCurve, this->kAsm2 = QLineF ( GetP4().toQPointF(), p3 ).length()/L; } +//--------------------------------------------------------------------------------------------------------------------- qreal VSpline::GetLength () const { return LengthBezier ( GetP1().toQPointF(), this->p2, this->p3, GetP4().toQPointF()); } +//--------------------------------------------------------------------------------------------------------------------- QString VSpline::name() const { return _name; } +//--------------------------------------------------------------------------------------------------------------------- QLineF::IntersectType VSpline::CrossingSplLine ( const QLineF &line, QPointF *intersectionPoint ) const { QVector px; @@ -130,6 +139,7 @@ QLineF::IntersectType VSpline::CrossingSplLine ( const QLineF &line, QPointF *in throw "Can't found point of intersection spline and line."; } +//--------------------------------------------------------------------------------------------------------------------- qreal VSpline::LengthT(qreal t) const { if (t < 0 || t > 1) @@ -164,6 +174,7 @@ qreal VSpline::LengthT(qreal t) const return LengthBezier ( GetP1().toQPointF(), p12, p123, p1234); } +//--------------------------------------------------------------------------------------------------------------------- QPointF VSpline::CutSpline ( qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3 ) const { //Always need return two splines, so we must correct wrong length. @@ -223,11 +234,13 @@ QPointF VSpline::CutSpline ( qreal length, QPointF &spl1p2, QPointF &spl1p3, QPo return p1234; } +//--------------------------------------------------------------------------------------------------------------------- QVector VSpline::GetPoints () const { return GetPoints(GetP1().toQPointF(), p2, p3, GetP4().toQPointF()); } +//--------------------------------------------------------------------------------------------------------------------- QVector VSpline::GetPoints (const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4) { QVector pvector; @@ -248,6 +261,7 @@ QVector VSpline::GetPoints (const QPointF &p1, const QPointF &p2, const return pvector; } +//--------------------------------------------------------------------------------------------------------------------- qreal VSpline::LengthBezier ( const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4 ) const { QPainterPath splinePath; @@ -260,6 +274,7 @@ qreal VSpline::LengthBezier ( const QPointF &p1, const QPointF &p2, const QPoint return splinePath.length(); } +//--------------------------------------------------------------------------------------------------------------------- void VSpline::PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4, qint16 level, QVector &px, QVector &py) @@ -271,15 +286,15 @@ void VSpline::PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2, const double m_cusp_limit = 0.0; double m_approximation_scale = 1.0; double m_distance_tolerance_square; - + m_distance_tolerance_square = 0.5 / m_approximation_scale; m_distance_tolerance_square *= m_distance_tolerance_square; - + if (level > curve_recursion_limit) { return; } - + // Calculate all the mid-points of the line segments //---------------------- const double x12 = (x1 + x2) / 2; @@ -294,16 +309,16 @@ void VSpline::PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2, const double y234 = (y23 + y34) / 2; const double x1234 = (x123 + x234) / 2; const double y1234 = (y123 + y234) / 2; - - + + // Try to approximate the full cubic curve by a single straight line //------------------ const double dx = x4-x1; const double dy = y4-y1; - + double d2 = fabs((x2 - x4) * dy - (y2 - y4) * dx); double d3 = fabs((x3 - x4) * dy - (y3 - y4) * dx); - + switch ((static_cast(d2 > curve_collinearity_epsilon) << 1) + static_cast(d3 > curve_collinearity_epsilon)) { @@ -531,13 +546,14 @@ void VSpline::PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2, default: break; } - + // Continue subdivision //---------------------- PointBezier_r(x1, y1, x12, y12, x123, y123, x1234, y1234, static_cast(level + 1), px, py); PointBezier_r(x1234, y1234, x234, y234, x34, y34, x4, y4, static_cast(level + 1), px, py); } +//--------------------------------------------------------------------------------------------------------------------- qreal VSpline::CalcSqDistance (qreal x1, qreal y1, qreal x2, qreal y2) { qreal dx = x2 - x1; @@ -545,11 +561,13 @@ qreal VSpline::CalcSqDistance (qreal x1, qreal y1, qreal x2, qreal y2) return dx * dx + dy * dy; } +//--------------------------------------------------------------------------------------------------------------------- void VSpline::CreateName() { _name = QString("Spl_%1_%2").arg(this->GetP1().name(), this->GetP4().name()); } +//--------------------------------------------------------------------------------------------------------------------- QPainterPath VSpline::GetPath() const { QPainterPath splinePath; @@ -569,6 +587,7 @@ QPainterPath VSpline::GetPath() const return splinePath; } +//--------------------------------------------------------------------------------------------------------------------- QVector VSpline::SplinePoints(const QPointF &p1, const QPointF &p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve) { @@ -586,6 +605,7 @@ QVector VSpline::SplinePoints(const QPointF &p1, const QPointF &p4, qre return GetPoints(p1, p2, p3, p4); } +//--------------------------------------------------------------------------------------------------------------------- VSpline &VSpline::operator =(const VSpline &spline) { VGObject::operator=(spline); diff --git a/src/app/geometry/vsplinepath.cpp b/src/app/geometry/vsplinepath.cpp index 0698b93c2..a51362d2d 100644 --- a/src/app/geometry/vsplinepath.cpp +++ b/src/app/geometry/vsplinepath.cpp @@ -29,17 +29,18 @@ #include "vsplinepath.h" #include "../exception/vexception.h" +//--------------------------------------------------------------------------------------------------------------------- VSplinePath::VSplinePath(qreal kCurve, quint32 idObject, Valentina::Draws mode) : VGObject(GObject::SplinePath, idObject, mode), path(QVector()), kCurve(kCurve), maxCountPoints(0) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VSplinePath::VSplinePath(const VSplinePath &splPath) : VGObject(splPath), path(*splPath.GetPoint()), kCurve(splPath.getKCurve()), maxCountPoints(splPath.getMaxCountPoints()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- void VSplinePath::append(const VSplinePoint &point) { path.append(point); @@ -51,6 +52,7 @@ void VSplinePath::append(const VSplinePoint &point) } } +//--------------------------------------------------------------------------------------------------------------------- qint32 VSplinePath::Count() const { if (path.size() == 0) @@ -63,6 +65,7 @@ qint32 VSplinePath::Count() const } } +//--------------------------------------------------------------------------------------------------------------------- VSpline VSplinePath::GetSpline(qint32 index) const { if (Count()<1) @@ -78,6 +81,7 @@ VSpline VSplinePath::GetSpline(qint32 index) const return spl; } +//--------------------------------------------------------------------------------------------------------------------- QPainterPath VSplinePath::GetPath() const { QPainterPath painterPath; @@ -90,6 +94,7 @@ QPainterPath VSplinePath::GetPath() const return painterPath; } +//--------------------------------------------------------------------------------------------------------------------- QVector VSplinePath::GetPathPoints() const { QVector pathPoints; @@ -102,6 +107,7 @@ QVector VSplinePath::GetPathPoints() const return pathPoints; } +//--------------------------------------------------------------------------------------------------------------------- qreal VSplinePath::GetLength() const { qreal length = 0; @@ -114,6 +120,7 @@ qreal VSplinePath::GetLength() const return length; } +//--------------------------------------------------------------------------------------------------------------------- void VSplinePath::UpdatePoint(qint32 indexSpline, const SplinePoint::Position &pos, const VSplinePoint &point) { if (indexSpline < 1 || indexSpline > Count()) @@ -130,6 +137,7 @@ void VSplinePath::UpdatePoint(qint32 indexSpline, const SplinePoint::Position &p } } +//--------------------------------------------------------------------------------------------------------------------- VSplinePoint VSplinePath::GetSplinePoint(qint32 indexSpline, SplinePoint::Position pos) const { if (indexSpline < 1 || indexSpline > Count()) @@ -146,6 +154,7 @@ VSplinePoint VSplinePath::GetSplinePoint(qint32 indexSpline, SplinePoint::Positi } } +//--------------------------------------------------------------------------------------------------------------------- VSplinePath &VSplinePath::operator =(const VSplinePath &path) { VGObject::operator=(path); @@ -155,16 +164,19 @@ VSplinePath &VSplinePath::operator =(const VSplinePath &path) return *this; } +//--------------------------------------------------------------------------------------------------------------------- VSplinePoint & VSplinePath::operator[](ptrdiff_t indx) { return path[indx]; } +//--------------------------------------------------------------------------------------------------------------------- const VSplinePoint &VSplinePath::at(ptrdiff_t indx) const { return path[indx]; } +//--------------------------------------------------------------------------------------------------------------------- QPointF VSplinePath::CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3) const { @@ -199,11 +211,14 @@ QPointF VSplinePath::CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF } return QPointF(); } + +//--------------------------------------------------------------------------------------------------------------------- qint32 VSplinePath::getMaxCountPoints() const { return maxCountPoints; } +//--------------------------------------------------------------------------------------------------------------------- void VSplinePath::setMaxCountPoints(const qint32 &value) { maxCountPoints = value; diff --git a/src/app/geometry/vsplinepoint.cpp b/src/app/geometry/vsplinepoint.cpp index a638c7f42..a25417c5f 100644 --- a/src/app/geometry/vsplinepoint.cpp +++ b/src/app/geometry/vsplinepoint.cpp @@ -29,9 +29,12 @@ #include "vsplinepoint.h" #include +//--------------------------------------------------------------------------------------------------------------------- VSplinePoint::VSplinePoint() - :pSpline(VPointF()), angle1(0), angle2(180), kAsm1(1), kAsm2(1){} + :pSpline(VPointF()), angle1(0), angle2(180), kAsm1(1), kAsm2(1) +{} +//--------------------------------------------------------------------------------------------------------------------- VSplinePoint::VSplinePoint(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2) :pSpline(pSpline), angle1(0), angle2(180), kAsm1(kAsm1), kAsm2(kAsm2) { @@ -42,9 +45,12 @@ VSplinePoint::VSplinePoint(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAs SetAngle2(angle2); } +//--------------------------------------------------------------------------------------------------------------------- VSplinePoint::VSplinePoint(const VSplinePoint &point) - :pSpline(point.P()), angle1(point.Angle1()), angle2(point.Angle2()), kAsm1(point.KAsm1()), kAsm2(point.KAsm2()){} + :pSpline(point.P()), angle1(point.Angle1()), angle2(point.Angle2()), kAsm1(point.KAsm1()), kAsm2(point.KAsm2()) +{} +//--------------------------------------------------------------------------------------------------------------------- void VSplinePoint::SetAngle1(const qreal &value) { QLineF line(0, 0, 100, 0); @@ -55,6 +61,7 @@ void VSplinePoint::SetAngle1(const qreal &value) angle2 = line.angle(); } +//--------------------------------------------------------------------------------------------------------------------- void VSplinePoint::SetAngle2(const qreal &value) { QLineF line(0, 0, 100, 0); diff --git a/src/app/main.cpp b/src/app/main.cpp index dd11ec665..b5facc0d5 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -35,6 +35,7 @@ #include "tablewindow.h" #include "version.h" +//--------------------------------------------------------------------------------------------------------------------- void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { // Why on earth didn't Qt want to make failed signal/slot connections qWarning? @@ -116,6 +117,7 @@ void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, c } } +//--------------------------------------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { Q_INIT_RESOURCE(cursor); diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 34fbfc983..5d3a47ab0 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -46,6 +46,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow), pattern(nullptr), doc(nullptr), tool(Valentina::ArrowTool), currentScene(nullptr), sceneDraw(nullptr), sceneDetails(nullptr), mouseCoordinate(nullptr), helpLabel(nullptr), @@ -92,6 +93,7 @@ MainWindow::MainWindow(QWidget *parent) setCurrentFile(""); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionNewDraw() { QString patternPieceName = QString(tr("Pattern piece %1")).arg(comboBoxDraws->count()+1); @@ -180,6 +182,7 @@ void MainWindow::ActionNewDraw() &MainWindow::currentDrawChanged); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::OptionDraw() { const QString activDraw = doc->GetNameActivDraw(); @@ -198,6 +201,7 @@ void MainWindow::OptionDraw() } } +//--------------------------------------------------------------------------------------------------------------------- template void MainWindow::SetToolButton(bool checked, Valentina::Tools t, const QString &cursor, const QString &toolTip, Func closeDialogSlot) @@ -226,6 +230,7 @@ void MainWindow::SetToolButton(bool checked, Valentina::Tools t, const QString & } } +//--------------------------------------------------------------------------------------------------------------------- template void MainWindow::ClosedDialog(int result) { @@ -237,127 +242,150 @@ void MainWindow::ClosedDialog(int result) ArrowTool(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolEndLine(bool checked) { SetToolButton(checked, Valentina::EndLineTool, ":/cursor/endline_cursor.png", tr("Select point"), &MainWindow::ClosedDialogEndLine); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogEndLine(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolLine(bool checked) { SetToolButton(checked, Valentina::LineTool, ":/cursor/line_cursor.png", tr("Select first point"), &MainWindow::ClosedDialogLine); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogLine(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolAlongLine(bool checked) { SetToolButton(checked, Valentina::AlongLineTool, ":/cursor/alongline_cursor.png", tr("Select point"), &MainWindow::ClosedDialogAlongLine); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogAlongLine(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolShoulderPoint(bool checked) { SetToolButton(checked, Valentina::ShoulderPointTool, ":/cursor/shoulder_cursor.png", tr("Select first point of line"), &MainWindow::ClosedDialogShoulderPoint); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogShoulderPoint(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolNormal(bool checked) { SetToolButton(checked, Valentina::NormalTool, ":/cursor/normal_cursor.png", tr("Select first point of line"), &MainWindow::ClosedDialogNormal); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogNormal(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolBisector(bool checked) { SetToolButton(checked, Valentina::BisectorTool, ":/cursor/bisector_cursor.png", tr("Select first point of angle"), &MainWindow::ClosedDialogBisector); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogBisector(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolLineIntersect(bool checked) { SetToolButton(checked, Valentina::LineIntersectTool, ":/cursor/intersect_cursor.png", tr("Select first point of first line"), &MainWindow::ClosedDialogLineIntersect); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogLineIntersect(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolSpline(bool checked) { SetToolButton(checked, Valentina::SplineTool, ":/cursor/spline_cursor.png", tr("Select first point curve"), &MainWindow::ClosedDialogSpline); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogSpline(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolCutSpline(bool checked) { SetToolButton(checked, Valentina::CutSplineTool, ":/cursor/spline_cut_point_cursor.png", tr("Select simple curve"), &MainWindow::ClosedDialogCutSpline); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogCutSpline(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolArc(bool checked) { SetToolButton(checked, Valentina::ArcTool, ":/cursor/arc_cursor.png", tr("Select point of center of arc"), &MainWindow::ClosedDialogArc); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogArc(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolSplinePath(bool checked) { SetToolButton(checked, Valentina::SplinePathTool, ":/cursor/splinepath_cursor.png", tr("Select point of curve path"), &MainWindow::ClosedDialogSplinePath); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogSplinePath(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolCutSplinePath(bool checked) { SetToolButton(checked, Valentina::CutSplinePathTool, @@ -365,28 +393,33 @@ void MainWindow::ToolCutSplinePath(bool checked) &MainWindow::ClosedDialogCutSplinePath); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogCutSplinePath(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolPointOfContact(bool checked) { SetToolButton(checked, Valentina::PointOfContact, ":/cursor/pointcontact_cursor.png", tr("Select first point of line"), &MainWindow::ClosedDialogPointOfContact); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogPointOfContact(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolDetail(bool checked) { SetToolButton(checked, Valentina::DetailTool, "://cursor/new_detail_cursor.png", tr("Select points, arcs, curves clockwise."), &MainWindow::ClosedDialogDetail); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogDetail(int result) { if (result == QDialog::Accepted) @@ -397,28 +430,33 @@ void MainWindow::ClosedDialogDetail(int result) doc->FullUpdateTree(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolHeight(bool checked) { SetToolButton(checked, Valentina::Height, ":/cursor/height_cursor.png", tr("Select base point"), &MainWindow::ClosedDialogHeight); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogHeight(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolTriangle(bool checked) { SetToolButton(checked, Valentina::Triangle, ":/cursor/triangle_cursor.png", tr("Select first point of axis"), &MainWindow::ClosedDialogTriangle); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogTriangle(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolPointOfIntersection(bool checked) { SetToolButton(checked, Valentina::PointOfIntersection, @@ -426,11 +464,13 @@ void MainWindow::ToolPointOfIntersection(bool checked) &MainWindow::ClosedDialogPointOfIntersection); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogPointOfIntersection(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolUnionDetails(bool checked) { SetToolButton(checked, Valentina::UnionDetails, ":/cursor/union_cursor.png", @@ -439,23 +479,27 @@ void MainWindow::ToolUnionDetails(bool checked) disconnect(doc, &VPattern::FullUpdateFromFile, dialogTool, &DialogTool::UpdateList); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogUnionDetails(int result) { ClosedDialog(result); doc->FullUpdateTree(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolCutArc(bool checked) { SetToolButton(checked, Valentina::CutArcTool, ":/cursor/arc_cut_cursor.png", tr("Select arc"), &MainWindow::ClosedDialogCutArc); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedDialogCutArc(int result) { ClosedDialog(result); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::About() { QDate date = QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), QLatin1String("MMM d yyyy")); @@ -468,22 +512,26 @@ void MainWindow::About() QMessageBox::about(this, tr("About Valentina"), about); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::AboutQt() { QMessageBox::aboutQt(this, tr("About Qt")); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ShowToolTip(const QString &toolTip) { helpLabel->setText(toolTip); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::tableClosed() { show(); MinimumScrollBar(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::OpenRecentFile() { QAction *action = qobject_cast(sender()); @@ -493,12 +541,14 @@ void MainWindow::OpenRecentFile() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::PatternProperties() { DialogPatternProperties proper(doc, this); proper.exec(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::showEvent( QShowEvent *event ) { QMainWindow::showEvent( event ); @@ -518,6 +568,7 @@ void MainWindow::showEvent( QShowEvent *event ) isInitialized = true;//first show windows are held } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::closeEvent(QCloseEvent *event) { if (MaybeSave()) @@ -531,6 +582,7 @@ void MainWindow::closeEvent(QCloseEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolBarOption() { if (qApp->patternType() == Pattern::Standard) @@ -566,6 +618,7 @@ void MainWindow::ToolBarOption() ui->toolBarOption->addWidget(mouseCoordinate); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ToolBarDraws() { QLabel *labelPtternPieceName = new QLabel(tr("Pattern Piece: ")); @@ -592,6 +645,7 @@ void MainWindow::ToolBarDraws() ui->actionLayout->setEnabled(false); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::InitToolButtons() { connect(ui->toolButtonEndLine, &QToolButton::clicked, this, &MainWindow::ToolEndLine); @@ -615,6 +669,7 @@ void MainWindow::InitToolButtons() connect(ui->toolButtonArcCutPoint, &QToolButton::clicked, this, &MainWindow::ToolCutArc); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::currentDrawChanged( int index ) { if (index != -1) @@ -634,6 +689,7 @@ void MainWindow::currentDrawChanged( int index ) } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::mouseMove(const QPointF &scenePos) { QString string = QString("%1, %2").arg(static_cast(qApp->fromPixel(scenePos.x()))) @@ -644,6 +700,7 @@ void MainWindow::mouseMove(const QPointF &scenePos) } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::CancelTool() { delete dialogTool; @@ -757,6 +814,7 @@ void MainWindow::CancelTool() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ArrowTool() { CancelTool(); @@ -767,11 +825,13 @@ void MainWindow::ArrowTool() helpLabel->setText(""); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionAroowTool() { ArrowTool(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::keyPressEvent ( QKeyEvent * event ) { switch (event->key()) @@ -785,6 +845,7 @@ void MainWindow::keyPressEvent ( QKeyEvent * event ) QMainWindow::keyPressEvent ( event ); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::SaveCurrentScene() { /*Save transform*/ @@ -796,6 +857,7 @@ void MainWindow::SaveCurrentScene() currentScene->setVerScrollBar(verScrollBar->value()); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::RestoreCurrentScene() { /*Set transform for current scene*/ @@ -807,6 +869,7 @@ void MainWindow::RestoreCurrentScene() verScrollBar->setValue(currentScene->getVerScrollBar()); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionDraw(bool checked) { if (checked) @@ -839,6 +902,7 @@ void MainWindow::ActionDraw(bool checked) } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionDetails(bool checked) { if (checked) @@ -873,6 +937,7 @@ void MainWindow::ActionDetails(bool checked) } } +//--------------------------------------------------------------------------------------------------------------------- bool MainWindow::SaveAs() { QString filters(tr("Pattern files (*.val)")); @@ -899,6 +964,7 @@ bool MainWindow::SaveAs() return SavePattern(fileName); } +//--------------------------------------------------------------------------------------------------------------------- bool MainWindow::Save() { if (curFile.isEmpty()) @@ -918,6 +984,7 @@ bool MainWindow::Save() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::Open() { if (MaybeSave()) @@ -943,6 +1010,7 @@ void MainWindow::Open() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::Options() { ConfigDialog dlg(this); @@ -952,6 +1020,7 @@ void MainWindow::Options() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::Clear() { setCurrentFile(""); @@ -973,6 +1042,7 @@ void MainWindow::Clear() #endif } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::NewPattern() { QProcess *v = new QProcess(this); @@ -980,12 +1050,14 @@ void MainWindow::NewPattern() delete v; } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::PatternWasModified() { setWindowModified(doc->isPatternModified()); ui->actionSave->setEnabled(true); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ChangedSize(const QString & text) { qint32 size = text.toInt(); @@ -993,6 +1065,7 @@ void MainWindow::ChangedSize(const QString & text) doc->FullUpdateTree(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ChangedHeight(const QString &text) { qint32 growth = text.toInt(); @@ -1000,6 +1073,7 @@ void MainWindow::ChangedHeight(const QString &text) doc->FullUpdateTree(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::SetEnableWidgets(bool enable) { ui->actionSaveAs->setEnabled(enable); @@ -1014,6 +1088,7 @@ void MainWindow::SetEnableWidgets(bool enable) ui->actionHistory->setEnabled(enable); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionTable(bool checked) { if (checked) @@ -1029,6 +1104,7 @@ void MainWindow::ActionTable(bool checked) } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedActionTable() { ui->actionTable->setChecked(false); @@ -1036,6 +1112,7 @@ void MainWindow::ClosedActionTable() dialogTable = nullptr; } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionHistory(bool checked) { if (checked) @@ -1052,6 +1129,7 @@ void MainWindow::ActionHistory(bool checked) } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ActionLayout(bool checked) { Q_UNUSED(checked); @@ -1069,12 +1147,14 @@ void MainWindow::ActionLayout(bool checked) emit ModelChosen(listDetails, curFile, description); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::ClosedActionHistory() { ui->actionHistory->setChecked(false); delete dialogHistory; } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::SetEnableTool(bool enable) { bool drawTools = false; @@ -1111,6 +1191,7 @@ void MainWindow::SetEnableTool(bool enable) ui->toolButtonUnionDetails->setEnabled(modelingTools); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::MinimumScrollBar() { QScrollBar *horScrollBar = view->horizontalScrollBar(); @@ -1119,6 +1200,7 @@ void MainWindow::MinimumScrollBar() verScrollBar->setValue(verScrollBar->minimum()); } +//--------------------------------------------------------------------------------------------------------------------- bool MainWindow::SavePattern(const QString &fileName) { QFileInfo tempInfo(fileName); @@ -1134,6 +1216,7 @@ bool MainWindow::SavePattern(const QString &fileName) return result; } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::AutoSavePattern() { if (curFile.isEmpty() == false && doc->isPatternModified() == true) @@ -1146,6 +1229,7 @@ void MainWindow::AutoSavePattern() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::setCurrentFile(const QString &fileName) { curFile = fileName; @@ -1176,6 +1260,7 @@ void MainWindow::setCurrentFile(const QString &fileName) setWindowTitle(shownName); } +//--------------------------------------------------------------------------------------------------------------------- QString MainWindow::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); @@ -1191,6 +1276,7 @@ void MainWindow::ReadSettings() move(pos); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::WriteSettings() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -1199,6 +1285,7 @@ void MainWindow::WriteSettings() settings.setValue("size", size()); } +//--------------------------------------------------------------------------------------------------------------------- bool MainWindow::MaybeSave() { if (doc->isPatternModified()) @@ -1219,6 +1306,7 @@ bool MainWindow::MaybeSave() return true; } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::UpdateRecentFileActions() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), @@ -1242,6 +1330,7 @@ void MainWindow::UpdateRecentFileActions() separatorAct->setVisible(numRecentFiles > 0); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::CreateMenus() { for (int i = 0; i < MaxRecentFiles; ++i) @@ -1254,6 +1343,7 @@ void MainWindow::CreateMenus() UpdateRecentFileActions(); } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::CreateActions() { ui->setupUi(this); @@ -1284,6 +1374,7 @@ void MainWindow::CreateActions() } } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::InitAutoSave() { //Autosaving file each 5 minutes @@ -1309,6 +1400,7 @@ void MainWindow::InitAutoSave() } } +//--------------------------------------------------------------------------------------------------------------------- QString MainWindow::PatternPieceName(const QString &text) { QInputDialog *dlg = new QInputDialog(this); @@ -1337,6 +1429,7 @@ QString MainWindow::PatternPieceName(const QString &text) return nameDraw; } +//--------------------------------------------------------------------------------------------------------------------- MainWindow::~MainWindow() { CancelTool(); @@ -1348,6 +1441,7 @@ MainWindow::~MainWindow() delete sceneDraw; } +//--------------------------------------------------------------------------------------------------------------------- void MainWindow::LoadPattern(const QString &fileName) { try @@ -1470,6 +1564,7 @@ void MainWindow::LoadPattern(const QString &fileName) helpLabel->setText(tr("File loaded")); } +//--------------------------------------------------------------------------------------------------------------------- QString MainWindow::CheckPathToMeasurements(const QString &path, const Pattern::Measurements &patternType) { QFile table(path); diff --git a/src/app/tablewindow.cpp b/src/app/tablewindow.cpp index 1c88edb4f..87c4801f0 100644 --- a/src/app/tablewindow.cpp +++ b/src/app/tablewindow.cpp @@ -33,6 +33,7 @@ #include #include "widgets/vapplication.h" +//--------------------------------------------------------------------------------------------------------------------- TableWindow::TableWindow(QWidget *parent) :QMainWindow(parent), numberDetal(nullptr), colission(nullptr), ui(new Ui::TableWindow), listDetails(QVector()), outItems(false), collidingItems(false), tableScene(nullptr), @@ -67,12 +68,14 @@ TableWindow::TableWindow(QWidget *parent) connect(view, &VTableGraphicsView::itemChect, this, &TableWindow::itemChect); } +//--------------------------------------------------------------------------------------------------------------------- TableWindow::~TableWindow() { delete tableScene; delete ui; } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::AddPaper() { qreal x1, y1, x2, y2; @@ -87,6 +90,7 @@ void TableWindow::AddPaper() qDebug()<rect().size().toSize(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::AddDetail() { if (indexDetailsetText(QString(tr("%1 details left.")).arg(listDetails.count()-indexDetail)); } +//--------------------------------------------------------------------------------------------------------------------- /* * Get details for creation layout. */ @@ -142,12 +147,14 @@ void TableWindow::ModelChosen(QVector listDetails, const QString &fileNa show(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::closeEvent(QCloseEvent *event) { event->ignore(); StopTable(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::moveToCenter() { QRect rect = frameGeometry(); @@ -155,12 +162,14 @@ void TableWindow::moveToCenter() move(rect.topLeft()); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::showEvent ( QShowEvent * event ) { QMainWindow::showEvent(event); moveToCenter(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::StopTable() { hide(); @@ -172,6 +181,7 @@ void TableWindow::StopTable() emit closed(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::saveScene() { QMap extByMessage; @@ -251,12 +261,14 @@ void TableWindow::saveScene() delete brush; } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::itemChect(bool flag) { ui->actionTurn->setDisabled(flag); ui->actionMirror->setDisabled(flag); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::checkNext() { if (outItems == true && collidingItems == true) @@ -281,6 +293,7 @@ void TableWindow::checkNext() } } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::itemOut(int number, bool flag) { listOutItems->setBit(number, flag); @@ -298,6 +311,7 @@ void TableWindow::itemOut(int number, bool flag) checkNext(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::itemColliding(QList list, int number) { //qDebug()<<"number="< list, int number) checkNext(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::GetNextDetail() { AddDetail(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::AddLength() { QRectF rect = tableScene->sceneRect(); @@ -384,6 +400,7 @@ void TableWindow::AddLength() emit LengthChanged(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::RemoveLength() { if (sceneRect.height() <= tableScene->sceneRect().height() - 100) @@ -409,6 +426,7 @@ void TableWindow::RemoveLength() } } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::keyPressEvent ( QKeyEvent * event ) { if ( event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return ) @@ -422,7 +440,7 @@ void TableWindow::keyPressEvent ( QKeyEvent * event ) QMainWindow::keyPressEvent ( event ); } - +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::SvgFile(const QString &name) const { QSvgGenerator generator; @@ -442,6 +460,7 @@ void TableWindow::SvgFile(const QString &name) const painter.end(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::PngFile(const QString &name) const { QRectF r = paper->rect(); @@ -459,6 +478,7 @@ void TableWindow::PngFile(const QString &name) const image.save(name); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::PdfFile(const QString &name) const { QPrinter printer; @@ -483,6 +503,7 @@ void TableWindow::PdfFile(const QString &name) const painter.end(); } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::EpsFile(const QString &name) const { QTemporaryFile tmp; @@ -497,6 +518,7 @@ void TableWindow::EpsFile(const QString &name) const } } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::PsFile(const QString &name) const { QTemporaryFile tmp; @@ -511,6 +533,7 @@ void TableWindow::PsFile(const QString &name) const } } +//--------------------------------------------------------------------------------------------------------------------- void TableWindow::PdfToPs(const QStringList ¶ms) const { #ifndef QT_NO_CURSOR diff --git a/src/app/tools/drawTools/vabstractspline.cpp b/src/app/tools/drawTools/vabstractspline.cpp index 9ca601d57..d8ecc259c 100644 --- a/src/app/tools/drawTools/vabstractspline.cpp +++ b/src/app/tools/drawTools/vabstractspline.cpp @@ -31,17 +31,20 @@ const QString VAbstractSpline::TagName = QStringLiteral("spline"); +//--------------------------------------------------------------------------------------------------------------------- VAbstractSpline::VAbstractSpline(VPattern *doc, VContainer *data, quint32 id, QGraphicsItem *parent) :VDrawTool(doc, data, id), QGraphicsPathItem(parent), controlPoints(QVector()) { ignoreFullUpdate = true; } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractSpline::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractSpline::ChangedActivDraw(const QString &newName) { bool selectable = false; @@ -62,17 +65,20 @@ void VAbstractSpline::ChangedActivDraw(const QString &newName) VDrawTool::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractSpline::ShowTool(quint32 id, Qt::GlobalColor color, bool enable) { ShowItem(this, id, color, enable); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractSpline::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction void VAbstractSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { @@ -80,6 +86,7 @@ void VAbstractSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction void VAbstractSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { @@ -87,6 +94,7 @@ void VAbstractSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- QVariant VAbstractSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemSelectedChange) @@ -105,6 +113,7 @@ QVariant VAbstractSpline::itemChange(QGraphicsItem::GraphicsItemChange change, c return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractSpline::keyReleaseEvent(QKeyEvent *event) { switch (event->key()) diff --git a/src/app/tools/drawTools/vdrawtool.cpp b/src/app/tools/drawTools/vdrawtool.cpp index 8312f4fa5..25f329719 100644 --- a/src/app/tools/drawTools/vdrawtool.cpp +++ b/src/app/tools/drawTools/vdrawtool.cpp @@ -30,6 +30,7 @@ qreal VDrawTool::factor = 1; +//--------------------------------------------------------------------------------------------------------------------- VDrawTool::VDrawTool(VPattern *doc, VContainer *data, quint32 id) :VAbstractTool(doc, data, id), ignoreContextMenuEvent(false), ignoreFullUpdate(false), nameActivDraw(doc->GetNameActivDraw()), dialog(nullptr) @@ -39,11 +40,13 @@ VDrawTool::VDrawTool(VPattern *doc, VContainer *data, quint32 id) connect(this->doc, &VPattern::ShowTool, this, &VDrawTool::ShowTool); } +//--------------------------------------------------------------------------------------------------------------------- VDrawTool::~VDrawTool() { delete dialog; } +//--------------------------------------------------------------------------------------------------------------------- void VDrawTool::ShowTool(quint32 id, Qt::GlobalColor color, bool enable) { Q_UNUSED(id); @@ -51,6 +54,7 @@ void VDrawTool::ShowTool(quint32 id, Qt::GlobalColor color, bool enable) Q_UNUSED(enable); } +//--------------------------------------------------------------------------------------------------------------------- void VDrawTool::ChangedActivDraw(const QString &newName) { if (nameActivDraw == newName) @@ -63,6 +67,7 @@ void VDrawTool::ChangedActivDraw(const QString &newName) } } +//--------------------------------------------------------------------------------------------------------------------- void VDrawTool::ChangedNameDraw(const QString &oldName, const QString &newName) { if (nameActivDraw == oldName) @@ -71,6 +76,7 @@ void VDrawTool::ChangedNameDraw(const QString &oldName, const QString &newName) } } +//--------------------------------------------------------------------------------------------------------------------- void VDrawTool::FullUpdateFromGui(int result) { if (result == QDialog::Accepted) @@ -88,6 +94,7 @@ void VDrawTool::FullUpdateFromGui(int result) dialog = nullptr; } +//--------------------------------------------------------------------------------------------------------------------- void VDrawTool::SetFactor(qreal factor) { if (factor <= 2 && factor >= 0.5) @@ -96,6 +103,7 @@ void VDrawTool::SetFactor(qreal factor) } } +//--------------------------------------------------------------------------------------------------------------------- void VDrawTool::AddToCalculation(const QDomElement &domElement) { QDomElement calcElement; diff --git a/src/app/tools/drawTools/vtoolalongline.cpp b/src/app/tools/drawTools/vtoolalongline.cpp index 0e9b5396a..6165f562e 100644 --- a/src/app/tools/drawTools/vtoolalongline.cpp +++ b/src/app/tools/drawTools/vtoolalongline.cpp @@ -32,6 +32,7 @@ const QString VToolAlongLine::ToolType = QStringLiteral("alongLine"); +//--------------------------------------------------------------------------------------------------------------------- VToolAlongLine::VToolAlongLine(VPattern *doc, VContainer *data, quint32 id, const QString &formula, const quint32 &firstPointId, const quint32 &secondPointId, const QString &typeLine, const Valentina::Sources &typeCreation, @@ -49,6 +50,7 @@ VToolAlongLine::VToolAlongLine(VPattern *doc, VContainer *data, quint32 id, cons } } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -62,23 +64,27 @@ void VToolAlongLine::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void VToolAlongLine::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -98,6 +104,7 @@ void VToolAlongLine::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -114,12 +121,14 @@ void VToolAlongLine::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::RemoveReferens() { doc->DecrementReferens(secondPointId); VToolLinePoint::RemoveReferens(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -132,6 +141,7 @@ void VToolAlongLine::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrSecondPoint, dialogTool->getSecondPointId()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::setDialog() { Q_CHECK_PTR(dialog); @@ -145,6 +155,7 @@ void VToolAlongLine::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -159,6 +170,7 @@ void VToolAlongLine::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPatt Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolAlongLine::Create(const quint32 _id, const QString &pointName, const QString &typeLine, const QString &formula, const quint32 &firstPointId, const quint32 &secondPointId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, diff --git a/src/app/tools/drawTools/vtoolarc.cpp b/src/app/tools/drawTools/vtoolarc.cpp index 842c14675..199b1139c 100644 --- a/src/app/tools/drawTools/vtoolarc.cpp +++ b/src/app/tools/drawTools/vtoolarc.cpp @@ -34,6 +34,7 @@ const QString VToolArc::TagName = QStringLiteral("arc"); const QString VToolArc::ToolType = QStringLiteral("simple"); +//--------------------------------------------------------------------------------------------------------------------- VToolArc::VToolArc(VPattern *doc, VContainer *data, quint32 id, const Valentina::Sources &typeCreation, QGraphicsItem *parent) :VDrawTool(doc, data, id), QGraphicsPathItem(parent) @@ -58,6 +59,7 @@ VToolArc::VToolArc(VPattern *doc, VContainer *data, quint32 id, const Valentina: } } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::setDialog() { Q_CHECK_PTR(dialog); @@ -70,6 +72,7 @@ void VToolArc::setDialog() dialogTool->SetRadius(arc->GetFormulaRadius()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -83,6 +86,7 @@ void VToolArc::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *d Create(0, center, radius, f1, f2, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::Create(const quint32 _id, const quint32 ¢er, const QString &radius, const QString &f1, const QString &f2, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, const Document::Documents &parse, const Valentina::Sources &typeCreation) @@ -138,11 +142,13 @@ void VToolArc::Create(const quint32 _id, const quint32 ¢er, const QString &r } } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::ChangedActivDraw(const QString &newName) { bool selectable = false; @@ -162,22 +168,26 @@ void VToolArc::ChangedActivDraw(const QString &newName) VDrawTool::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::ShowTool(quint32 id, Qt::GlobalColor color, bool enable) { ShowItem(this, id, color, enable); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::AddToFile() { const VArc *arc = VAbstractTool::data.GeometricObject(id); @@ -193,6 +203,7 @@ void VToolArc::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::RefreshDataInFile() { const VArc *arc = VAbstractTool::data.GeometricObject(id); @@ -206,6 +217,7 @@ void VToolArc::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -215,6 +227,7 @@ void VToolArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void VToolArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { @@ -222,6 +235,7 @@ void VToolArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event) this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void VToolArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { @@ -229,12 +243,14 @@ void VToolArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::RemoveReferens() { const VArc *arc = VAbstractTool::data.GeometricObject(id); doc->DecrementReferens(arc->GetCenter().id()); } +//--------------------------------------------------------------------------------------------------------------------- QVariant VToolArc::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemSelectedChange) @@ -253,6 +269,7 @@ QVariant VToolArc::itemChange(QGraphicsItem::GraphicsItemChange change, const QV return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::keyReleaseEvent(QKeyEvent *event) { switch (event->key()) @@ -266,6 +283,7 @@ void VToolArc::keyReleaseEvent(QKeyEvent *event) QGraphicsItem::keyReleaseEvent ( event ); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -277,6 +295,7 @@ void VToolArc::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrAngle2, dialogTool->GetF2()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolArc::RefreshGeometry() { this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); diff --git a/src/app/tools/drawTools/vtoolbisector.cpp b/src/app/tools/drawTools/vtoolbisector.cpp index caac9b893..e770348d6 100644 --- a/src/app/tools/drawTools/vtoolbisector.cpp +++ b/src/app/tools/drawTools/vtoolbisector.cpp @@ -32,6 +32,7 @@ const QString VToolBisector::ToolType = QStringLiteral("bisector"); +//--------------------------------------------------------------------------------------------------------------------- VToolBisector::VToolBisector(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, const QString &formula, const quint32 &firstPointId, const quint32 &secondPointId, const quint32 &thirdPointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent) @@ -50,6 +51,7 @@ VToolBisector::VToolBisector(VPattern *doc, VContainer *data, const quint32 &id, } } +//--------------------------------------------------------------------------------------------------------------------- QPointF VToolBisector::FindPoint(const QPointF &firstPoint, const QPointF &secondPoint, const QPointF &thirdPoint, const qreal &length) { @@ -69,6 +71,7 @@ QPointF VToolBisector::FindPoint(const QPointF &firstPoint, const QPointF &secon return line1.p2(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::setDialog() { Q_CHECK_PTR(dialog); @@ -83,6 +86,7 @@ void VToolBisector::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -99,6 +103,7 @@ void VToolBisector::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPatte Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::Create(const quint32 _id, const QString &formula, const quint32 &firstPointId, const quint32 &secondPointId, const quint32 &thirdPointId, const QString &typeLine, const QString &pointName, const qreal &mx, const qreal &my, @@ -147,6 +152,7 @@ void VToolBisector::Create(const quint32 _id, const QString &formula, const quin } } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -161,22 +167,26 @@ void VToolBisector::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -197,6 +207,7 @@ void VToolBisector::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -214,6 +225,7 @@ void VToolBisector::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::RemoveReferens() { doc->DecrementReferens(firstPointId); @@ -221,6 +233,7 @@ void VToolBisector::RemoveReferens() VToolLinePoint::RemoveReferens(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolBisector::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolcutarc.cpp b/src/app/tools/drawTools/vtoolcutarc.cpp index 2ca7bf4f6..41209fb78 100644 --- a/src/app/tools/drawTools/vtoolcutarc.cpp +++ b/src/app/tools/drawTools/vtoolcutarc.cpp @@ -33,6 +33,7 @@ const QString VToolCutArc::ToolType = QStringLiteral("cutArc"); const QString VToolCutArc::AttrArc = QStringLiteral("arc"); +//--------------------------------------------------------------------------------------------------------------------- VToolCutArc::VToolCutArc(VPattern *doc, VContainer *data, const quint32 &id, const QString &formula, const quint32 &arcId, const quint32 &arc1id, const quint32 &arc2id, const Valentina::Sources &typeCreation, QGraphicsItem * parent) @@ -63,6 +64,7 @@ VToolCutArc::VToolCutArc(VPattern *doc, VContainer *data, const quint32 &id, con } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::setDialog() { Q_CHECK_PTR(dialog); @@ -74,6 +76,7 @@ void VToolCutArc::setDialog() dialogTool->setPointName(point->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -86,6 +89,7 @@ void VToolCutArc::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern Create(0, pointName, formula, arcId, 5, 10, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::Create(const quint32 _id, const QString &pointName, const QString &formula, const quint32 &arcId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, const Document::Documents &parse, const Valentina::Sources &typeCreation) @@ -151,6 +155,7 @@ void VToolCutArc::Create(const quint32 _id, const QString &pointName, const QStr } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -162,11 +167,13 @@ void VToolCutArc::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::ArcChoosed(quint32 id) { emit ChoosedTool(id, Valentina::Arc); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::ChangedActivDraw(const QString &newName) { if (nameActivDraw == newName) @@ -190,16 +197,19 @@ void VToolCutArc::ChangedActivDraw(const QString &newName) VToolPoint::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -217,6 +227,7 @@ void VToolCutArc::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -231,6 +242,7 @@ void VToolCutArc::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::RefreshGeometry() { RefreshArc(firstArc, arc1id, SimpleArc::ForthPoint); @@ -238,6 +250,7 @@ void VToolCutArc::RefreshGeometry() VToolPoint::RefreshPointGeometry(*VDrawTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -248,6 +261,7 @@ void VToolCutArc::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrArc, QString().setNum(dialogTool->getArcId())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutArc::RefreshArc(VSimpleArc *sArc, quint32 arcid, SimpleArc::Translation tr) { const VArc *arc = VAbstractTool::data.GeometricObject(arcid); diff --git a/src/app/tools/drawTools/vtoolcutspline.cpp b/src/app/tools/drawTools/vtoolcutspline.cpp index e7bb7f458..cdb8153c1 100644 --- a/src/app/tools/drawTools/vtoolcutspline.cpp +++ b/src/app/tools/drawTools/vtoolcutspline.cpp @@ -33,6 +33,7 @@ const QString VToolCutSpline::ToolType = QStringLiteral("cutSpline"); const QString VToolCutSpline::AttrSpline = QStringLiteral("spline"); +//--------------------------------------------------------------------------------------------------------------------- VToolCutSpline::VToolCutSpline(VPattern *doc, VContainer *data, const quint32 &id, const QString &formula, const quint32 &splineId, const quint32 &spl1id, const quint32 &spl2id, const Valentina::Sources &typeCreation, QGraphicsItem *parent) @@ -63,6 +64,7 @@ VToolCutSpline::VToolCutSpline(VPattern *doc, VContainer *data, const quint32 &i } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::setDialog() { Q_CHECK_PTR(dialog); @@ -74,6 +76,7 @@ void VToolCutSpline::setDialog() dialogTool->setPointName(point->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -86,6 +89,7 @@ void VToolCutSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene, Create(0, pointName, formula, splineId, 5, 10, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::Create(const quint32 _id, const QString &pointName, const QString &formula, const quint32 &splineId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, @@ -152,6 +156,7 @@ void VToolCutSpline::Create(const quint32 _id, const QString &pointName, } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -163,11 +168,13 @@ void VToolCutSpline::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::SplineChoosed(quint32 id) { emit ChoosedTool(id, Valentina::Spline); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::ChangedActivDraw(const QString &newName) { bool flag = true; @@ -186,16 +193,19 @@ void VToolCutSpline::ChangedActivDraw(const QString &newName) VToolPoint::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -213,6 +223,7 @@ void VToolCutSpline::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -227,6 +238,7 @@ void VToolCutSpline::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::RefreshGeometry() { RefreshSpline(firstSpline, spl1id, SimpleSpline::ForthPoint); @@ -234,11 +246,13 @@ void VToolCutSpline::RefreshGeometry() VToolPoint::RefreshPointGeometry(*VDrawTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::RemoveReferens() { doc->DecrementReferens(splineId); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -249,6 +263,7 @@ void VToolCutSpline::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrSpline, QString().setNum(dialogTool->getSplineId())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSpline::RefreshSpline(VSimpleSpline *spline, quint32 splid, SimpleSpline::Translation tr) { const VSpline *spl = VAbstractTool::data.GeometricObject(splid); diff --git a/src/app/tools/drawTools/vtoolcutsplinepath.cpp b/src/app/tools/drawTools/vtoolcutsplinepath.cpp index 7c879f690..55af235e5 100644 --- a/src/app/tools/drawTools/vtoolcutsplinepath.cpp +++ b/src/app/tools/drawTools/vtoolcutsplinepath.cpp @@ -33,6 +33,7 @@ const QString VToolCutSplinePath::ToolType = QStringLiteral("cutSplinePath"); const QString VToolCutSplinePath::AttrSplinePath = QStringLiteral("splinePath"); +//--------------------------------------------------------------------------------------------------------------------- VToolCutSplinePath::VToolCutSplinePath(VPattern *doc, VContainer *data, const quint32 &id, const QString &formula, const quint32 &splinePathId, const quint32 &splPath1id, const quint32 &splPath2id, @@ -64,6 +65,7 @@ VToolCutSplinePath::VToolCutSplinePath(VPattern *doc, VContainer *data, const qu } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::setDialog() { Q_CHECK_PTR(dialog); @@ -75,6 +77,7 @@ void VToolCutSplinePath::setDialog() dialogTool->setPointName(point->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -86,6 +89,7 @@ void VToolCutSplinePath::Create(DialogTool *dialog, VMainGraphicsScene *scene, V Create(0, pointName, formula, splinePathId, 5, 10, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::Create(const quint32 _id, const QString &pointName, const QString &formula, const quint32 &splinePathId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, @@ -226,6 +230,7 @@ void VToolCutSplinePath::Create(const quint32 _id, const QString &pointName, con } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -237,11 +242,13 @@ void VToolCutSplinePath::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::SplineChoosed(quint32 id) { emit ChoosedTool(id, Valentina::SplinePath); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::ChangedActivDraw(const QString &newName) { bool flag = true; @@ -260,16 +267,19 @@ void VToolCutSplinePath::ChangedActivDraw(const QString &newName) VToolPoint::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -287,6 +297,7 @@ void VToolCutSplinePath::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -301,6 +312,7 @@ void VToolCutSplinePath::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::RefreshGeometry() { RefreshSpline(firstSpline, splPath1id, SimpleSpline::ForthPoint); @@ -308,11 +320,13 @@ void VToolCutSplinePath::RefreshGeometry() VToolPoint::RefreshPointGeometry(*VDrawTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::RemoveReferens() { doc->DecrementReferens(splinePathId); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -323,6 +337,7 @@ void VToolCutSplinePath::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrSplinePath, QString().setNum(dialogTool->getSplinePathId())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolCutSplinePath::RefreshSpline(VSimpleSpline *spline, quint32 splPathid, SimpleSpline::Translation tr) { const VSplinePath *splPath = VAbstractTool::data.GeometricObject(splPathid); diff --git a/src/app/tools/drawTools/vtoolendline.cpp b/src/app/tools/drawTools/vtoolendline.cpp index d57ef5f78..14f1b2a0e 100644 --- a/src/app/tools/drawTools/vtoolendline.cpp +++ b/src/app/tools/drawTools/vtoolendline.cpp @@ -33,6 +33,7 @@ const QString VToolEndLine::ToolType = QStringLiteral("endLine"); +//--------------------------------------------------------------------------------------------------------------------- VToolEndLine::VToolEndLine(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, const QString &formula, const qreal &angle, const quint32 &basePointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent) @@ -49,6 +50,7 @@ VToolEndLine::VToolEndLine(VPattern *doc, VContainer *data, const quint32 &id, } } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::setDialog() { Q_CHECK_PTR(dialog); @@ -62,6 +64,7 @@ void VToolEndLine::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -77,6 +80,7 @@ void VToolEndLine::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPatter Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::Create(const quint32 _id, const QString &pointName, const QString &typeLine, const QString &formula, const qreal &angle, const quint32 &basePointId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, @@ -120,6 +124,7 @@ void VToolEndLine::Create(const quint32 _id, const QString &pointName, const QSt } } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -133,16 +138,19 @@ void VToolEndLine::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -162,6 +170,7 @@ void VToolEndLine::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -178,6 +187,7 @@ void VToolEndLine::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolEndLine::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolheight.cpp b/src/app/tools/drawTools/vtoolheight.cpp index 5ecfdc5b7..ab1381ac0 100644 --- a/src/app/tools/drawTools/vtoolheight.cpp +++ b/src/app/tools/drawTools/vtoolheight.cpp @@ -31,6 +31,7 @@ const QString VToolHeight::ToolType = QStringLiteral("height"); +//--------------------------------------------------------------------------------------------------------------------- VToolHeight::VToolHeight(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, const quint32 &basePointId, const quint32 &p1LineId, const quint32 &p2LineId, const Valentina::Sources &typeCreation, QGraphicsItem * parent) @@ -47,6 +48,7 @@ VToolHeight::VToolHeight(VPattern *doc, VContainer *data, const quint32 &id, con } } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::setDialog() { Q_CHECK_PTR(dialog); @@ -60,6 +62,7 @@ void VToolHeight::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -76,6 +79,7 @@ void VToolHeight::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::Create(const quint32 _id, const QString &pointName, const QString &typeLine, const quint32 &basePointId, const quint32 &p1LineId, const quint32 &p2LineId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, @@ -120,11 +124,13 @@ void VToolHeight::Create(const quint32 _id, const QString &pointName, const QStr } } +//--------------------------------------------------------------------------------------------------------------------- QPointF VToolHeight::FindPoint(const QLineF &line, const QPointF &point) { return VAbstractTool::ClosestPoint(line, point); } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -139,16 +145,19 @@ void VToolHeight::FullUpdateFromFile() } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -169,6 +178,7 @@ void VToolHeight::AddToFile() } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -185,6 +195,7 @@ void VToolHeight::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolHeight::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolline.cpp b/src/app/tools/drawTools/vtoolline.cpp index 950cbf85e..d4aab43df 100644 --- a/src/app/tools/drawTools/vtoolline.cpp +++ b/src/app/tools/drawTools/vtoolline.cpp @@ -32,6 +32,7 @@ const QString VToolLine::TagName = QStringLiteral("line"); +//--------------------------------------------------------------------------------------------------------------------- VToolLine::VToolLine(VPattern *doc, VContainer *data, quint32 id, quint32 firstPoint, quint32 secondPoint, const QString &typeLine, const Valentina::Sources &typeCreation, QGraphicsItem *parent) :VDrawTool(doc, data, id), QGraphicsLineItem(parent), firstPoint(firstPoint), secondPoint(secondPoint) @@ -58,6 +59,7 @@ VToolLine::VToolLine(VPattern *doc, VContainer *data, quint32 id, quint32 firstP } } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::setDialog() { Q_CHECK_PTR(dialog); @@ -68,6 +70,7 @@ void VToolLine::setDialog() dialogTool->setTypeLine(typeLine); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -79,6 +82,7 @@ void VToolLine::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern * Create(0, firstPoint, secondPoint, typeLine, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::Create(const quint32 &_id, const quint32 &firstPoint, const quint32 &secondPoint, const QString &typeLine, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, const Document::Documents &parse, const Valentina::Sources &typeCreation) @@ -114,22 +118,26 @@ void VToolLine::Create(const quint32 &_id, const quint32 &firstPoint, const quin } } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::ShowTool(quint32 id, Qt::GlobalColor color, bool enable) { ShowItem(this, id, color, enable); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::ChangedActivDraw(const QString &newName) { bool selectable = false; @@ -148,11 +156,13 @@ void VToolLine::ChangedActivDraw(const QString &newName) VDrawTool::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::AddToFile() { QDomElement domElement = doc->createElement(TagName); @@ -164,6 +174,7 @@ void VToolLine::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -175,24 +186,28 @@ void VToolLine::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine())/factor, LineStyle())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor, LineStyle())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::RemoveReferens() { doc->DecrementReferens(firstPoint); doc->DecrementReferens(secondPoint); } +//--------------------------------------------------------------------------------------------------------------------- QVariant VToolLine::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemSelectedChange) @@ -211,6 +226,7 @@ QVariant VToolLine::itemChange(QGraphicsItem::GraphicsItemChange change, const Q return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::keyReleaseEvent(QKeyEvent *event) { switch (event->key()) @@ -224,6 +240,7 @@ void VToolLine::keyReleaseEvent(QKeyEvent *event) QGraphicsItem::keyReleaseEvent ( event ); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -234,6 +251,7 @@ void VToolLine::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrTypeLine, dialogTool->getTypeLine()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLine::RefreshGeometry() { QDomElement domElement = doc->elementById(QString().setNum(id)); diff --git a/src/app/tools/drawTools/vtoollineintersect.cpp b/src/app/tools/drawTools/vtoollineintersect.cpp index 80630b280..1f737fe20 100644 --- a/src/app/tools/drawTools/vtoollineintersect.cpp +++ b/src/app/tools/drawTools/vtoollineintersect.cpp @@ -31,6 +31,7 @@ const QString VToolLineIntersect::ToolType = QStringLiteral("lineIntersect"); +//--------------------------------------------------------------------------------------------------------------------- VToolLineIntersect::VToolLineIntersect(VPattern *doc, VContainer *data, const quint32 &id, const quint32 &p1Line1, const quint32 &p2Line1, const quint32 &p1Line2, const quint32 &p2Line2, const Valentina::Sources &typeCreation, @@ -49,6 +50,7 @@ VToolLineIntersect::VToolLineIntersect(VPattern *doc, VContainer *data, const qu } } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::setDialog() { Q_CHECK_PTR(dialog); @@ -62,6 +64,7 @@ void VToolLineIntersect::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -76,6 +79,7 @@ void VToolLineIntersect::Create(DialogTool *dialog, VMainGraphicsScene *scene, V Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::Create(const quint32 _id, const quint32 &p1Line1Id, const quint32 &p2Line1Id, const quint32 &p1Line2Id, const quint32 &p2Line2Id, const QString &pointName, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, @@ -131,6 +135,7 @@ void VToolLineIntersect::Create(const quint32 _id, const quint32 &p1Line1Id, con } } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -144,22 +149,26 @@ void VToolLineIntersect::FullUpdateFromFile() RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -179,6 +188,7 @@ void VToolLineIntersect::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -195,6 +205,7 @@ void VToolLineIntersect::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::RemoveReferens() { doc->DecrementReferens(p1Line1); @@ -203,6 +214,7 @@ void VToolLineIntersect::RemoveReferens() doc->DecrementReferens(p2Line2); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLineIntersect::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoollinepoint.cpp b/src/app/tools/drawTools/vtoollinepoint.cpp index 89d2ab7c4..c5dc5d5a7 100644 --- a/src/app/tools/drawTools/vtoollinepoint.cpp +++ b/src/app/tools/drawTools/vtoollinepoint.cpp @@ -28,6 +28,7 @@ #include "vtoollinepoint.h" +//--------------------------------------------------------------------------------------------------------------------- VToolLinePoint::VToolLinePoint(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, const QString &formula, const quint32 &basePointId, const qreal &angle, QGraphicsItem *parent) @@ -43,6 +44,7 @@ VToolLinePoint::VToolLinePoint(VPattern *doc, VContainer *data, const quint32 &i mainLine->setFlag(QGraphicsItem::ItemStacksBehindParent, true); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLinePoint::ChangedActivDraw(const QString &newName) { if (nameActivDraw == newName) @@ -57,6 +59,7 @@ void VToolLinePoint::ChangedActivDraw(const QString &newName) VToolPoint::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLinePoint::RefreshGeometry() { mainLine->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor, LineStyle())); @@ -66,6 +69,7 @@ void VToolLinePoint::RefreshGeometry() mainLine->setLine(QLineF(basePoint - point, QPointF())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolLinePoint::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); diff --git a/src/app/tools/drawTools/vtoolnormal.cpp b/src/app/tools/drawTools/vtoolnormal.cpp index 0a2c038b5..0c3c75b3d 100644 --- a/src/app/tools/drawTools/vtoolnormal.cpp +++ b/src/app/tools/drawTools/vtoolnormal.cpp @@ -32,6 +32,7 @@ const QString VToolNormal::ToolType = QStringLiteral("normal"); +//--------------------------------------------------------------------------------------------------------------------- VToolNormal::VToolNormal(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, const QString &formula, const qreal &angle, const quint32 &firstPointId, const quint32 &secondPointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent) @@ -49,6 +50,7 @@ VToolNormal::VToolNormal(VPattern *doc, VContainer *data, const quint32 &id, con } } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::setDialog() { Q_CHECK_PTR(dialog); @@ -63,6 +65,7 @@ void VToolNormal::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -78,6 +81,7 @@ void VToolNormal::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::Create(const quint32 _id, const QString &formula, const quint32 &firstPointId, const quint32 &secondPointId, const QString &typeLine, const QString &pointName, const qreal angle, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, @@ -123,6 +127,7 @@ void VToolNormal::Create(const quint32 _id, const QString &formula, const quint3 } } +//--------------------------------------------------------------------------------------------------------------------- QPointF VToolNormal::FindPoint(const QPointF &firstPoint, const QPointF &secondPoint, const qreal &length, const qreal &angle) { @@ -133,6 +138,7 @@ QPointF VToolNormal::FindPoint(const QPointF &firstPoint, const QPointF &secondP return normal.p2(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -147,22 +153,26 @@ void VToolNormal::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -183,6 +193,7 @@ void VToolNormal::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -200,12 +211,14 @@ void VToolNormal::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::RemoveReferens() { doc->DecrementReferens(secondPointId); VToolLinePoint::RemoveReferens(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolNormal::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolpoint.cpp b/src/app/tools/drawTools/vtoolpoint.cpp index a6ab0578b..563e749a2 100644 --- a/src/app/tools/drawTools/vtoolpoint.cpp +++ b/src/app/tools/drawTools/vtoolpoint.cpp @@ -33,6 +33,7 @@ const QString VToolPoint::TagName = QStringLiteral("point"); #define DefRadius 2.0//mm +//--------------------------------------------------------------------------------------------------------------------- VToolPoint::VToolPoint(VPattern *doc, VContainer *data, quint32 id, QGraphicsItem *parent):VDrawTool(doc, data, id), QGraphicsEllipseItem(parent), radius(DefRadius), namePoint(0), lineName(0) { @@ -65,6 +66,7 @@ VToolPoint::VToolPoint(VPattern *doc, VContainer *data, quint32 id, QGraphicsIte RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::NameChangePosition(const QPointF &pos) { VPointF *point = new VPointF(*VAbstractTool::data.GeometricObject(id)); @@ -76,6 +78,7 @@ void VToolPoint::NameChangePosition(const QPointF &pos) VAbstractTool::data.UpdateGObject(id, point); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::UpdateNamePosition(qreal mx, qreal my) { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -87,6 +90,7 @@ void VToolPoint::UpdateNamePosition(qreal mx, qreal my) } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::ChangedActivDraw(const QString &newName) { bool selectable = false; @@ -112,22 +116,26 @@ void VToolPoint::ChangedActivDraw(const QString &newName) VDrawTool::ChangedActivDraw(newName); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::ShowTool(quint32 id, Qt::GlobalColor color, bool enable) { ShowItem(this, id, color, enable); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { Q_UNUSED(event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -137,18 +145,21 @@ void VToolPoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::RefreshPointGeometry(const VPointF &point) { this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); @@ -166,6 +177,7 @@ void VToolPoint::RefreshPointGeometry(const VPointF &point) RefreshLine(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::RefreshLine() { QRectF nameRec = namePoint->sceneBoundingRect(); @@ -191,6 +203,7 @@ void VToolPoint::RefreshLine() } } +//--------------------------------------------------------------------------------------------------------------------- QVariant VToolPoint::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemSelectedChange) @@ -209,6 +222,7 @@ QVariant VToolPoint::itemChange(QGraphicsItem::GraphicsItemChange change, const return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPoint::keyReleaseEvent(QKeyEvent *event) { switch (event->key()) diff --git a/src/app/tools/drawTools/vtoolpointofcontact.cpp b/src/app/tools/drawTools/vtoolpointofcontact.cpp index 69aa5bf20..305ee98dd 100644 --- a/src/app/tools/drawTools/vtoolpointofcontact.cpp +++ b/src/app/tools/drawTools/vtoolpointofcontact.cpp @@ -32,6 +32,7 @@ const QString VToolPointOfContact::ToolType = QStringLiteral("pointOfContact"); +//--------------------------------------------------------------------------------------------------------------------- VToolPointOfContact::VToolPointOfContact(VPattern *doc, VContainer *data, const quint32 &id, const QString &radius, const quint32 ¢er, const quint32 &firstPointId, const quint32 &secondPointId, @@ -49,6 +50,7 @@ VToolPointOfContact::VToolPointOfContact(VPattern *doc, VContainer *data, const } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::setDialog() { Q_CHECK_PTR(dialog); @@ -62,6 +64,7 @@ void VToolPointOfContact::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- QPointF VToolPointOfContact::FindPoint(const qreal &radius, const QPointF ¢er, const QPointF &firstPoint, const QPointF &secondPoint) { @@ -88,6 +91,7 @@ QPointF VToolPointOfContact::FindPoint(const qreal &radius, const QPointF ¢e return pArc; } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -102,6 +106,7 @@ void VToolPointOfContact::Create(DialogTool *dialog, VMainGraphicsScene *scene, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::Create(const quint32 _id, const QString &radius, const quint32 ¢er, const quint32 &firstPointId, const quint32 &secondPointId, const QString &pointName, const qreal &mx, const qreal &my, @@ -154,6 +159,7 @@ void VToolPointOfContact::Create(const quint32 _id, const QString &radius, const } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -167,22 +173,26 @@ void VToolPointOfContact::FullUpdateFromFile() RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -202,6 +212,7 @@ void VToolPointOfContact::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -218,6 +229,7 @@ void VToolPointOfContact::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::RemoveReferens() { doc->DecrementReferens(center); @@ -225,6 +237,7 @@ void VToolPointOfContact::RemoveReferens() doc->DecrementReferens(secondPointId); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfContact::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolpointofintersection.cpp b/src/app/tools/drawTools/vtoolpointofintersection.cpp index 2b91430f7..8d0a35a14 100644 --- a/src/app/tools/drawTools/vtoolpointofintersection.cpp +++ b/src/app/tools/drawTools/vtoolpointofintersection.cpp @@ -31,6 +31,7 @@ const QString VToolPointOfIntersection::ToolType = QStringLiteral("pointOfIntersection"); +//--------------------------------------------------------------------------------------------------------------------- VToolPointOfIntersection::VToolPointOfIntersection(VPattern *doc, VContainer *data, const quint32 &id, const quint32 &firstPointId, const quint32 &secondPointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent) @@ -47,6 +48,7 @@ VToolPointOfIntersection::VToolPointOfIntersection(VPattern *doc, VContainer *da } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::setDialog() { Q_CHECK_PTR(dialog); @@ -58,6 +60,7 @@ void VToolPointOfIntersection::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -70,6 +73,7 @@ void VToolPointOfIntersection::Create(DialogTool *dialog, VMainGraphicsScene *sc Create(0, pointName, firstPointId, secondPointId, 5, 10, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::Create(const quint32 _id, const QString &pointName, const quint32 &firstPointId, const quint32 &secondPointId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, @@ -106,6 +110,7 @@ void VToolPointOfIntersection::Create(const quint32 _id, const QString &pointNam } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -117,22 +122,26 @@ void VToolPointOfIntersection::FullUpdateFromFile() VToolPoint::RefreshPointGeometry(*VDrawTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::RemoveReferens() { doc->DecrementReferens(firstPointId); doc->DecrementReferens(secondPointId); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -150,6 +159,7 @@ void VToolPointOfIntersection::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -164,6 +174,7 @@ void VToolPointOfIntersection::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolPointOfIntersection::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolshoulderpoint.cpp b/src/app/tools/drawTools/vtoolshoulderpoint.cpp index 47fb729ac..cdd026c81 100644 --- a/src/app/tools/drawTools/vtoolshoulderpoint.cpp +++ b/src/app/tools/drawTools/vtoolshoulderpoint.cpp @@ -32,6 +32,7 @@ const QString VToolShoulderPoint::ToolType = QStringLiteral("shoulder"); +//--------------------------------------------------------------------------------------------------------------------- VToolShoulderPoint::VToolShoulderPoint(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, const QString &formula, const quint32 &p1Line, const quint32 &p2Line, const quint32 &pShoulder, const Valentina::Sources &typeCreation, @@ -48,6 +49,7 @@ VToolShoulderPoint::VToolShoulderPoint(VPattern *doc, VContainer *data, const qu } } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::setDialog() { Q_CHECK_PTR(dialog); @@ -62,6 +64,7 @@ void VToolShoulderPoint::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- QPointF VToolShoulderPoint::FindPoint(const QPointF &p1Line, const QPointF &p2Line, const QPointF &pShoulder, const qreal &length) { @@ -89,6 +92,7 @@ QPointF VToolShoulderPoint::FindPoint(const QPointF &p1Line, const QPointF &p2Li } } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -104,6 +108,7 @@ void VToolShoulderPoint::Create(DialogTool *dialog, VMainGraphicsScene *scene, V Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::Create(const quint32 _id, const QString &formula, const quint32 &p1Line, const quint32 &p2Line, const quint32 &pShoulder, const QString &typeLine, const QString &pointName, const qreal &mx, const qreal &my, @@ -155,6 +160,7 @@ void VToolShoulderPoint::Create(const quint32 _id, const QString &formula, const } } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -169,22 +175,26 @@ void VToolShoulderPoint::FullUpdateFromFile() RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -205,6 +215,7 @@ void VToolShoulderPoint::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -222,6 +233,7 @@ void VToolShoulderPoint::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::RemoveReferens() { doc->DecrementReferens(p2Line); @@ -229,6 +241,7 @@ void VToolShoulderPoint::RemoveReferens() VToolLinePoint::RemoveReferens(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolShoulderPoint::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/drawTools/vtoolsinglepoint.cpp b/src/app/tools/drawTools/vtoolsinglepoint.cpp index fd0f63c18..2c542cc5d 100644 --- a/src/app/tools/drawTools/vtoolsinglepoint.cpp +++ b/src/app/tools/drawTools/vtoolsinglepoint.cpp @@ -31,6 +31,7 @@ const QString VToolSinglePoint::ToolType = QStringLiteral("single"); +//--------------------------------------------------------------------------------------------------------------------- VToolSinglePoint::VToolSinglePoint (VPattern *doc, VContainer *data, quint32 id, const Valentina::Sources &typeCreation, QGraphicsItem * parent ) :VToolPoint(doc, data, id, parent) @@ -53,6 +54,7 @@ VToolSinglePoint::VToolSinglePoint (VPattern *doc, VContainer *data, quint32 id, } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::setDialog() { Q_CHECK_PTR(dialog); @@ -62,6 +64,7 @@ void VToolSinglePoint::setDialog() dialogTool->setData(p->name(), p->toQPointF()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -78,6 +81,7 @@ void VToolSinglePoint::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -92,6 +96,7 @@ void VToolSinglePoint::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- QVariant VToolSinglePoint::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) @@ -128,6 +133,7 @@ QVariant VToolSinglePoint::itemChange(QGraphicsItem::GraphicsItemChange change, return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::decrementReferens() { if (_referens > 1) @@ -136,6 +142,7 @@ void VToolSinglePoint::decrementReferens() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -148,23 +155,27 @@ void VToolSinglePoint::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrY, QString().setNum(qApp->fromPixel(p.y()))); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::setColorLabel(const Qt::GlobalColor &color) { namePoint->setBrush(color); lineName->setPen(QPen(color, qApp->toPixel(qApp->widthHairLine())/factor)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ) { ContextMenu(this, event, false); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::FullUpdateFromFile() { VPointF point = *VAbstractTool::data.GeometricObject(id); RefreshPointGeometry(point); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::ChangedActivDraw(const QString &newName) { if (nameActivDraw == newName) @@ -181,12 +192,14 @@ void VToolSinglePoint::ChangedActivDraw(const QString &newName) } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::SetFactor(qreal factor) { VDrawTool::SetFactor(factor); RefreshPointGeometry(*(VAbstractTool::data.GeometricObject(id))); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSinglePoint::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event, false); diff --git a/src/app/tools/drawTools/vtoolspline.cpp b/src/app/tools/drawTools/vtoolspline.cpp index 71a5a9dd9..ca87c745a 100644 --- a/src/app/tools/drawTools/vtoolspline.cpp +++ b/src/app/tools/drawTools/vtoolspline.cpp @@ -32,6 +32,7 @@ const QString VToolSpline::ToolType = QStringLiteral("simple"); +//--------------------------------------------------------------------------------------------------------------------- VToolSpline::VToolSpline(VPattern *doc, VContainer *data, quint32 id, const Valentina::Sources &typeCreation, QGraphicsItem *parent) :VAbstractSpline(doc, data, id, parent) { @@ -71,6 +72,7 @@ VToolSpline::VToolSpline(VPattern *doc, VContainer *data, quint32 id, const Vale } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::setDialog() { Q_CHECK_PTR(dialog); @@ -86,6 +88,7 @@ void VToolSpline::setDialog() dialogTool->setKCurve(spl->GetKcurve()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -103,6 +106,7 @@ void VToolSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::Create(const quint32 _id, const quint32 &p1, const quint32 &p4, const qreal &kAsm1, const qreal kAsm2, const qreal &angle1, const qreal &angle2, const qreal &kCurve, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, @@ -139,6 +143,7 @@ void VToolSpline::Create(const quint32 _id, const quint32 &p1, const quint32 &p4 } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const SplinePoint::Position &position, const QPointF &pos) { @@ -166,6 +171,7 @@ void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const Sp } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); @@ -189,6 +195,7 @@ void VToolSpline::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::RefreshDataInFile() { const VSpline *spl = VAbstractTool::data.GeometricObject(id); @@ -205,6 +212,7 @@ void VToolSpline::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -214,6 +222,7 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::RemoveReferens() { const VSpline *spl = VAbstractTool::data.GeometricObject(id); @@ -221,6 +230,7 @@ void VToolSpline::RemoveReferens() doc->DecrementReferens(spl->GetP4().id()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -254,6 +264,7 @@ void VToolSpline::SaveDialog(QDomElement &domElement) doc->SetAttribute(domElement, AttrKCurve, spl.GetKcurve()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSpline::RefreshGeometry() { this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); diff --git a/src/app/tools/drawTools/vtoolsplinepath.cpp b/src/app/tools/drawTools/vtoolsplinepath.cpp index 1de4c5327..6d18d81a0 100644 --- a/src/app/tools/drawTools/vtoolsplinepath.cpp +++ b/src/app/tools/drawTools/vtoolsplinepath.cpp @@ -31,6 +31,7 @@ const QString VToolSplinePath::ToolType = QStringLiteral("path"); +//--------------------------------------------------------------------------------------------------------------------- VToolSplinePath::VToolSplinePath(VPattern *doc, VContainer *data, quint32 id, const Valentina::Sources &typeCreation, QGraphicsItem *parent) :VAbstractSpline(doc, data, id, parent) { @@ -72,6 +73,7 @@ VToolSplinePath::VToolSplinePath(VPattern *doc, VContainer *data, quint32 id, co } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::setDialog() { Q_CHECK_PTR(dialog); @@ -81,6 +83,7 @@ void VToolSplinePath::setDialog() dialogTool->SetPath(*splPath); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -94,6 +97,7 @@ void VToolSplinePath::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPat Create(0, path, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::Create(const quint32 _id, VSplinePath *path, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, const Document::Documents &parse, const Valentina::Sources &typeCreation) @@ -124,6 +128,7 @@ void VToolSplinePath::Create(const quint32 _id, VSplinePath *path, VMainGraphics } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, const SplinePoint::Position &position, const QPointF &pos) { @@ -149,6 +154,7 @@ void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, cons } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::CorectControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) { VSplinePoint p = splPath.GetSplinePoint(indexSpline, SplinePoint::FirstPoint); @@ -162,6 +168,7 @@ void VToolSplinePath::CorectControlPoints(const VSpline &spl, VSplinePath &splPa splPath.UpdatePoint(indexSpline, SplinePoint::LastPoint, p); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::RefreshSplinePath(VSplinePath &splPath) { for (qint32 i = 1; i<=splPath.Count(); ++i) @@ -186,6 +193,7 @@ void VToolSplinePath::RefreshSplinePath(VSplinePath &splPath) } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::UpdatePathPoint(QDomNode& node, VSplinePath &path) { QDomNodeList nodeList = node.childNodes(); @@ -204,11 +212,13 @@ void VToolSplinePath::UpdatePathPoint(QDomNode& node, VSplinePath &path) } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::AddToFile() { VSplinePath splPath = *VAbstractTool::data.GeometricObject(id); @@ -226,6 +236,7 @@ void VToolSplinePath::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -240,6 +251,7 @@ void VToolSplinePath::RefreshDataInFile() UpdatePathPoint(domElement, splPath); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::AddPathPoint(QDomElement &domElement, const VSplinePoint &splPoint) { QDomElement pathPoint = doc->createElement(AttrPathPoint); @@ -252,6 +264,7 @@ void VToolSplinePath::AddPathPoint(QDomElement &domElement, const VSplinePoint & domElement.appendChild(pathPoint); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -261,6 +274,7 @@ void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::RemoveReferens() { VSplinePath splPath = *VAbstractTool::data.GeometricObject(id); @@ -270,6 +284,7 @@ void VToolSplinePath::RemoveReferens() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); @@ -282,6 +297,7 @@ void VToolSplinePath::SaveDialog(QDomElement &domElement) UpdatePathPoint(domElement, splPath); } +//--------------------------------------------------------------------------------------------------------------------- void VToolSplinePath::RefreshGeometry() { this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine())/factor)); diff --git a/src/app/tools/drawTools/vtooltriangle.cpp b/src/app/tools/drawTools/vtooltriangle.cpp index 542092d75..d9c679201 100644 --- a/src/app/tools/drawTools/vtooltriangle.cpp +++ b/src/app/tools/drawTools/vtooltriangle.cpp @@ -31,6 +31,7 @@ const QString VToolTriangle::ToolType = QStringLiteral("triangle"); +//--------------------------------------------------------------------------------------------------------------------- VToolTriangle::VToolTriangle(VPattern *doc, VContainer *data, const quint32 &id, const quint32 &axisP1Id, const quint32 &axisP2Id, const quint32 &firstPointId, const quint32 &secondPointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent) @@ -48,6 +49,7 @@ VToolTriangle::VToolTriangle(VPattern *doc, VContainer *data, const quint32 &id, } } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::setDialog() { Q_CHECK_PTR(dialog); @@ -61,6 +63,7 @@ void VToolTriangle::setDialog() dialogTool->setPointName(p->name()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { @@ -76,6 +79,7 @@ void VToolTriangle::Create(DialogTool *dialog, VMainGraphicsScene *scene, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::Create(const quint32 _id, const QString &pointName, const quint32 &axisP1Id, const quint32 &axisP2Id, const quint32 &firstPointId, const quint32 &secondPointId, const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, @@ -117,6 +121,7 @@ void VToolTriangle::Create(const quint32 _id, const QString &pointName, const qu } } +//--------------------------------------------------------------------------------------------------------------------- QPointF VToolTriangle::FindPoint(const QPointF &axisP1, const QPointF &axisP2, const QPointF &firstPoint, const QPointF &secondPoint) { @@ -158,6 +163,7 @@ QPointF VToolTriangle::FindPoint(const QPointF &axisP1, const QPointF &axisP2, c } } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::FullUpdateFromFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -171,11 +177,13 @@ void VToolTriangle::FullUpdateFromFile() VToolPoint::RefreshPointGeometry(*VDrawTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::RemoveReferens() { doc->DecrementReferens(axisP1Id); @@ -184,11 +192,13 @@ void VToolTriangle::RemoveReferens() doc->DecrementReferens(secondPointId); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { ContextMenu(this, event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -208,6 +218,7 @@ void VToolTriangle::AddToFile() AddToCalculation(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -224,6 +235,7 @@ void VToolTriangle::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolTriangle::SaveDialog(QDomElement &domElement) { Q_CHECK_PTR(dialog); diff --git a/src/app/tools/nodeDetails/vabstractnode.cpp b/src/app/tools/nodeDetails/vabstractnode.cpp index 1b721a203..eafadc8b0 100644 --- a/src/app/tools/nodeDetails/vabstractnode.cpp +++ b/src/app/tools/nodeDetails/vabstractnode.cpp @@ -32,6 +32,7 @@ const QString VAbstractNode::AttrIdObject = QStringLiteral("idObject"); const QString VAbstractNode::AttrIdTool = QStringLiteral("idTool"); +//--------------------------------------------------------------------------------------------------------------------- VAbstractNode::VAbstractNode(VPattern *doc, VContainer *data, const quint32 &id, const quint32 &idNode, const quint32 &idTool, QObject *parent) : VAbstractTool(doc, data, id, parent), idNode(idNode), idTool(idTool) @@ -39,6 +40,7 @@ VAbstractNode::VAbstractNode(VPattern *doc, VContainer *data, const quint32 &id, _referens = 0; } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractNode::DeleteNode() { if (_referens <= 1) @@ -73,6 +75,7 @@ void VAbstractNode::DeleteNode() } } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractNode::AddToModeling(const QDomElement &domElement) { QDomElement modelingElement; @@ -88,6 +91,7 @@ void VAbstractNode::AddToModeling(const QDomElement &domElement) emit toolhaveChange(); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractNode::decrementReferens() { if (_referens > 0) diff --git a/src/app/tools/nodeDetails/vnodearc.cpp b/src/app/tools/nodeDetails/vnodearc.cpp index a31ebf812..b87aeb9fb 100644 --- a/src/app/tools/nodeDetails/vnodearc.cpp +++ b/src/app/tools/nodeDetails/vnodearc.cpp @@ -34,6 +34,7 @@ const QString VNodeArc::TagName = QStringLiteral("arc"); const QString VNodeArc::ToolType = QStringLiteral("modeling"); +//--------------------------------------------------------------------------------------------------------------------- VNodeArc::VNodeArc(VPattern *doc, VContainer *data, quint32 id, quint32 idArc, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *qoParent, QGraphicsItem *parent) :VAbstractNode(doc, data, id, idArc, idTool, qoParent), QGraphicsPathItem(parent) @@ -51,6 +52,7 @@ VNodeArc::VNodeArc(VPattern *doc, VContainer *data, quint32 id, quint32 idArc, c } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idArc, const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *parent) { @@ -78,17 +80,20 @@ void VNodeArc::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idArc } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::DeleteNode() { VAbstractNode::DeleteNode(); this->setVisible(false); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::AddToFile() { QDomElement domElement = doc->createElement(TagName); @@ -104,6 +109,7 @@ void VNodeArc::AddToFile() AddToModeling(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -117,6 +123,7 @@ void VNodeArc::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -126,18 +133,21 @@ void VNodeArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeArc::RefreshGeometry() { const VArc *arc = VAbstractTool::data.GeometricObject(id); diff --git a/src/app/tools/nodeDetails/vnodepoint.cpp b/src/app/tools/nodeDetails/vnodepoint.cpp index 854d5fcf7..d6735f89c 100644 --- a/src/app/tools/nodeDetails/vnodepoint.cpp +++ b/src/app/tools/nodeDetails/vnodepoint.cpp @@ -34,6 +34,7 @@ const QString VNodePoint::TagName = QStringLiteral("point"); const QString VNodePoint::ToolType = QStringLiteral("modeling"); +//--------------------------------------------------------------------------------------------------------------------- VNodePoint::VNodePoint(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *qoParent, QGraphicsItem *parent) @@ -59,6 +60,7 @@ VNodePoint::VNodePoint(VPattern *doc, VContainer *data, quint32 id, quint32 idPo } } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *parent) @@ -89,17 +91,20 @@ void VNodePoint::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idP } } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::DeleteNode() { VAbstractNode::DeleteNode(); this->setVisible(false); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::FullUpdateFromFile() { RefreshPointGeometry(*VAbstractTool::data.GeometricObject(id)); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::AddToFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -118,6 +123,7 @@ void VNodePoint::AddToFile() AddToModeling(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::RefreshDataInFile() { const VPointF *point = VAbstractTool::data.GeometricObject(id); @@ -134,6 +140,7 @@ void VNodePoint::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -143,19 +150,21 @@ void VNodePoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine()))); } - +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::NameChangePosition(const QPointF &pos) { VPointF *point = new VPointF(*VAbstractTool::data.GeometricObject(id)); @@ -167,6 +176,7 @@ void VNodePoint::NameChangePosition(const QPointF &pos) VAbstractTool::data.UpdateGObject(id, point); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::UpdateNamePosition(qreal mx, qreal my) { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -178,6 +188,7 @@ void VNodePoint::UpdateNamePosition(qreal mx, qreal my) } } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::RefreshPointGeometry(const VPointF &point) { QRectF rec = QRectF(0, 0, radius*2, radius*2); @@ -194,6 +205,7 @@ void VNodePoint::RefreshPointGeometry(const VPointF &point) RefreshLine(); } +//--------------------------------------------------------------------------------------------------------------------- void VNodePoint::RefreshLine() { QRectF nameRec = namePoint->sceneBoundingRect(); diff --git a/src/app/tools/nodeDetails/vnodespline.cpp b/src/app/tools/nodeDetails/vnodespline.cpp index f0d017d79..bebdb7042 100644 --- a/src/app/tools/nodeDetails/vnodespline.cpp +++ b/src/app/tools/nodeDetails/vnodespline.cpp @@ -34,6 +34,7 @@ const QString VNodeSpline::TagName = QStringLiteral("spline"); const QString VNodeSpline::ToolType = QStringLiteral("modelingSpline"); +//--------------------------------------------------------------------------------------------------------------------- VNodeSpline::VNodeSpline(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *qoParent, QGraphicsItem * parent) @@ -52,6 +53,7 @@ VNodeSpline::VNodeSpline(VPattern *doc, VContainer *data, quint32 id, quint32 id } } +//--------------------------------------------------------------------------------------------------------------------- VNodeSpline *VNodeSpline::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *parent) @@ -82,17 +84,20 @@ VNodeSpline *VNodeSpline::Create(VPattern *doc, VContainer *data, quint32 id, qu return spl; } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::DeleteNode() { VAbstractNode::DeleteNode(); this->setVisible(false); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::AddToFile() { QDomElement domElement = doc->createElement(TagName); @@ -108,6 +113,7 @@ void VNodeSpline::AddToFile() AddToModeling(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -121,6 +127,7 @@ void VNodeSpline::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -130,18 +137,21 @@ void VNodeSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSpline::RefreshGeometry() { const VSpline *spl = VAbstractTool::data.GeometricObject(id); diff --git a/src/app/tools/nodeDetails/vnodesplinepath.cpp b/src/app/tools/nodeDetails/vnodesplinepath.cpp index 49008ceee..8b2fc44fd 100644 --- a/src/app/tools/nodeDetails/vnodesplinepath.cpp +++ b/src/app/tools/nodeDetails/vnodesplinepath.cpp @@ -34,6 +34,7 @@ const QString VNodeSplinePath::TagName = QStringLiteral("spline"); const QString VNodeSplinePath::ToolType = QStringLiteral("modelingPath"); +//--------------------------------------------------------------------------------------------------------------------- VNodeSplinePath::VNodeSplinePath(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *qoParent, QGraphicsItem * parent) @@ -52,6 +53,7 @@ VNodeSplinePath::VNodeSplinePath(VPattern *doc, VContainer *data, quint32 id, qu } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool, QObject *parent) @@ -85,17 +87,20 @@ void VNodeSplinePath::Create(VPattern *doc, VContainer *data, quint32 id, quint3 } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::DeleteNode() { VAbstractNode::DeleteNode(); this->setVisible(false); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::AddToFile() { QDomElement domElement = doc->createElement(TagName); @@ -111,6 +116,7 @@ void VNodeSplinePath::AddToFile() AddToModeling(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -124,6 +130,7 @@ void VNodeSplinePath::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -133,18 +140,21 @@ void VNodeSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthHairLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VNodeSplinePath::RefreshGeometry() { const VSplinePath *splPath = VAbstractTool::data.GeometricObject(id); diff --git a/src/app/tools/vabstracttool.cpp b/src/app/tools/vabstracttool.cpp index 50ff3af22..523d702fe 100644 --- a/src/app/tools/vabstracttool.cpp +++ b/src/app/tools/vabstracttool.cpp @@ -70,6 +70,7 @@ const QString VAbstractTool::TypeLineDotLine = QStringLiteral("dotLine"); const QString VAbstractTool::TypeLineDashDotLine = QStringLiteral("dashDotLine"); const QString VAbstractTool::TypeLineDashDotDotLine = QStringLiteral("dashDotDotLine"); +//--------------------------------------------------------------------------------------------------------------------- VAbstractTool::VAbstractTool(VPattern *doc, VContainer *data, quint32 id, QObject *parent) :VDataTool(data, parent), doc(doc), id(id), baseColor(Qt::black), currentColor(Qt::black), typeLine(TypeLineLine) { @@ -80,6 +81,7 @@ VAbstractTool::VAbstractTool(VPattern *doc, VContainer *data, quint32 id, QObjec emit toolhaveChange(); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractTool::NewSceneRect(QGraphicsScene *sc, QGraphicsView *view) { QRectF rect = sc->itemsBoundingRect(); @@ -108,6 +110,7 @@ void VAbstractTool::NewSceneRect(QGraphicsScene *sc, QGraphicsView *view) sc->setSceneRect(rec1); } +//--------------------------------------------------------------------------------------------------------------------- QPointF VAbstractTool::LineIntersectRect(QRectF rec, QLineF line) { qreal x1, y1, x2, y2; @@ -137,6 +140,7 @@ QPointF VAbstractTool::LineIntersectRect(QRectF rec, QLineF line) return point; } +//--------------------------------------------------------------------------------------------------------------------- qint32 VAbstractTool::LineIntersectCircle(const QPointF ¢er, qreal radius, const QLineF &line, QPointF &p1, QPointF &p2) { @@ -172,6 +176,7 @@ qint32 VAbstractTool::LineIntersectCircle(const QPointF ¢er, qreal radius, c return flag; } +//--------------------------------------------------------------------------------------------------------------------- QPointF VAbstractTool::ClosestPoint(const QLineF &line, const QPointF &point) { qreal a = 0, b = 0, c = 0; @@ -191,11 +196,13 @@ QPointF VAbstractTool::ClosestPoint(const QLineF &line, const QPointF &point) } } +//--------------------------------------------------------------------------------------------------------------------- QPointF VAbstractTool::addVector(const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k) { return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k); } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractTool::RemoveAllChild(QDomElement &domElement) { if ( domElement.hasChildNodes() ) @@ -207,6 +214,7 @@ void VAbstractTool::RemoveAllChild(QDomElement &domElement) } } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractTool::DeleteTool(QGraphicsItem *tool) { if (_referens <= 1) @@ -257,6 +265,7 @@ void VAbstractTool::DeleteTool(QGraphicsItem *tool) } } +//--------------------------------------------------------------------------------------------------------------------- Qt::PenStyle VAbstractTool::LineStyle() { QStringList styles = Styles(); @@ -286,6 +295,7 @@ Qt::PenStyle VAbstractTool::LineStyle() } } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractTool::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c) { //coefficient for equation of segment @@ -295,6 +305,7 @@ void VAbstractTool::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qre *c = - *a * p1.x() - *b * p1.y(); } +//--------------------------------------------------------------------------------------------------------------------- const QStringList VAbstractTool::Styles() { //Keep synchronize with DialogTool lineStyles list!!! @@ -304,6 +315,7 @@ const QStringList VAbstractTool::Styles() return styles; } +//--------------------------------------------------------------------------------------------------------------------- void VAbstractTool::AddRecord(const quint32 id, const Valentina::Tools &toolType, VPattern *doc) { quint32 cursor = doc->getCursor(); diff --git a/src/app/tools/vdatatool.cpp b/src/app/tools/vdatatool.cpp index 3c791f08b..ec16d4f67 100644 --- a/src/app/tools/vdatatool.cpp +++ b/src/app/tools/vdatatool.cpp @@ -28,11 +28,13 @@ #include "vdatatool.h" +//--------------------------------------------------------------------------------------------------------------------- VDataTool::VDataTool(VContainer *data, QObject *parent): QObject(parent), data(*data), _referens(1) { Q_CHECK_PTR(data); } +//--------------------------------------------------------------------------------------------------------------------- VDataTool &VDataTool::operator =(const VDataTool &tool) { data = tool.getData(); @@ -40,6 +42,7 @@ VDataTool &VDataTool::operator =(const VDataTool &tool) return *this; } +//--------------------------------------------------------------------------------------------------------------------- void VDataTool::decrementReferens() { if (_referens > 0) diff --git a/src/app/tools/vtooldetail.cpp b/src/app/tools/vtooldetail.cpp index 2e109114c..c5d2dfa1c 100644 --- a/src/app/tools/vtooldetail.cpp +++ b/src/app/tools/vtooldetail.cpp @@ -50,6 +50,7 @@ const QString VToolDetail::NodePoint = QStringLiteral("NodePoint"); const QString VToolDetail::NodeSpline = QStringLiteral("NodeSpline"); const QString VToolDetail::NodeSplinePath = QStringLiteral("NodeSplinePath"); +//--------------------------------------------------------------------------------------------------------------------- VToolDetail::VToolDetail(VPattern *doc, VContainer *data, const quint32 &id, const Valentina::Sources &typeCreation, VMainGraphicsScene *scene, QGraphicsItem *parent) :VAbstractTool(doc, data, id), QGraphicsPathItem(parent), dialog(nullptr), sceneDetails(scene) @@ -89,11 +90,13 @@ VToolDetail::VToolDetail(VPattern *doc, VContainer *data, const quint32 &id, con } } +//--------------------------------------------------------------------------------------------------------------------- VToolDetail::~VToolDetail() { delete dialog; } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::setDialog() { Q_CHECK_PTR(dialog); @@ -103,6 +106,7 @@ void VToolDetail::setDialog() dialogTool->setDetails(detail); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -150,6 +154,7 @@ void VToolDetail::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern Create(0, det, scene, doc, data, Document::FullParse, Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::Create(const quint32 &_id, const VDetail &newDetail, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, const Document::Documents &parse, const Valentina::Sources &typeCreation) { @@ -177,16 +182,19 @@ void VToolDetail::Create(const quint32 &_id, const VDetail &newDetail, VMainGrap } } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::Remove() { DeleteTool(this); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::FullUpdateFromFile() { RefreshGeometry(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::FullUpdateFromGui(int result) { if (result == QDialog::Accepted) @@ -226,6 +234,7 @@ void VToolDetail::FullUpdateFromGui(int result) dialog = 0; } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::AddToFile() { VDetail detail = VAbstractTool::data.GetDetail(id); @@ -252,6 +261,7 @@ void VToolDetail::AddToFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -270,6 +280,7 @@ void VToolDetail::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- QVariant VToolDetail::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionHasChanged && scene()) @@ -306,6 +317,7 @@ QVariant VToolDetail::itemChange(QGraphicsItem::GraphicsItemChange change, const return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::keyReleaseEvent(QKeyEvent *event) { switch (event->key()) @@ -319,6 +331,7 @@ void VToolDetail::keyReleaseEvent(QKeyEvent *event) QGraphicsItem::keyReleaseEvent ( event ); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -328,6 +341,7 @@ void VToolDetail::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; @@ -359,6 +373,7 @@ void VToolDetail::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::RemoveReferens() { VDetail detail = VAbstractTool::data.GetDetail(id); @@ -368,6 +383,7 @@ void VToolDetail::RemoveReferens() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::AddNode(QDomElement &domElement, const VNodeDetail &node) { QDomElement nod = doc->createElement(TagNode); @@ -404,12 +420,14 @@ void VToolDetail::AddNode(QDomElement &domElement, const VNodeDetail &node) domElement.appendChild(nod); } +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::RefreshGeometry() { QPainterPath path = VEquidistant().ContourPath(id, this->getData()); this->setPath(path); } +//--------------------------------------------------------------------------------------------------------------------- template //cppcheck-suppress unusedFunction void VToolDetail::InitTool(VMainGraphicsScene *scene, const VNodeDetail &node) diff --git a/src/app/tools/vtooluniondetails.cpp b/src/app/tools/vtooluniondetails.cpp index 7281ac086..56fbf01fd 100644 --- a/src/app/tools/vtooluniondetails.cpp +++ b/src/app/tools/vtooluniondetails.cpp @@ -41,6 +41,7 @@ const QString VToolUnionDetails::AttrNodeType = QStringLiteral("nodeType"); const QString VToolUnionDetails::NodeTypeContour = QStringLiteral("Contour"); const QString VToolUnionDetails::NodeTypeModeling = QStringLiteral("Modeling"); +//--------------------------------------------------------------------------------------------------------------------- VToolUnionDetails::VToolUnionDetails(VPattern *doc, VContainer *data, const quint32 &id, const VDetail &d1, const VDetail &d2, const quint32 &indexD1, const quint32 &indexD2, const Valentina::Sources &typeCreation, QObject *parent) @@ -56,6 +57,7 @@ VToolUnionDetails::VToolUnionDetails(VPattern *doc, VContainer *data, const quin } } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::AddToNewDetail(QObject *tool, VPattern *doc, VContainer *data, VDetail &newDetail, const VDetail &det, const ptrdiff_t &i, const quint32 &idTool, const qreal &dx, const qreal &dy, const quint32 &pRotate, const qreal &angle) @@ -222,6 +224,7 @@ void VToolUnionDetails::AddToNewDetail(QObject *tool, VPattern *doc, VContainer newDetail.append(VNodeDetail(id, det.at(i).getTypeTool(), NodeDetail::Contour)); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::UpdatePoints(const quint32 &idDetail, VContainer *data, const VDetail &det, const ptrdiff_t &i, quint32 &idCount, const qreal &dx, const qreal &dy, const quint32 &pRotate, const qreal &angle) @@ -369,6 +372,7 @@ void VToolUnionDetails::UpdatePoints(const quint32 &idDetail, VContainer *data, } } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::BiasRotatePoint(VPointF *point, const qreal &dx, const qreal &dy, const QPointF &pRotate, const qreal angle) { @@ -380,6 +384,7 @@ void VToolUnionDetails::BiasRotatePoint(VPointF *point, const qreal &dx, const q point->setY(line.p2().y()); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, VContainer *data) { Q_CHECK_PTR(dialog); @@ -393,6 +398,7 @@ void VToolUnionDetails::Create(DialogTool *dialog, VMainGraphicsScene *scene, VP Valentina::FromGui); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::Create(const quint32 _id, const VDetail &d1, const VDetail &d2, const quint32 &d1id, const quint32 &d2id, const quint32 &indexD1, const quint32 &indexD2, VMainGraphicsScene *scene, VPattern *doc, VContainer *data, @@ -528,6 +534,7 @@ void VToolUnionDetails::Create(const quint32 _id, const VDetail &d1, const VDeta } } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::PointsOnEdge(const VDetail &d, const qint32 &index, VPointF &p1, VPointF &p2, VContainer *data) { VNodeDetail det2p1; @@ -537,6 +544,7 @@ void VToolUnionDetails::PointsOnEdge(const VDetail &d, const qint32 &index, VPoi p2 = VPointF(*data->GeometricObject(det2p2.getId())); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::FindJ(const qint32 &pointsD2, const VDetail &d2, const qint32 &indexD2, qint32 &j) { if (pointsD2 == 0) @@ -556,6 +564,7 @@ void VToolUnionDetails::FindJ(const qint32 &pointsD2, const VDetail &d2, const q } } +//--------------------------------------------------------------------------------------------------------------------- QVector VToolUnionDetails::GetDetailFromFile(VPattern *doc, const QDomElement &domElement) { QVector vector; @@ -611,6 +620,7 @@ QVector VToolUnionDetails::GetDetailFromFile(VPattern *doc, const QDomE return vector; } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::AddToFile() { QDomElement domElement = doc->createElement(TagName); @@ -626,6 +636,7 @@ void VToolUnionDetails::AddToFile() AddToModeling(domElement); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::RefreshDataInFile() { QDomElement domElement = doc->elementById(QString().setNum(id)); @@ -640,6 +651,7 @@ void VToolUnionDetails::RefreshDataInFile() } } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::AddDetail(QDomElement &domElement, VDetail &d) { QDomElement det = doc->createElement(TagDetail); @@ -652,6 +664,7 @@ void VToolUnionDetails::AddDetail(QDomElement &domElement, VDetail &d) domElement.appendChild(det); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::AddNode(QDomElement &domElement, const VNodeDetail &node) { QDomElement nod = doc->createElement(TagNode); @@ -688,6 +701,7 @@ void VToolUnionDetails::AddNode(QDomElement &domElement, const VNodeDetail &node domElement.appendChild(nod); } +//--------------------------------------------------------------------------------------------------------------------- QDomNode VToolUnionDetails::UpdateDetail(const QDomNode &domNode, const VDetail &d) { //QDomNode domNode = domElement.firstChild(); @@ -713,6 +727,7 @@ QDomNode VToolUnionDetails::UpdateDetail(const QDomNode &domNode, const VDetail return domNode.nextSibling(); } +//--------------------------------------------------------------------------------------------------------------------- void VToolUnionDetails::AddToModeling(const QDomElement &domElement) { QDomElement modelingElement; diff --git a/src/app/widgets/doubledelegate.cpp b/src/app/widgets/doubledelegate.cpp index bce09af06..8f611b1ee 100644 --- a/src/app/widgets/doubledelegate.cpp +++ b/src/app/widgets/doubledelegate.cpp @@ -30,6 +30,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction QWidget *DoubleSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const @@ -43,6 +44,7 @@ QWidget *DoubleSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOption return editor; } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void DoubleSpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { @@ -53,6 +55,7 @@ void DoubleSpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &in spinBox->setValue(value); } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void DoubleSpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { @@ -64,6 +67,7 @@ void DoubleSpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *mo model->setData(index, value, Qt::EditRole); } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void DoubleSpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -72,6 +76,7 @@ void DoubleSpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOp editor->setGeometry(option.rect); } +//--------------------------------------------------------------------------------------------------------------------- void DoubleSpinBoxDelegate::commitAndCloseEditor() { QDoubleSpinBox *spinBox = qobject_cast(sender()); diff --git a/src/app/widgets/textdelegate.cpp b/src/app/widgets/textdelegate.cpp index e7c7ebad8..1584ebc18 100644 --- a/src/app/widgets/textdelegate.cpp +++ b/src/app/widgets/textdelegate.cpp @@ -30,6 +30,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- TextDelegate::TextDelegate(const QString ®ex, QObject *parent): QItemDelegate(parent), lastText(QString("Name_")), regex(regex) { @@ -37,6 +38,7 @@ TextDelegate::TextDelegate(const QString ®ex, QObject *parent): QItemDelegate connect(this, &TextDelegate::SaveText, this, &TextDelegate::InitText); } +//--------------------------------------------------------------------------------------------------------------------- QWidget *TextDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option); @@ -48,6 +50,7 @@ QWidget *TextDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem return editor; } +//--------------------------------------------------------------------------------------------------------------------- void TextDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString text = index.model()->data(index, Qt::EditRole).toString(); @@ -62,6 +65,7 @@ void TextDelegate::setEditorData(QWidget *editor, const QModelIndex &index) cons lineEdit->setText(text); } +//--------------------------------------------------------------------------------------------------------------------- void TextDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QLineEdit *lineEdit = qobject_cast(editor); @@ -75,6 +79,7 @@ void TextDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, cons model->setData(index, text, Qt::EditRole); } +//--------------------------------------------------------------------------------------------------------------------- void TextDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -82,6 +87,7 @@ void TextDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewI editor->setGeometry(option.rect); } +//--------------------------------------------------------------------------------------------------------------------- void TextDelegate::commitAndCloseEditor() { QLineEdit *lineEdit = qobject_cast(sender()); @@ -100,6 +106,7 @@ void TextDelegate::commitAndCloseEditor() emit closeEditor(lineEdit); } +//--------------------------------------------------------------------------------------------------------------------- void TextDelegate::InitText(const QString &text) { lastText = text; diff --git a/src/app/widgets/vapplication.cpp b/src/app/widgets/vapplication.cpp index 061ca841c..be1e45304 100644 --- a/src/app/widgets/vapplication.cpp +++ b/src/app/widgets/vapplication.cpp @@ -40,6 +40,7 @@ const qreal VApplication::PrintDPI = 96.0; #define DefWidth 1.2//mm +//--------------------------------------------------------------------------------------------------------------------- VApplication::VApplication(int &argc, char **argv) : QApplication(argc, argv), _patternUnit(Valentina::Cm), _patternType(Pattern::Individual), _widthMainLine(DefWidth), _widthHairLine(DefWidth/3.0) @@ -47,6 +48,7 @@ VApplication::VApplication(int &argc, char **argv) InitLineWidth(); } +//--------------------------------------------------------------------------------------------------------------------- // reimplemented from QApplication so we can throw exceptions in slots bool VApplication::notify(QObject *receiver, QEvent *event) { @@ -91,6 +93,7 @@ bool VApplication::notify(QObject *receiver, QEvent *event) return false; } +//--------------------------------------------------------------------------------------------------------------------- double VApplication::toPixel(double unit) const { double result = 0; @@ -111,6 +114,7 @@ double VApplication::toPixel(double unit) const return result; } +//--------------------------------------------------------------------------------------------------------------------- double VApplication::fromPixel(double pix) const { double result = 0; @@ -130,6 +134,8 @@ double VApplication::fromPixel(double pix) const } return result; } + +//--------------------------------------------------------------------------------------------------------------------- QString VApplication::pathToTables() const { if (_patternType == Pattern::Individual) @@ -158,6 +164,7 @@ QString VApplication::pathToTables() const } } +//--------------------------------------------------------------------------------------------------------------------- QString VApplication::translationsPath() const { #ifdef Q_OS_WIN @@ -171,7 +178,7 @@ QString VApplication::translationsPath() const #endif } - +//--------------------------------------------------------------------------------------------------------------------- void VApplication::InitLineWidth() { switch (_patternUnit) @@ -192,7 +199,7 @@ void VApplication::InitLineWidth() _widthHairLine = _widthMainLine/3.0; } - +//--------------------------------------------------------------------------------------------------------------------- void VApplication::setPatternUnit(const Valentina::Units &patternUnit) { _patternUnit = patternUnit; diff --git a/src/app/widgets/vcontrolpointspline.cpp b/src/app/widgets/vcontrolpointspline.cpp index 6968f9459..56bbf6e2c 100644 --- a/src/app/widgets/vcontrolpointspline.cpp +++ b/src/app/widgets/vcontrolpointspline.cpp @@ -32,6 +32,7 @@ #include #include "../widgets/vapplication.h" +//--------------------------------------------------------------------------------------------------------------------- VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePoint::Position position, const QPointF &controlPoint, const QPointF &splinePoint, QGraphicsItem *parent) @@ -57,18 +58,21 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePoint: controlLine->setFlag(QGraphicsItem::ItemStacksBehindParent, true); } +//--------------------------------------------------------------------------------------------------------------------- void VControlPointSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthMainLine()))); } +//--------------------------------------------------------------------------------------------------------------------- void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthHairLine()))); } +//--------------------------------------------------------------------------------------------------------------------- QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) @@ -80,6 +84,7 @@ QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange chang return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VControlPointSpline::RefreshLine(const qint32 &indexSpline, SplinePoint::Position pos, const QPointF &controlPoint, const QPointF &splinePoint) { @@ -91,6 +96,7 @@ void VControlPointSpline::RefreshLine(const qint32 &indexSpline, SplinePoint::Po } } +//--------------------------------------------------------------------------------------------------------------------- void VControlPointSpline::setEnabledPoint(bool enable) { if (enable == true) diff --git a/src/app/widgets/vgraphicssimpletextitem.cpp b/src/app/widgets/vgraphicssimpletextitem.cpp index 10a8f01eb..4cadfbbe2 100644 --- a/src/app/widgets/vgraphicssimpletextitem.cpp +++ b/src/app/widgets/vgraphicssimpletextitem.cpp @@ -30,6 +30,7 @@ #include +//--------------------------------------------------------------------------------------------------------------------- VGraphicsSimpleTextItem::VGraphicsSimpleTextItem(QGraphicsItem * parent) :QGraphicsSimpleTextItem(parent), fontSize(0) { @@ -43,6 +44,7 @@ VGraphicsSimpleTextItem::VGraphicsSimpleTextItem(QGraphicsItem * parent) this->setFont(font); } +//--------------------------------------------------------------------------------------------------------------------- VGraphicsSimpleTextItem::VGraphicsSimpleTextItem( const QString & text, QGraphicsItem * parent ) :QGraphicsSimpleTextItem(text, parent), fontSize(0) { @@ -52,6 +54,7 @@ VGraphicsSimpleTextItem::VGraphicsSimpleTextItem( const QString & text, QGraphic this->setAcceptHoverEvents(true); } +//--------------------------------------------------------------------------------------------------------------------- QVariant VGraphicsSimpleTextItem::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) @@ -62,18 +65,21 @@ QVariant VGraphicsSimpleTextItem::itemChange(GraphicsItemChange change, const QV return QGraphicsItem::itemChange(change, value); } +//--------------------------------------------------------------------------------------------------------------------- void VGraphicsSimpleTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setBrush(Qt::green); } +//--------------------------------------------------------------------------------------------------------------------- void VGraphicsSimpleTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setBrush(Qt::black); } +//--------------------------------------------------------------------------------------------------------------------- void VGraphicsSimpleTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { emit ShowContextMenu(event); diff --git a/src/app/widgets/vitem.cpp b/src/app/widgets/vitem.cpp index 561549b7f..f75559412 100644 --- a/src/app/widgets/vitem.cpp +++ b/src/app/widgets/vitem.cpp @@ -32,22 +32,21 @@ #include #include "../widgets/vapplication.h" +//--------------------------------------------------------------------------------------------------------------------- VItem::VItem (const QPainterPath & path, int numInList, QGraphicsItem * parent ) :QGraphicsPathItem ( path, parent ), numInOutList(numInList), paper(nullptr) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VItem::VItem():numInOutList(0), paper(nullptr) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- VItem::VItem(int numInList, QGraphicsItem *parent):QGraphicsPathItem (parent), numInOutList(numInList), paper(nullptr) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- void VItem::checkItemChange() { QRectF rect; @@ -87,6 +86,7 @@ void VItem::checkItemChange() //qDebug()<<"list="< +//--------------------------------------------------------------------------------------------------------------------- VMainGraphicsScene::VMainGraphicsScene() :QGraphicsScene(), horScrollBar(0), verScrollBar(0), scaleFactor(1), _transform(QTransform()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- VMainGraphicsScene::VMainGraphicsScene(const QRectF & sceneRect, QObject * parent) :QGraphicsScene ( sceneRect, parent ), horScrollBar(0), verScrollBar(0), scaleFactor(1), _transform(QTransform()) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { emit mouseMove(event->scenePos()); QGraphicsScene::mouseMoveEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { emit mousePress(event->scenePos()); QGraphicsScene::mousePressEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- QTransform VMainGraphicsScene::transform() const { return _transform; } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsScene::setTransform(const QTransform &transform) { _transform = transform; } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsScene::ChoosedItem(quint32 id, const Valentina::Scenes &type) { emit ChoosedObject(id, type); } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsScene::SetFactor(qreal factor) { scaleFactor=scaleFactor*factor; diff --git a/src/app/widgets/vmaingraphicsview.cpp b/src/app/widgets/vmaingraphicsview.cpp index 017789898..5ba1cc11c 100644 --- a/src/app/widgets/vmaingraphicsview.cpp +++ b/src/app/widgets/vmaingraphicsview.cpp @@ -34,6 +34,7 @@ #include #include "../tools/vabstracttool.h" +//--------------------------------------------------------------------------------------------------------------------- VMainGraphicsView::VMainGraphicsView(QWidget *parent) :QGraphicsView(parent), _numScheduledScalings(0) { @@ -42,6 +43,7 @@ VMainGraphicsView::VMainGraphicsView(QWidget *parent) this->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); } +//--------------------------------------------------------------------------------------------------------------------- //cppcheck-suppress unusedFunction void VMainGraphicsView::wheelEvent(QWheelEvent *event) { @@ -68,6 +70,7 @@ void VMainGraphicsView::wheelEvent(QWheelEvent *event) anim->start(); } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsView::scalingTime(qreal x) { Q_UNUSED(x); @@ -86,6 +89,7 @@ void VMainGraphicsView::scalingTime(qreal x) emit NewFactor(factor); } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsView::scrollingTime(qreal x) { Q_UNUSED(x); @@ -105,6 +109,7 @@ void VMainGraphicsView::scrollingTime(qreal x) } } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsView::animFinished() { if (_numScheduledScalings > 0) @@ -118,6 +123,7 @@ void VMainGraphicsView::animFinished() sender()->~QObject(); } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsView::mousePressEvent(QMouseEvent *mousePress) { if (mousePress->button() & Qt::LeftButton) @@ -135,6 +141,7 @@ void VMainGraphicsView::mousePressEvent(QMouseEvent *mousePress) } } +//--------------------------------------------------------------------------------------------------------------------- void VMainGraphicsView::mouseReleaseEvent(QMouseEvent *event) { QGraphicsView::mouseReleaseEvent ( event ); diff --git a/src/app/widgets/vsimplearc.cpp b/src/app/widgets/vsimplearc.cpp index 20e35aac6..7a3c8a359 100644 --- a/src/app/widgets/vsimplearc.cpp +++ b/src/app/widgets/vsimplearc.cpp @@ -31,6 +31,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- VSimpleArc::VSimpleArc(quint32 id, Qt::GlobalColor *currentColor, qreal *factor, QObject *parent) :QObject(parent), QGraphicsPathItem(), id (id), factor(factor), currentColor(currentColor) { @@ -46,6 +47,7 @@ VSimpleArc::VSimpleArc(quint32 id, Qt::GlobalColor *currentColor, qreal *factor, setAcceptHoverEvents(true); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -55,6 +57,7 @@ void VSimpleArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); @@ -68,6 +71,7 @@ void VSimpleArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); diff --git a/src/app/widgets/vsimplespline.cpp b/src/app/widgets/vsimplespline.cpp index 2aa9d83fb..9f30b30f5 100644 --- a/src/app/widgets/vsimplespline.cpp +++ b/src/app/widgets/vsimplespline.cpp @@ -30,6 +30,7 @@ #include "../widgets/vapplication.h" #include +//--------------------------------------------------------------------------------------------------------------------- VSimpleSpline::VSimpleSpline(quint32 id, Qt::GlobalColor *currentColor, qreal *factor, QObject *parent) :QObject(parent), QGraphicsPathItem(), id (id), factor(factor), currentColor(currentColor) { @@ -45,6 +46,7 @@ VSimpleSpline::VSimpleSpline(quint32 id, Qt::GlobalColor *currentColor, qreal *f setAcceptHoverEvents(true); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSpline::ChangedActivDraw(const bool &flag) { setFlag(QGraphicsItem::ItemIsSelectable, flag); @@ -52,6 +54,7 @@ void VSimpleSpline::ChangedActivDraw(const bool &flag) setPen(QPen(*currentColor, qApp->toPixel(qApp->widthHairLine())/ *factor)); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -61,6 +64,7 @@ void VSimpleSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); @@ -74,6 +78,7 @@ void VSimpleSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); diff --git a/src/app/widgets/vsimplesplinepath.cpp b/src/app/widgets/vsimplesplinepath.cpp index d73b71b52..6decd6d2f 100644 --- a/src/app/widgets/vsimplesplinepath.cpp +++ b/src/app/widgets/vsimplesplinepath.cpp @@ -30,11 +30,12 @@ #include "../widgets/vapplication.h" #include +//--------------------------------------------------------------------------------------------------------------------- VSimpleSplinePath::VSimpleSplinePath(VPattern *doc, VContainer *data, quint32 id, qreal *factor) :VAbstractTool(doc, data, id), factor(factor) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) @@ -44,12 +45,14 @@ void VSimpleSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsItem::mouseReleaseEvent(event); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSplinePath::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); this->setPen(QPen(currentColor, qApp->toPixel(qApp->widthMainLine())/ *factor)); } +//--------------------------------------------------------------------------------------------------------------------- void VSimpleSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); diff --git a/src/app/widgets/vtablegraphicsview.cpp b/src/app/widgets/vtablegraphicsview.cpp index 385fc26c8..3ef25896f 100644 --- a/src/app/widgets/vtablegraphicsview.cpp +++ b/src/app/widgets/vtablegraphicsview.cpp @@ -32,6 +32,7 @@ #include #include +//--------------------------------------------------------------------------------------------------------------------- VTableGraphicsView::VTableGraphicsView(QGraphicsScene* pScene, QWidget *parent) :QGraphicsView(pScene, parent) { @@ -39,6 +40,7 @@ VTableGraphicsView::VTableGraphicsView(QGraphicsScene* pScene, QWidget *parent) connect(pScene, &QGraphicsScene::selectionChanged, this, &VTableGraphicsView::selectionChanged); } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::selectionChanged() { QList listSelectedItems = scene()->selectedItems(); @@ -54,6 +56,7 @@ void VTableGraphicsView::selectionChanged() } } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::MirrorItem() { QList list = scene()->selectedItems(); @@ -94,6 +97,7 @@ void VTableGraphicsView::MirrorItem() } } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::wheelEvent(QWheelEvent *event) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) @@ -114,6 +118,7 @@ void VTableGraphicsView::wheelEvent(QWheelEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::mousePressEvent(QMouseEvent *mousePress) { if (mousePress->button() & Qt::LeftButton) @@ -131,12 +136,14 @@ void VTableGraphicsView::mousePressEvent(QMouseEvent *mousePress) } } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::mouseReleaseEvent(QMouseEvent *event) { QGraphicsView::mouseReleaseEvent ( event ); QGraphicsView::setDragMode( QGraphicsView::RubberBandDrag ); } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::keyPressEvent(QKeyEvent *event) { switch (event->key()) @@ -162,6 +169,7 @@ void VTableGraphicsView::keyPressEvent(QKeyEvent *event) QGraphicsView::keyPressEvent ( event ); } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::rotateIt() { QList list = scene()->selectedItems(); @@ -177,6 +185,7 @@ void VTableGraphicsView::rotateIt() } } +//--------------------------------------------------------------------------------------------------------------------- void VTableGraphicsView::MoveItem(VTableGraphicsView::typeMove_e move) { qreal dx = 0, dy = 0; diff --git a/src/app/xml/vdomdocument.cpp b/src/app/xml/vdomdocument.cpp index d0fd35ae9..d5b57b219 100644 --- a/src/app/xml/vdomdocument.cpp +++ b/src/app/xml/vdomdocument.cpp @@ -64,16 +64,19 @@ private: QSourceLocation m_sourceLocation; }; +//--------------------------------------------------------------------------------------------------------------------- inline QString MessageHandler::statusMessage() const { return m_description; } +//--------------------------------------------------------------------------------------------------------------------- inline qint64 MessageHandler::line() const { return m_sourceLocation.line(); } +//--------------------------------------------------------------------------------------------------------------------- inline qint64 MessageHandler::column() const { return m_sourceLocation.column(); @@ -85,12 +88,12 @@ const QString VDomDocument::UnitMM = QStringLiteral("mm"); const QString VDomDocument::UnitCM = QStringLiteral("cm"); const QString VDomDocument::UnitINCH = QStringLiteral("inch"); +//--------------------------------------------------------------------------------------------------------------------- VDomDocument::VDomDocument(VContainer *data) : QDomDocument(), data(data), map(QHash()) -{ - -} +{} +//--------------------------------------------------------------------------------------------------------------------- QDomElement VDomDocument::elementById(const QString& id) { if (map.contains(id)) @@ -111,6 +114,7 @@ QDomElement VDomDocument::elementById(const QString& id) return QDomElement(); } +//--------------------------------------------------------------------------------------------------------------------- void VDomDocument::removeAllChilds(QDomElement &element) { QDomNode domNode = element.firstChild(); @@ -128,6 +132,7 @@ void VDomDocument::removeAllChilds(QDomElement &element) } } +//--------------------------------------------------------------------------------------------------------------------- bool VDomDocument::find(const QDomElement &node, const QString& id) { if (node.hasAttribute(AttrId)) @@ -154,6 +159,7 @@ bool VDomDocument::find(const QDomElement &node, const QString& id) return false; } +//--------------------------------------------------------------------------------------------------------------------- quint32 VDomDocument::GetParametrUInt(const QDomElement &domElement, const QString &name, const QString &defValue) const { Q_ASSERT_X(name.isEmpty() == false, Q_FUNC_INFO, "name of parametr is empty"); @@ -183,6 +189,7 @@ quint32 VDomDocument::GetParametrUInt(const QDomElement &domElement, const QStri return id; } +//--------------------------------------------------------------------------------------------------------------------- QString VDomDocument::GetParametrString(const QDomElement &domElement, const QString &name, const QString &defValue) const { @@ -203,6 +210,7 @@ QString VDomDocument::GetParametrString(const QDomElement &domElement, const QSt return parameter; } +//--------------------------------------------------------------------------------------------------------------------- qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QString &name, const QString &defValue) const { Q_ASSERT_X(name.isEmpty() == false, Q_FUNC_INFO, "name of parametr is empty"); @@ -230,6 +238,7 @@ qreal VDomDocument::GetParametrDouble(const QDomElement &domElement, const QStri return param; } +//--------------------------------------------------------------------------------------------------------------------- QString VDomDocument::UniqueTagText(const QString &tagName, const QString &defVal) const { const QDomNodeList nodeList = this->elementsByTagName(tagName); @@ -252,6 +261,7 @@ QString VDomDocument::UniqueTagText(const QString &tagName, const QString &defVa return defVal; } +//--------------------------------------------------------------------------------------------------------------------- void VDomDocument::ValidateXML(const QString &schema, const QString &fileName) { QFile pattern(fileName); @@ -301,6 +311,7 @@ void VDomDocument::ValidateXML(const QString &schema, const QString &fileName) fileSchema.close(); } +//--------------------------------------------------------------------------------------------------------------------- void VDomDocument::setContent(const QString &fileName) { QFile file(fileName); @@ -322,6 +333,7 @@ void VDomDocument::setContent(const QString &fileName) } } +//--------------------------------------------------------------------------------------------------------------------- Valentina::Units VDomDocument::StrToUnits(const QString &unit) { QStringList units; @@ -345,6 +357,7 @@ Valentina::Units VDomDocument::StrToUnits(const QString &unit) return result; } +//--------------------------------------------------------------------------------------------------------------------- QString VDomDocument::UnitsToStr(const Valentina::Units &unit) { QString result; @@ -366,6 +379,7 @@ QString VDomDocument::UnitsToStr(const Valentina::Units &unit) return result; } +//--------------------------------------------------------------------------------------------------------------------- bool VDomDocument::SaveDocument(const QString &fileName) { if (fileName.isEmpty()) @@ -416,6 +430,7 @@ bool VDomDocument::SaveDocument(const QString &fileName) return result; } +//--------------------------------------------------------------------------------------------------------------------- void VDomDocument::setTagText(const QString &tag, const QString &text) { const QDomNodeList nodeList = this->elementsByTagName(tag); diff --git a/src/app/xml/vindividualmeasurements.cpp b/src/app/xml/vindividualmeasurements.cpp index 455f848b7..57a98d5f9 100644 --- a/src/app/xml/vindividualmeasurements.cpp +++ b/src/app/xml/vindividualmeasurements.cpp @@ -46,21 +46,24 @@ const QString VIndividualMeasurements::TagEmail = QStringLiteral("email") const QString VIndividualMeasurements::SexMale = QStringLiteral("male"); const QString VIndividualMeasurements::SexFemale = QStringLiteral("female"); +//--------------------------------------------------------------------------------------------------------------------- VIndividualMeasurements::VIndividualMeasurements(VContainer *data):VDomDocument(data) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- Valentina::Units VIndividualMeasurements::Unit() const { const QString unit = UniqueTagText(TagUnit, UnitCM); return VDomDocument::StrToUnits(unit); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::setUnit(const Valentina::Units &unit) { setTagText(TagUnit, UnitsToStr(unit)); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::Measurements() { //head and neck @@ -152,6 +155,7 @@ void VIndividualMeasurements::Measurements() Measurement("crotch_height"); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::Measurement(const QString &tag) { const QDomNodeList nodeList = this->elementsByTagName(tag); @@ -218,62 +222,74 @@ void VIndividualMeasurements::Measurement(const QString &tag) } } +//--------------------------------------------------------------------------------------------------------------------- QString VIndividualMeasurements::Language() const { return UniqueTagText(TagLang, "en"); } +//--------------------------------------------------------------------------------------------------------------------- QString VIndividualMeasurements::FamilyName() const { return UniqueTagText(TagFamily_name, ""); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::setFamilyName(const QString &text) { setTagText(TagFamily_name, text); } +//--------------------------------------------------------------------------------------------------------------------- QString VIndividualMeasurements::GivenName() const { return UniqueTagText(TagGiven_name, ""); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::setGivenName(const QString &text) { setTagText(TagGiven_name, text); } +//--------------------------------------------------------------------------------------------------------------------- QDate VIndividualMeasurements::BirthDate() const { const QString date = UniqueTagText(TagBirth_date, "1900-01-01"); return QDate::fromString(date, "yyyy-MM-dd"); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::setBirthDate(const QDate &date) { setTagText(TagBirth_date, date.toString("yyyy-MM-dd")); } +//--------------------------------------------------------------------------------------------------------------------- VIndividualMeasurements::Genders VIndividualMeasurements::Sex() const { return StrToGender(UniqueTagText(TagSex, "")); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::setSex(const VIndividualMeasurements::Genders &sex) { setTagText(TagSex, GenderToStr(sex)); } +//--------------------------------------------------------------------------------------------------------------------- QString VIndividualMeasurements::Mail() const { return UniqueTagText(TagEmail, ""); } +//--------------------------------------------------------------------------------------------------------------------- void VIndividualMeasurements::setMail(const QString &text) { setTagText(TagEmail, text); } +//--------------------------------------------------------------------------------------------------------------------- QString VIndividualMeasurements::GenderToStr(const VIndividualMeasurements::Genders &sex) { switch (sex) @@ -287,6 +303,7 @@ QString VIndividualMeasurements::GenderToStr(const VIndividualMeasurements::Gend } } +//--------------------------------------------------------------------------------------------------------------------- VIndividualMeasurements::Genders VIndividualMeasurements::StrToGender(const QString &sex) { QStringList genders; diff --git a/src/app/xml/vpattern.cpp b/src/app/xml/vpattern.cpp index 56ca2737b..1a0637923 100644 --- a/src/app/xml/vpattern.cpp +++ b/src/app/xml/vpattern.cpp @@ -67,12 +67,13 @@ const QString VPattern::IncrementKsize = QStringLiteral("ksize"); const QString VPattern::IncrementKgrowth = QStringLiteral("kgrowth"); const QString VPattern::IncrementDescription = QStringLiteral("description"); +//--------------------------------------------------------------------------------------------------------------------- VPattern::VPattern(VContainer *data, QComboBox *comboBoxDraws, Valentina::Draws *mode, QObject *parent) : QObject(parent), VDomDocument(data), nameActivDraw(QString()), tools(QHash()), history(QVector()), cursor(0), comboBoxDraws(comboBoxDraws), mode(mode), patternModified(false) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- void VPattern::CreateEmptyFile(const QString &tablePath) { if (tablePath.isEmpty()) @@ -98,6 +99,7 @@ void VPattern::CreateEmptyFile(const QString &tablePath) insertBefore(createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""), this->firstChild()); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ChangeActivDraw(const QString &name, const Document::Documents &parse) { Q_ASSERT_X(name.isEmpty() == false, "ChangeActivDraw", "name draw is empty"); @@ -111,6 +113,7 @@ void VPattern::ChangeActivDraw(const QString &name, const Document::Documents &p } } +//--------------------------------------------------------------------------------------------------------------------- bool VPattern::GetActivDrawElement(QDomElement &element) { if (nameActivDraw.isEmpty() == false) @@ -136,6 +139,7 @@ bool VPattern::GetActivDrawElement(QDomElement &element) return false; } +//--------------------------------------------------------------------------------------------------------------------- bool VPattern::appendDraw(const QString &name) { Q_ASSERT_X(name.isEmpty() == false, "appendDraw", "name draw is empty"); @@ -169,6 +173,7 @@ bool VPattern::appendDraw(const QString &name) return false; } +//--------------------------------------------------------------------------------------------------------------------- bool VPattern::SetNameDraw(const QString &name) { Q_ASSERT_X(name.isEmpty() == false, "SetNameDraw", "name draw is empty"); @@ -189,6 +194,7 @@ bool VPattern::SetNameDraw(const QString &name) } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::Parse(const Document::Documents &parse, VMainGraphicsScene *sceneDraw, VMainGraphicsScene *sceneDetail) { Q_CHECK_PTR(sceneDraw); @@ -246,6 +252,7 @@ void VPattern::Parse(const Document::Documents &parse, VMainGraphicsScene *scene } } +//--------------------------------------------------------------------------------------------------------------------- VDataTool *VPattern::getTool(const quint32 &id) { if (tools.contains(id)) @@ -260,12 +267,14 @@ VDataTool *VPattern::getTool(const quint32 &id) return 0; } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::setCursor(const quint32 &value) { cursor = value; emit ChangedCursor(cursor); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::setCurrentData() { if (*mode == Valentina::Calculation) @@ -305,6 +314,7 @@ void VPattern::setCurrentData() } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::AddTool(const quint32 &id, VDataTool *tool) { Q_ASSERT_X(id > 0, Q_FUNC_INFO, "id <= 0"); @@ -312,6 +322,7 @@ void VPattern::AddTool(const quint32 &id, VDataTool *tool) tools.insert(id, tool); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::UpdateToolData(const quint32 &id, VContainer *data) { Q_ASSERT_X(id > 0, Q_FUNC_INFO, "id <= 0"); @@ -321,6 +332,7 @@ void VPattern::UpdateToolData(const quint32 &id, VContainer *data) tool->VDataTool::setData(data); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::IncrementReferens(quint32 id) const { Q_ASSERT_X(id > 0, Q_FUNC_INFO, "id <= 0"); @@ -329,6 +341,7 @@ void VPattern::IncrementReferens(quint32 id) const tool->incrementReferens(); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::DecrementReferens(quint32 id) const { Q_ASSERT_X(id > 0, Q_FUNC_INFO, "id <= 0"); @@ -337,12 +350,14 @@ void VPattern::DecrementReferens(quint32 id) const tool->decrementReferens(); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::TestUniqueId() const { QVector vector; CollectId(documentElement(), vector); } +//--------------------------------------------------------------------------------------------------------------------- quint32 VPattern::SPointActiveDraw() { QDomElement calcElement; @@ -365,6 +380,7 @@ quint32 VPattern::SPointActiveDraw() return 0; } +//--------------------------------------------------------------------------------------------------------------------- bool VPattern::CheckNameDraw(const QString &name) const { Q_ASSERT_X(name.isEmpty() == false, "CheckNameDraw", "name draw is empty"); @@ -387,12 +403,14 @@ bool VPattern::CheckNameDraw(const QString &name) const return false; } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::SetActivDraw(const QString &name) { Q_ASSERT_X(name.isEmpty() == false, "SetActivDraw", "name draw is empty"); this->nameActivDraw = name; } +//--------------------------------------------------------------------------------------------------------------------- bool VPattern::GetActivNodeElement(const QString &name, QDomElement &element) { Q_ASSERT_X(name.isEmpty() == false, "GetActivNodeElement", "name draw is empty"); @@ -417,6 +435,7 @@ bool VPattern::GetActivNodeElement(const QString &name, QDomElement &element) return false; } +//--------------------------------------------------------------------------------------------------------------------- QString VPattern::MPath() const { QDomNodeList list = elementsByTagName(TagMeasurements); @@ -431,6 +450,7 @@ QString VPattern::MPath() const } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::SetPath(const QString &path) { if (path.isEmpty()) @@ -451,6 +471,7 @@ void VPattern::SetPath(const QString &path) } } +//--------------------------------------------------------------------------------------------------------------------- Valentina::Units VPattern::MUnit() const { QDomNodeList list = elementsByTagName(VPattern::TagMeasurements); @@ -482,6 +503,7 @@ Valentina::Units VPattern::MUnit() const } } +//--------------------------------------------------------------------------------------------------------------------- Pattern::Measurements VPattern::MType() const { QDomNodeList list = elementsByTagName(VPattern::TagMeasurements); @@ -510,6 +532,7 @@ Pattern::Measurements VPattern::MType() const } } +//--------------------------------------------------------------------------------------------------------------------- bool VPattern::SaveDocument(const QString &fileName) { try @@ -524,6 +547,7 @@ bool VPattern::SaveDocument(const QString &fileName) return VDomDocument::SaveDocument(fileName); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::FullUpdateTree() { VMainGraphicsScene *scene = new VMainGraphicsScene(); @@ -555,17 +579,20 @@ void VPattern::FullUpdateTree() emit FullUpdateFromFile(); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::haveLiteChange() { patternModified = true; emit patternChanged(); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ShowHistoryTool(quint32 id, Qt::GlobalColor color, bool enable) { emit ShowTool(id, color, enable); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseDrawElement(VMainGraphicsScene *sceneDraw, VMainGraphicsScene *sceneDetail, const QDomNode &node, const Document::Documents &parse) { @@ -601,6 +628,7 @@ void VPattern::ParseDrawElement(VMainGraphicsScene *sceneDraw, VMainGraphicsScen } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseDrawMode(VMainGraphicsScene *sceneDraw, VMainGraphicsScene *sceneDetail, const QDomNode &node, const Document::Documents &parse, const Valentina::Draws &mode) { @@ -649,6 +677,7 @@ void VPattern::ParseDrawMode(VMainGraphicsScene *sceneDraw, VMainGraphicsScene * } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseDetailElement(VMainGraphicsScene *sceneDetail, const QDomElement &domElement, const Document::Documents &parse) { @@ -716,6 +745,7 @@ void VPattern::ParseDetailElement(VMainGraphicsScene *sceneDetail, const QDomEle } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseDetails(VMainGraphicsScene *sceneDetail, const QDomElement &domElement, const Document::Documents &parse) { @@ -739,6 +769,7 @@ void VPattern::ParseDetails(VMainGraphicsScene *sceneDetail, const QDomElement & } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParsePointElement(VMainGraphicsScene *scene, const QDomElement &domElement, const Document::Documents &parse, const QString &type) { @@ -1104,6 +1135,7 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, const QDomElement &d } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseLineElement(VMainGraphicsScene *scene, const QDomElement &domElement, const Document::Documents &parse) { @@ -1127,6 +1159,7 @@ void VPattern::ParseLineElement(VMainGraphicsScene *scene, const QDomElement &do } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseSplineElement(VMainGraphicsScene *scene, const QDomElement &domElement, const Document::Documents &parse, const QString &type) { @@ -1248,6 +1281,7 @@ void VPattern::ParseSplineElement(VMainGraphicsScene *scene, const QDomElement & } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseArcElement(VMainGraphicsScene *scene, const QDomElement &domElement, const Document::Documents &parse, const QString &type) { @@ -1303,6 +1337,7 @@ void VPattern::ParseArcElement(VMainGraphicsScene *scene, const QDomElement &dom } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseToolsElement(VMainGraphicsScene *scene, const QDomElement &domElement, const Document::Documents &parse, const QString &type) { @@ -1340,6 +1375,7 @@ void VPattern::ParseToolsElement(VMainGraphicsScene *scene, const QDomElement &d } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::ParseIncrementsElement(const QDomNode &node) { QDomNode domNode = node.firstChild(); @@ -1367,6 +1403,7 @@ void VPattern::ParseIncrementsElement(const QDomNode &node) } } +//--------------------------------------------------------------------------------------------------------------------- quint32 VPattern::GetParametrId(const QDomElement &domElement) const { Q_ASSERT_X(domElement.isNull() == false, Q_FUNC_INFO, "domElement is null"); @@ -1391,6 +1428,7 @@ quint32 VPattern::GetParametrId(const QDomElement &domElement) const return id; } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::CollectId(const QDomElement &node, QVector &vector) const { if (node.hasAttribute(VDomDocument::AttrId)) @@ -1413,6 +1451,7 @@ void VPattern::CollectId(const QDomElement &node, QVector &vector) cons } } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::PrepareForParse(const Document::Documents &parse, VMainGraphicsScene *sceneDraw, VMainGraphicsScene *sceneDetail) { @@ -1438,6 +1477,7 @@ void VPattern::PrepareForParse(const Document::Documents &parse, VMainGraphicsSc history.clear(); } +//--------------------------------------------------------------------------------------------------------------------- void VPattern::UpdateMeasurements() { const QString path = MPath(); diff --git a/src/app/xml/vstandardmeasurements.cpp b/src/app/xml/vstandardmeasurements.cpp index 354b6c1a6..334f15395 100644 --- a/src/app/xml/vstandardmeasurements.cpp +++ b/src/app/xml/vstandardmeasurements.cpp @@ -40,16 +40,18 @@ const QString VStandardMeasurements::AttrSize_increace = QStringLiteral("size_ const QString VStandardMeasurements::AttrHeight_increase = QStringLiteral("height_increase"); const QString VStandardMeasurements::AttrNumber = QStringLiteral("number"); +//--------------------------------------------------------------------------------------------------------------------- VStandardMeasurements::VStandardMeasurements(VContainer *data):VDomDocument(data) -{ -} +{} +//--------------------------------------------------------------------------------------------------------------------- Valentina::Units VStandardMeasurements::Unit() { const QString unit = UniqueTagText(AttrUnit, UnitCM); return VDomDocument::StrToUnits(unit); } +//--------------------------------------------------------------------------------------------------------------------- QString VStandardMeasurements::Description() { const QString desc = UniqueTagText(TagDescription, ""); @@ -60,6 +62,7 @@ QString VStandardMeasurements::Description() return desc; } +//--------------------------------------------------------------------------------------------------------------------- void VStandardMeasurements::Measurements() { const QDomNodeList nodeList = this->elementsByTagName(TagMeasurement); @@ -105,6 +108,7 @@ void VStandardMeasurements::Measurements() } } +//--------------------------------------------------------------------------------------------------------------------- void VStandardMeasurements::SetSize() { const QDomNodeList nodeList = this->elementsByTagName(TagSize); @@ -138,6 +142,7 @@ void VStandardMeasurements::SetSize() } } +//--------------------------------------------------------------------------------------------------------------------- void VStandardMeasurements::SetHeight() { const QDomNodeList nodeList = this->elementsByTagName(TagHeight); diff --git a/src/app/xml/vtoolrecord.cpp b/src/app/xml/vtoolrecord.cpp index 6f5875037..4ea39a243 100644 --- a/src/app/xml/vtoolrecord.cpp +++ b/src/app/xml/vtoolrecord.cpp @@ -28,8 +28,12 @@ #include "vtoolrecord.h" +//--------------------------------------------------------------------------------------------------------------------- VToolRecord::VToolRecord() - :id(0), typeTool(Valentina::ArrowTool), nameDraw(QString()){} + :id(0), typeTool(Valentina::ArrowTool), nameDraw(QString()) +{} +//--------------------------------------------------------------------------------------------------------------------- VToolRecord::VToolRecord(const quint32 &id, const Valentina::Tools &typeTool, const QString &nameDraw) - :id(id), typeTool(typeTool), nameDraw(nameDraw){} + :id(id), typeTool(typeTool), nameDraw(nameDraw) +{} From 60ba211f2ade1c84c9900291397d7dbcbd30224e Mon Sep 17 00:00:00 2001 From: dismine Date: Mon, 5 May 2014 10:29:14 +0300 Subject: [PATCH 21/26] Porting new change from muparser. --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.h | 7 +- src/libs/qmuparser/qmuparserdef.h | 4 +- src/libs/qmuparser/qmuparsererror.cpp | 71 ++++++++++----------- src/libs/qmuparser/qmuparsererror.h | 12 ++-- src/libs/qmuparser/qmuparsertest.cpp | 11 +++- src/libs/qmuparser/qmuparsertokenreader.cpp | 15 +++-- 6 files changed, 64 insertions(+), 56 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index b85aa8813..a70adb5d8 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -160,7 +160,12 @@ protected: virtual std::string do_grouping() const { - return std::string(1, m_nGroup); + // fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4 + // courtesy of Jens Bartsch + // original code: + // return std::string(1, (char)m_nGroup); + // new code: + return std::string(1, static_cast(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX)); } private: int m_nGroup; diff --git a/src/libs/qmuparser/qmuparserdef.h b/src/libs/qmuparser/qmuparserdef.h index 6f4b2aa0d..a15557d9c 100644 --- a/src/libs/qmuparser/qmuparserdef.h +++ b/src/libs/qmuparser/qmuparserdef.h @@ -32,8 +32,8 @@ @brief This file contains standard definitions used by the parser. */ -#define QMUP_VERSION "2.2.3" -#define QMUP_VERSION_DATE "20121222; SF" +#define QMUP_VERSION "2.2.4" +#define QMUP_VERSION_DATE "20140504; GC" #define QMUP_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 9fd28bb5c..6d01c8b39 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -109,10 +109,9 @@ QmuParserErrorMsg::QmuParserErrorMsg() * @brief Default constructor. */ QmuParserError::QmuParserError() - : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + : m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) -{ -} +{} //--------------------------------------------------------------------------------------------------------------------- /** @@ -121,12 +120,12 @@ QmuParserError::QmuParserError() * It does not contain any information but the error code. */ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) - : m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), + : m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - m_strMsg = m_ErrMsg[m_iErrc]; - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + m_sMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_sMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_sMsg, "$TOK$", m_sTok ); } //--------------------------------------------------------------------------------------------------------------------- @@ -134,7 +133,7 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) * @brief Construct an error from a message text. */ QmuParserError::QmuParserError ( const QString &sMsg ) - : m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + : m_sMsg(sMsg), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -146,16 +145,13 @@ QmuParserError::QmuParserError ( const QString &sMsg ) * @param [in] sExpr The expression related to the error. * @param [in] a_iPos the position in the expression where the error occured. */ -QmuParserError::QmuParserError ( EErrorCodes iErrc, - const QString &sTok, - const QString &sExpr, - int iPos ) - : m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), +QmuParserError::QmuParserError ( EErrorCodes iErrc, const QString &sTok, const QString &sExpr, int iPos ) + : m_sMsg(), m_sExpr ( sExpr ), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - m_strMsg = m_ErrMsg[m_iErrc]; - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + m_sMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_sMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_sMsg, "$TOK$", m_sTok ); } //--------------------------------------------------------------------------------------------------------------------- @@ -165,13 +161,13 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc, * @param [in] iPos the position in the expression where the error occured. * @param [in] sTok The token string related to this error. */ -QmuParserError::QmuParserError ( EErrorCodes iErrc, int iPos, const QString &sTok ) - : m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), +QmuParserError::QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok ) + : m_sMsg(), m_sExpr(), m_sTok ( sTok ), m_iPos ( a_iPos ), m_iErrc ( a_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - m_strMsg = m_ErrMsg[m_iErrc]; - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + m_sMsg = m_ErrMsg[m_iErrc]; + ReplaceSubString ( m_sMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_sMsg, "$TOK$", m_sTok ); } //--------------------------------------------------------------------------------------------------------------------- @@ -181,20 +177,19 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc, int iPos, const QString &sTo * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok ) - : m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), + : m_sMsg ( szMsg ), m_sExpr(), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { - ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) ); - ReplaceSubString ( m_strMsg, "$TOK$", m_strTok ); + ReplaceSubString ( m_sMsg, "$POS$", QString().setNum ( m_iPos ) ); + ReplaceSubString ( m_sMsg, "$TOK$", m_sTok ); } //--------------------------------------------------------------------------------------------------------------------- /** @brief Copy constructor. */ QmuParserError::QmuParserError ( const QmuParserError &a_Obj ) - : m_strMsg ( a_Obj.m_strMsg ), m_strFormula ( a_Obj.m_strFormula ), m_strTok ( a_Obj.m_strTok ), + : m_sMsg ( a_Obj.m_sMsg ), m_sExpr ( a_Obj.m_sExpr ), m_sTok ( a_Obj.m_sTok ), m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) -{ -} +{} //--------------------------------------------------------------------------------------------------------------------- /** @brief Assignment operator. */ @@ -205,9 +200,9 @@ QmuParserError& QmuParserError::operator= ( const QmuParserError &a_Obj ) return *this; } - m_strMsg = a_Obj.m_strMsg; - m_strFormula = a_Obj.m_strFormula; - m_strTok = a_Obj.m_strTok; + m_sMsg = a_Obj.m_sMsg; + m_sExpr = a_Obj.m_sExpr; + m_sTok = a_Obj.m_sTok; m_iPos = a_Obj.m_iPos; m_iErrc = a_Obj.m_iErrc; return *this; @@ -252,9 +247,9 @@ void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFi // cppcheck-suppress unusedFunction void QmuParserError::Reset() { - m_strMsg.clear(); - m_strFormula.clear(); - m_strTok.clear(); + m_sMsg.clear(); + m_sExpr.clear(); + m_sTok.clear(); m_iPos = -1; m_iErrc = ecUNDEFINED; } @@ -265,7 +260,7 @@ void QmuParserError::Reset() */ void QmuParserError::SetFormula ( const QString &a_strFormula ) { - m_strFormula = a_strFormula; + m_sExpr = a_strFormula; } //--------------------------------------------------------------------------------------------------------------------- @@ -274,7 +269,7 @@ void QmuParserError::SetFormula ( const QString &a_strFormula ) */ const QString& QmuParserError::GetExpr() const { - return m_strFormula; + return m_sExpr; } //--------------------------------------------------------------------------------------------------------------------- @@ -283,7 +278,7 @@ const QString& QmuParserError::GetExpr() const */ const QString& QmuParserError::GetMsg() const { - return m_strMsg; + return m_sMsg; } //--------------------------------------------------------------------------------------------------------------------- @@ -292,7 +287,7 @@ const QString& QmuParserError::GetMsg() const * * If the error is not related to a distinct position this will return -1 */ -std::size_t QmuParserError::GetPos() const +int QmuParserError::GetPos() const { return m_iPos; } @@ -303,7 +298,7 @@ std::size_t QmuParserError::GetPos() const */ const QString& QmuParserError::GetToken() const { - return m_strTok; + return m_sTok; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index 2a86e2829..dd450602f 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -134,16 +134,16 @@ public: void SetFormula ( const QString &a_strFormula ); const QString& GetExpr() const; const QString& GetMsg() const; - std::size_t GetPos() const; + int GetPos() const; const QString& GetToken() const; EErrorCodes GetCode() const; private: - QString m_strMsg; ///< The message string - QString m_strFormula; ///< Formula string - QString m_strTok; ///< Token related with the error - int m_iPos; ///< Formula position related to the error - EErrorCodes m_iErrc; ///< Error code + QString m_sMsg; ///< The message string + QString m_sExpr; ///< Formula string + QString m_sTok; ///< Token related with the error + int m_iPos; ///< Formula position related to the error + EErrorCodes m_iErrc; ///< Error code const QmuParserErrorMsg &m_ErrMsg; /** * @brief Replace all ocuurences of a substring with another string. diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index cd9644cde..9bdd8bad4 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -1352,9 +1352,16 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass // The tests equations never result in infinity, if they do thats a bug. // reference: // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825 - if ( numeric_limits::has_infinity ) +#if defined(Q_CC_MSVC) +#pragma warning(push) +#pragma warning(disable:4127) +#endif + if (std::numeric_limits::has_infinity) +#if defined(Q_CC_MSVC) +#pragma warning(pop) +#endif { - bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), numeric_limits::infinity())==false ); + bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), std::numeric_limits::infinity())==false ); } } diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 8dcafb9cc..6944656b9 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -643,7 +643,7 @@ bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok ) } // iteraterate over all postfix operator strings - funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin(); + auto it = m_pInfixOprtDef->rbegin(); for ( ; it != m_pInfixOprtDef->rend(); ++it ) { if ( sTok.indexOf ( it->first ) != 0 ) @@ -752,7 +752,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) // are part of long token names (like: "add123") will be found instead // of the long ones. // Length sorting is done with ascending length so we use a reverse iterator here. - funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin(); + auto it = m_pOprtDef->rbegin(); for ( ; it != m_pOprtDef->rend(); ++it ) { const QString &sID = it->first; @@ -781,7 +781,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) } m_iPos += sID.length(); - m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN; + m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noASSIGN; return true; } } @@ -825,7 +825,7 @@ bool QmuParserTokenReader::IsPostOpTok ( token_type &a_Tok ) } // iteraterate over all postfix operator strings - funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin(); + auto it = m_pPostOprtDef->rbegin(); for ( ; it != m_pPostOprtDef->rend(); ++it ) { if ( sTok.indexOf ( it->first ) != 0 ) @@ -890,7 +890,8 @@ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) int iStart = m_iPos; if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 ) { - strTok = m_strFormula.mid ( iStart, m_iPos ); + // 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2 + strTok = m_strFormula.mid ( iStart, m_iPos-iStart ); if ( m_iSynFlags & noVAL ) { Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); @@ -913,7 +914,7 @@ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) */ bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok ) { - if ( m_pVarDef->size() == false) + if ( m_pVarDef->empty()) { return false; } @@ -952,7 +953,7 @@ bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok ) //--------------------------------------------------------------------------------------------------------------------- bool QmuParserTokenReader::IsStrVarTok ( token_type &a_Tok ) { - if ( m_pStrVarDef == false || m_pStrVarDef->size() == false) + if ( m_pStrVarDef == false || m_pStrVarDef->empty() ) { return false; } From d65368bafb68cff90c80a23b7743192ed7050424 Mon Sep 17 00:00:00 2001 From: dismine Date: Tue, 6 May 2014 12:45:21 +0300 Subject: [PATCH 22/26] Tests passed. --HG-- branch : feature --- src/app/app.pro | 2 +- src/app/exception/vexception.h | 26 +-- src/app/main.cpp | 5 +- src/libs/qmuparser/qmuparser.cpp | 8 +- src/libs/qmuparser/qmuparser.pro | 4 +- src/libs/qmuparser/qmuparserbase.cpp | 23 +-- src/libs/qmuparser/qmuparserbase.h | 12 +- src/libs/qmuparser/qmuparserbytecode.cpp | 31 +--- src/libs/qmuparser/qmuparsererror.cpp | 19 +-- src/libs/qmuparser/qmuparsererror.h | 30 +++- src/libs/qmuparser/qmuparsertest.cpp | 105 ++++++------ src/libs/qmuparser/qmuparsertest.h | 12 +- src/libs/qmuparser/qmuparsertoken.h | 80 +-------- src/libs/qmuparser/qmuparsertokenreader.cpp | 47 +++--- src/libs/qmuparser/qmuparsertokenreader.h | 175 +++++++++----------- 15 files changed, 243 insertions(+), 336 deletions(-) diff --git a/src/app/app.pro b/src/app/app.pro index 797def619..5ac95217c 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -102,7 +102,7 @@ CONFIG(debug, debug|release){ -Wmissing-include-dirs -Wpacked -Wredundant-decls -Winline \ -Wswitch-default -Wswitch-enum -Wuninitialized -Wvariadic-macros \ -Wlogical-op -Wnoexcept -Wmissing-noreturn -Wpointer-arith\ - -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 + -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -gdwarf-3 \ -ftrapv } } else { diff --git a/src/app/exception/vexception.h b/src/app/exception/vexception.h index 9771bb004..32a57f035 100644 --- a/src/app/exception/vexception.h +++ b/src/app/exception/vexception.h @@ -42,26 +42,26 @@ class VException : public QException { Q_DECLARE_TR_FUNCTIONS(VException) public: - /** - * @brief VException constructor exception - * @param what string with error - */ - VException(const QString &what); - /** - * @brief VException copy constructor - * @param e exception - */ - VException(const VException &e); - virtual ~VException() noexcept (true){} + /** + * @brief VException constructor exception + * @param what string with error + */ + VException(const QString &what); + /** + * @brief VException copy constructor + * @param e exception + */ + VException(const VException &e); + virtual ~VException() noexcept (true){} /** * @brief raise method raise for exception */ - void raise() const; + virtual void raise() const; /** * @brief clone clone exception * @return new exception */ - VException *clone() const; + virtual VException *clone() const; /** * @brief ErrorMessage return main error message * @return error message diff --git a/src/app/main.cpp b/src/app/main.cpp index b5facc0d5..299b22f91 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -74,8 +74,9 @@ void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, c switch (type) { case QtDebugMsg: - fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, - context.function); + fprintf(stderr, "Debug: %s\n", localMsg.constData()); +// fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, +// context.function); return; case QtWarningMsg: messageBox.setIcon(QMessageBox::Warning); diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 96fc7b9c7..9c64c5e38 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -131,7 +131,7 @@ qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc) { if (a_iArgc == false) { - throw exception_type("too few arguments for function sum."); + throw QmuParserError("too few arguments for function sum."); } qreal fRes=0; for (int i=0; i #endif +#include "qmuparsererror.h" +#include "qmuparsertokenreader.h" + using namespace std; /** @@ -438,19 +441,19 @@ void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a Q_UNREACHABLE(); break; case cmVARPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW3: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW4: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARMUL: - Q_UNREACHABLE(); + // For optimization purposes break; case cmPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmFUNC: Q_UNREACHABLE(); @@ -937,7 +940,7 @@ const varmap_type& QmuParserBase::GetUsedVar() const m_pParseFormula = &QmuParserBase::ParseString; m_pTokenReader->IgnoreUndefVar(false); } - catch (const exception_type &e) + catch (const QmuParserError &e) { // Make sure to stay in string parse mode, dont call ReInit() // because it deletes the array with the used variables @@ -995,7 +998,7 @@ const QString& QmuParserBase::GetExpr() const /** * @brief Execute a function that takes a single string argument. * @param a_FunTok Function token. - * @throw exception_type If the function token is not a string function + * @throw QmuParserError If the function token is not a string function */ QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok, const QVector &a_vArg) const @@ -1052,7 +1055,7 @@ QmuParserBase::token_type QmuParserBase::ApplyStrFunc(const token_type &a_FunTok * @param iArgCount Number of Arguments actually gathered used only for multiarg functions. * @post The result is pushed to the value stack * @post The function token is removed from the stack - * @throw exception_type if Argument count does not mach function requirements. + * @throw QmuParserError if Argument count does not mach function requirements. */ void QmuParserBase::ApplyFunc( QStack &a_stOpt, QStack &a_stVal, int a_iArgCount) const { @@ -2051,7 +2054,7 @@ qreal QmuParserBase::ParseString() const m_pParseFormula = &QmuParserBase::ParseCmdCode; return (this->*m_pParseFormula)(); } - catch (QmuParserError &exc) + catch (qmu::QmuParserError &exc) { exc.SetFormula(m_pTokenReader->GetExpr()); throw; @@ -2071,7 +2074,7 @@ qreal QmuParserBase::ParseString() const */ void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const { - throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); + throw qmu::QmuParserError (a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index a70adb5d8..62171abad 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -23,6 +23,7 @@ #ifndef QMUQPARSERBASE_H #define QMUQPARSERBASE_H +#include "qmuparser_global.h" #include #include #include @@ -51,17 +52,10 @@ namespace qmu * Complementary to a set of internally implemented functions the parser is able to handle * user defined functions and variables. */ -class QmuParserBase +class QMUPARSERSHARED_EXPORT QmuParserBase { friend class QmuParserTokenReader; public: - /** - * @brief Type of the error class. - * - * Included for backwards compatibility. - */ - typedef QmuParserError exception_type; - QmuParserBase(); QmuParserBase(const QmuParserBase &a_Parser); QmuParserBase& operator=(const QmuParserBase &a_Parser) Q_DECL_NOEXCEPT; @@ -112,7 +106,7 @@ public: const QString& ValidInfixOprtChars() const; void SetArgSep(char_type cArgSep); QChar GetArgSep() const; - void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; + void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const; /** * @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, * bool a_bAllowOpt = true) diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index 696163501..aa2a9e7be 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -430,10 +430,8 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) } break; case cmLE: - Q_UNREACHABLE(); break; case cmGE: - Q_UNREACHABLE(); break; case cmNEQ: Q_UNREACHABLE(); @@ -442,13 +440,10 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) Q_UNREACHABLE(); break; case cmLT: - Q_UNREACHABLE(); break; case cmGT: - Q_UNREACHABLE(); break; case cmLAND: - Q_UNREACHABLE(); break; case cmLOR: Q_UNREACHABLE(); @@ -670,10 +665,8 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT m_vRPN[idx].Oprt.offset = i - idx; break; case cmLE: - Q_UNREACHABLE(); break; case cmGE: - Q_UNREACHABLE(); break; case cmNEQ: Q_UNREACHABLE(); @@ -682,34 +675,25 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT Q_UNREACHABLE(); break; case cmLT: - Q_UNREACHABLE(); break; case cmGT: - Q_UNREACHABLE(); break; case cmADD: - Q_UNREACHABLE(); break; case cmSUB: - Q_UNREACHABLE(); break; case cmMUL: - Q_UNREACHABLE(); break; case cmDIV: - Q_UNREACHABLE(); break; case cmPOW: - Q_UNREACHABLE(); break; case cmLAND: - Q_UNREACHABLE(); break; case cmLOR: Q_UNREACHABLE(); break; case cmASSIGN: - Q_UNREACHABLE(); break; case cmBO: Q_UNREACHABLE(); @@ -721,31 +705,27 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT Q_UNREACHABLE(); break; case cmVAR: - Q_UNREACHABLE(); break; case cmVAL: - Q_UNREACHABLE(); break; case cmVARPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW3: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARPOW4: - Q_UNREACHABLE(); + // For optimization purposes break; case cmVARMUL: - Q_UNREACHABLE(); + // For optimization purposes break; case cmPOW2: - Q_UNREACHABLE(); + // For optimization purposes break; case cmFUNC: - Q_UNREACHABLE(); break; case cmFUNC_STR: - Q_UNREACHABLE(); break; case cmFUNC_BULK: Q_UNREACHABLE(); @@ -763,7 +743,6 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT Q_UNREACHABLE(); break; case cmEND: - Q_UNREACHABLE(); break; case cmUNKNOWN: Q_UNREACHABLE(); diff --git a/src/libs/qmuparser/qmuparsererror.cpp b/src/libs/qmuparser/qmuparsererror.cpp index 6d01c8b39..0bdc28e81 100644 --- a/src/libs/qmuparser/qmuparsererror.cpp +++ b/src/libs/qmuparser/qmuparsererror.cpp @@ -109,7 +109,7 @@ QmuParserErrorMsg::QmuParserErrorMsg() * @brief Default constructor. */ QmuParserError::QmuParserError() - : m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + : QException(), m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -120,7 +120,7 @@ QmuParserError::QmuParserError() * It does not contain any information but the error code. */ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) - : m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), + : QException(), m_sMsg(), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { m_sMsg = m_ErrMsg[m_iErrc]; @@ -133,7 +133,7 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc ) * @brief Construct an error from a message text. */ QmuParserError::QmuParserError ( const QString &sMsg ) - : m_sMsg(sMsg), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), + : QException(), m_sMsg(sMsg), m_sExpr(), m_sTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -146,7 +146,7 @@ QmuParserError::QmuParserError ( const QString &sMsg ) * @param [in] a_iPos the position in the expression where the error occured. */ QmuParserError::QmuParserError ( EErrorCodes iErrc, const QString &sTok, const QString &sExpr, int iPos ) - : m_sMsg(), m_sExpr ( sExpr ), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), + : QException(), m_sMsg(), m_sExpr ( sExpr ), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { m_sMsg = m_ErrMsg[m_iErrc]; @@ -162,7 +162,7 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc, const QString &sTok, const Q * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok ) - : m_sMsg(), m_sExpr(), m_sTok ( sTok ), m_iPos ( a_iPos ), m_iErrc ( a_iErrc ), + : QException(), m_sMsg(), m_sExpr(), m_sTok ( sTok ), m_iPos ( a_iPos ), m_iErrc ( a_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { m_sMsg = m_ErrMsg[m_iErrc]; @@ -177,7 +177,7 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString * @param [in] sTok The token string related to this error. */ QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok ) - : m_sMsg ( szMsg ), m_sExpr(), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), + : QException(), m_sMsg ( szMsg ), m_sExpr(), m_sTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) { ReplaceSubString ( m_sMsg, "$POS$", QString().setNum ( m_iPos ) ); @@ -187,7 +187,7 @@ QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString & //--------------------------------------------------------------------------------------------------------------------- /** @brief Copy constructor. */ QmuParserError::QmuParserError ( const QmuParserError &a_Obj ) - : m_sMsg ( a_Obj.m_sMsg ), m_sExpr ( a_Obj.m_sExpr ), m_sTok ( a_Obj.m_sTok ), + : QException(), m_sMsg ( a_Obj.m_sMsg ), m_sExpr ( a_Obj.m_sExpr ), m_sTok ( a_Obj.m_sTok ), m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() ) {} @@ -208,10 +208,6 @@ QmuParserError& QmuParserError::operator= ( const QmuParserError &a_Obj ) return *this; } -//--------------------------------------------------------------------------------------------------------------------- -QmuParserError::~QmuParserError() -{} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief Replace all ocuurences of a substring with another string. @@ -309,4 +305,5 @@ EErrorCodes QmuParserError::GetCode() const { return m_iErrc; } + } // namespace qmu diff --git a/src/libs/qmuparser/qmuparsererror.h b/src/libs/qmuparser/qmuparsererror.h index dd450602f..249c654db 100644 --- a/src/libs/qmuparser/qmuparsererror.h +++ b/src/libs/qmuparser/qmuparsererror.h @@ -23,11 +23,9 @@ #ifndef QMUPARSERERROR_H #define QMUPARSERERROR_H -#include -#include -#include +#include "qmuparser_global.h" #include -#include +#include #include "qmuparserdef.h" @@ -117,10 +115,9 @@ private: Part of the math parser package. */ -class QmuParserError +class QMUPARSERSHARED_EXPORT QmuParserError : public QException { public: - QmuParserError(); explicit QmuParserError ( EErrorCodes a_iErrc ); explicit QmuParserError ( const QString &sMsg ); @@ -129,7 +126,7 @@ public: QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() ); QmuParserError ( const QmuParserError &a_Obj ); QmuParserError& operator= ( const QmuParserError &a_Obj ); - ~QmuParserError(); + virtual ~QmuParserError() noexcept (true){} void SetFormula ( const QString &a_strFormula ); const QString& GetExpr() const; @@ -138,6 +135,15 @@ public: const QString& GetToken() const; EErrorCodes GetCode() const; + /** + * @brief raise method raise for exception + */ + virtual void raise() const; + /** + * @brief clone clone exception + * @return new exception + */ + virtual QmuParserError *clone() const; private: QString m_sMsg; ///< The message string QString m_sExpr; ///< Formula string @@ -152,6 +158,16 @@ private: void Reset(); }; +inline void QmuParserError::raise() const +{ + throw *this; +} + +inline QmuParserError *QmuParserError::clone() const +{ + return new QmuParserError(*this); +} + } // namespace qmu #endif diff --git a/src/libs/qmuparser/qmuparsertest.cpp b/src/libs/qmuparser/qmuparsertest.cpp index 9bdd8bad4..cce7cdfc2 100644 --- a/src/libs/qmuparser/qmuparsertest.cpp +++ b/src/libs/qmuparser/qmuparsertest.cpp @@ -23,10 +23,8 @@ #include "qmuparsertest.h" #include #include - -#include -#include -#include +#include +#include "qmuparsererror.h" using namespace std; @@ -64,32 +62,33 @@ QmuParserTester::QmuParserTester() //--------------------------------------------------------------------------------------------------------------------- int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal ) { - if ( a_szExpr[1] == 0 || ( a_szExpr[0] != '0' || a_szExpr[1] != 'x' ) ) + if ( a_szExpr.data()[1] == 0 || ( a_szExpr.data()[0] != '0' || a_szExpr.data()[1] != 'x' ) ) { return 0; } unsigned iVal ( 0 ); - bool ok = false; - iVal = a_szExpr.toUInt ( &ok, 16 ); - if ( ok ) +#if defined(_UNICODE) + std::wstring a_szExprStd = a_szExpr.mid(2).toStdWString(); +#else + std::string a_szExprStd = a_szExpr.mid(2).toStdString(); +#endif + + // New code based on streams for UNICODE compliance: + stringstream_type::pos_type nPos(0); + stringstream_type ss(a_szExprStd); + ss >> std::hex >> iVal; + nPos = ss.tellg(); + + if (nPos==static_cast(0)) { - int nPos = a_szExpr.indexOf ( QString().setNum ( iVal, 16 ) ); - if ( nPos == 0 ) - { - return 1; - } - - *a_iPos += 2 + nPos; - *a_fVal = static_cast(iVal); return 1; } - else - { - return 0; - } + *a_iPos += static_cast(2 + nPos); + *a_fVal = static_cast(iVal); + return 1; } //--------------------------------------------------------------------------------------------------------------------- @@ -128,11 +127,11 @@ int QmuParserTester::TestInterface() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestInterface passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestInterface failed with " << iStat << " errors"; } return iStat; @@ -157,11 +156,11 @@ int QmuParserTester::TestStrArg() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestStrArg passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestStrArg failed with " << iStat << " errors"; } return iStat; @@ -232,11 +231,11 @@ int QmuParserTester::TestBinOprt() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestBinOprt passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestBinOprt failed with " << iStat << " errors"; } return iStat; @@ -260,7 +259,7 @@ int QmuParserTester::TestNames() { \ p.Define##DOMAIN(EXPR, ARG); \ } \ - catch (QmuParser::exception_type&) \ + catch (QmuParserError &) \ { \ iErr = (FAIL==false) ? 0 : 1; \ } \ @@ -345,11 +344,11 @@ int QmuParserTester::TestNames() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestNames passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestNames failed with " << iStat << " errors"; } return iStat; @@ -398,11 +397,11 @@ int QmuParserTester::TestSyntax() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestSyntax passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestSyntax failed with " << iStat << " errors"; } return iStat; @@ -531,11 +530,11 @@ int QmuParserTester::TestVarConst() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestVarConst passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestVarConst failed with " << iStat << " errors"; } return iStat; @@ -629,11 +628,11 @@ int QmuParserTester::TestMultiArg() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestMultiArg passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestMultiArg failed with " << iStat << " errors"; } return iStat; @@ -698,11 +697,11 @@ int QmuParserTester::TestInfixOprt() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestInfixOprt passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestInfixOprt failed with " << iStat << " errors"; } return iStat; @@ -754,11 +753,11 @@ int QmuParserTester::TestPostFix() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestPostFix passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestPostFix failed with " << iStat << " errors"; } return iStat; @@ -792,6 +791,8 @@ int QmuParserTester::TestExpression() iStat += EqnTest ( "(2*b+1)*4", ( 2 * b + 1 ) * 4, true ); iStat += EqnTest ( "4*(2*b+1)", ( 2 * b + 1 ) * 4, true ); + // 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2 + iStat += EqnTest ( "1+2+3", 6, true ); // operator precedencs iStat += EqnTest ( "1+2-3*4/5^6", 2.99923, true ); @@ -839,11 +840,11 @@ int QmuParserTester::TestExpression() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestExpression passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestExpression failed with " << iStat << " errors"; } return iStat; @@ -949,11 +950,11 @@ int QmuParserTester::TestIfThenElse() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestIfThenElse passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestIfThenElse failed with " << iStat << " errors"; } return iStat; @@ -1047,11 +1048,11 @@ int QmuParserTester::TestException() if ( iStat == 0 ) { - qDebug() << "passed"; + qDebug() << "TestException passed"; } else { - qDebug() << "\n failed with " << iStat << " errors"; + qDebug() << "\n TestException failed with " << iStat << " errors"; } return iStat; @@ -1076,7 +1077,7 @@ void QmuParserTester::Run() iStat += ( this->*m_vTestFun[i] ) (); } } - catch ( QmuParser::exception_type &e ) + catch ( QmuParserError &e ) { qDebug() << "\n" << e.GetMsg(); qDebug() << e.GetToken(); @@ -1130,14 +1131,12 @@ int QmuParserTester::ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail p.SetExpr ( a_str ); p.Eval(); } - catch ( QmuParserError &e ) + catch ( const qmu::QmuParserError &e ) { // output the formula in case of an failed test if ( a_bFail == false || ( a_bFail == true && a_iErrc != e.GetCode() ) ) { - qDebug() << "\n " - << "Expression: " << a_str - << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" + qDebug() << "\n " << "Expression: " << a_str << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")" << " Expected:" << a_iErrc; } @@ -1194,7 +1193,7 @@ int QmuParserTester::EqnTestWithVarChange ( const QString &a_str, double a_fVar1 throw std::runtime_error ( "incorrect result (second pass)" ); } } - catch ( QmuParser::exception_type &e ) + catch ( QmuParserError &e ) { qDebug() << "\n fail: " << a_str << " (" << e.GetMsg() << ")"; return 1; @@ -1308,7 +1307,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass fVal[1] = p1->Eval(); // result from bytecode if ( qFuzzyCompare( fVal[0], fVal[1] ) == false ) { - throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." ); + throw QmuParserError ( "Bytecode / string parsing mismatch." ); } // Test copy and assignement operators @@ -1379,7 +1378,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass << fVal[4] << ")."; } } - catch ( QmuParser::exception_type &e ) + catch ( QmuParserError &e ) { if ( a_fPass ) { diff --git a/src/libs/qmuparser/qmuparsertest.h b/src/libs/qmuparser/qmuparsertest.h index ffa838ed8..0c02a88bb 100644 --- a/src/libs/qmuparser/qmuparsertest.h +++ b/src/libs/qmuparser/qmuparsertest.h @@ -23,9 +23,7 @@ #ifndef QMUPARSERTEST_H #define QMUPARSERTEST_H -#include -#include -#include // for accumulate +#include "qmuparser_global.h" #include "qmuparser.h" #include @@ -47,7 +45,7 @@ namespace Test * * (C) 2004-2011 Ingo Berg */ -class QmuParserTester // final +class QMUPARSERSHARED_EXPORT QmuParserTester // final { public: typedef int ( QmuParserTester::*testfun_type ) (); @@ -186,7 +184,7 @@ private: { if ( a_iArgc == false) { - throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." ); + throw QmuParserError ( "too few arguments for function FirstArg." ); } return a_afArg[0]; @@ -196,7 +194,7 @@ private: { if ( a_iArgc == false) { - throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." ); + throw QmuParserError ( "too few arguments for function LastArg." ); } return a_afArg[a_iArgc - 1]; @@ -206,7 +204,7 @@ private: { if ( a_iArgc == false) { - throw qmu::QmuParser::exception_type ( "too few arguments for function sum." ); + throw QmuParserError ( "too few arguments for function sum." ); } qreal fRes = 0; diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 92a2722c3..73db7485a 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -232,7 +232,7 @@ public: * * In cmSTRFUNC - This is the index to a string table in the main parser. * @param a_iIdx The index the string function result will take in the bytecode parser. - * @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING + * @throw QmuParserError if #a_iIdx<0 or #m_iType!=cmSTRING */ void SetIdx ( int a_iIdx ) { @@ -250,7 +250,7 @@ public: * * In cmSTRFUNC - This is the index to a string table in the main parser. * - * @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING + * @throw QmuParserError if #m_iIdx<0 or #m_iType!=cmSTRING * @return The index the result will take in the Bytecode calculatin array (#m_iIdx). */ int GetIdx() const @@ -327,7 +327,7 @@ public: * @brief Return the address of the callback function assoziated with function and operator tokens. * * @return The pointer stored in #m_pTok. - * @throw exception_type if token type is non of: + * @throw QmuParserError if token type is non of: *
      *
    • cmFUNC
    • *
    • cmSTRFUNC
    • @@ -348,7 +348,7 @@ public: * @brief Get value of the token. * * Only applicable to variable and value tokens. - * @throw exception_type if token is no value/variable token. + * @throw QmuParserError if token is no value/variable token. */ TBase GetVal() const { @@ -359,107 +359,39 @@ public: case cmVAR: return * ( reinterpret_cast(m_pTok) ); case cmLE: - Q_UNREACHABLE(); - break; case cmGE: - Q_UNREACHABLE(); - break; case cmNEQ: - Q_UNREACHABLE(); - break; case cmEQ: - Q_UNREACHABLE(); - break; case cmLT: - Q_UNREACHABLE(); - break; case cmGT: - Q_UNREACHABLE(); - break; case cmADD: - Q_UNREACHABLE(); - break; case cmSUB: - Q_UNREACHABLE(); - break; case cmMUL: - Q_UNREACHABLE(); - break; case cmDIV: - Q_UNREACHABLE(); - break; case cmPOW: - Q_UNREACHABLE(); - break; case cmLAND: - Q_UNREACHABLE(); - break; case cmLOR: - Q_UNREACHABLE(); - break; case cmASSIGN: - Q_UNREACHABLE(); - break; case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmIF: - Q_UNREACHABLE(); - break; case cmELSE: - Q_UNREACHABLE(); - break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmVARPOW2: - Q_UNREACHABLE(); - break; case cmVARPOW3: - Q_UNREACHABLE(); - break; case cmVARPOW4: - Q_UNREACHABLE(); - break; case cmVARMUL: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmFUNC: - Q_UNREACHABLE(); - break; case cmFUNC_STR: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; - case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; case cmEND: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; + case cmSTRING: default: throw QmuParserError ( ecVAL_EXPECTED ); } @@ -470,7 +402,7 @@ public: * @brief Get address of a variable token. * * Valid only if m_iType==CmdVar. - * @throw exception_type if token is no variable token. + * @throw QmuParserError if token is no variable token. */ TBase* GetVar() const { diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index 6944656b9..e16e6404f 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -254,15 +254,10 @@ QmuParserTokenReader::token_type QmuParserTokenReader::ReadNextToken() { assert ( m_pParser ); -#if defined(_UNICODE) - const char_type *szFormula = m_strFormula.toStdWString().c_str(); -#else - const char_type *szFormula = m_strFormula.toStdString().c_str(); -#endif token_type tok; // Ignore all non printable characters when reading the expression - while ( szFormula[m_iPos] > 0 && szFormula[m_iPos] <= 0x20 ) + while ( m_strFormula.data()[m_iPos] > 0 && m_strFormula.data()[m_iPos] <= 0x20 ) { ++m_iPos; } @@ -452,7 +447,7 @@ bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok ) for ( int i = 0; i < pOprtDef.size(); ++i ) { int len = pOprtDef.at ( i ).length(); - if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, m_iPos + len ) ) + if ( pOprtDef.at ( i ) == m_strFormula.mid ( m_iPos, len ) ) { switch ( i ) { @@ -596,23 +591,31 @@ bool QmuParserTokenReader::IsArgSep ( token_type &a_Tok ) * * @return true if an end of formula is found false otherwise. * @param a_Tok [out] If an eof is found the corresponding token will be stored there. - * @throw nothrow * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok */ -bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) Q_DECL_NOEXCEPT +bool QmuParserTokenReader::IsEOF ( token_type &a_Tok ) { -#if defined(_UNICODE) - const char_type* szFormula = m_strFormula.toStdWString().c_str(); -#else - const char_type* szFormula = m_strFormula.toStdString().c_str(); -#endif +//#if defined(_UNICODE) +// const char_type* szFormula = m_strFormula.toStdWString().c_str(); +//#else +// const char_type* szFormula = m_strFormula.toStdString().c_str(); +//#endif // check for EOF - if ( szFormula[m_iPos] == false /*|| szFormula[m_iPos] == '\n'*/ ) + if ( m_strFormula.data()[m_iPos] == false /*|| szFormula[m_iPos] == '\n'*/ ) { if ( m_iSynFlags & noEND ) { - Error ( ecUNEXPECTED_EOF, m_iPos ); + try + { + Error ( ecUNEXPECTED_EOF, m_iPos ); + } + catch (qmu::QmuParserError &e) + { + qDebug() << "\n " + << " Code:" << e.GetCode() << "(" << e.GetMsg() << ")"; + throw e; + } } if ( m_iBrackets > 0 ) @@ -756,7 +759,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok ) for ( ; it != m_pOprtDef->rend(); ++it ) { const QString &sID = it->first; - if ( sID == m_strFormula.mid ( m_iPos, m_iPos + sID.length() ) ) + if ( sID == m_strFormula.mid ( m_iPos, sID.length() ) ) { a_Tok.Set ( it->second, strTok ); @@ -891,7 +894,8 @@ bool QmuParserTokenReader::IsValTok ( token_type &a_Tok ) if ( ( *item ) ( m_strFormula.mid ( m_iPos ), &m_iPos, &fVal ) == 1 ) { // 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2 - strTok = m_strFormula.mid ( iStart, m_iPos-iStart ); + //strTok = m_strFormula.mid ( iStart, m_iPos-iStart ); + strTok = m_strFormula.mid ( iStart, m_iPos ); if ( m_iSynFlags & noVAL ) { Error ( ecUNEXPECTED_VAL, m_iPos - strTok.length(), strTok ); @@ -1050,16 +1054,15 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok ) Q_DECL_NOEXCEPT * @param a_Tok [out] If a variable token has been found it will be placed here. * @return true if a string token has been found. * @sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok - * @throw nothrow */ -bool QmuParserTokenReader::IsString ( token_type &a_Tok ) Q_DECL_NOEXCEPT +bool QmuParserTokenReader::IsString ( token_type &a_Tok ) { if ( m_strFormula[m_iPos] != '"' ) { return false; } - QString strBuf ( m_strFormula[m_iPos + 1] ); + QString strBuf (m_strFormula.mid(m_iPos + 1)); int iEnd ( 0 ), iSkip ( 0 ); // parser over escaped '\"' end replace them with '"' @@ -1105,7 +1108,7 @@ bool QmuParserTokenReader::IsString ( token_type &a_Tok ) Q_DECL_NOEXCEPT * @param a_strTok [in] The token string representation associated with the error. * @throw ParserException always throws thats the only purpose of this function. */ -void QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const +void Q_NORETURN QmuParserTokenReader::Error ( EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok ) const { m_pParser->Error ( a_iErrc, a_iPos, a_sTok ); } diff --git a/src/libs/qmuparser/qmuparsertokenreader.h b/src/libs/qmuparser/qmuparsertokenreader.h index 93af5ad12..17ed8a50f 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.h +++ b/src/libs/qmuparser/qmuparsertokenreader.h @@ -23,66 +23,53 @@ #ifndef QMUPARSERTOKENREADER_H #define QMUPARSERTOKENREADER_H -#include -#include -#include -#include -#include -#include -#include -#include - #include "qmuparserdef.h" #include "qmuparsertoken.h" -/** @file - @brief This file contains the parser token reader definition. -*/ - +/** + * @file + * @brief This file contains the parser token reader definition. + */ namespace qmu { - // Forward declaration - class QmuParserBase; +// Forward declaration +class QmuParserBase; - /** @brief Token reader for the ParserBase class. +/** + * @brief Token reader for the ParserBase class. + * + */ +class QmuParserTokenReader +{ +private: + typedef QmuParserToken token_type; +public: + QmuParserTokenReader(QmuParserBase *a_pParent); + QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const Q_DECL_NOEXCEPT; - */ - class QmuParserTokenReader - { - private: + void AddValIdent(identfun_type a_pCallback); + void SetVarCreator(facfun_type a_pFactory, void *pUserData); + void SetFormula(const QString &a_strFormula); + void SetArgSep(char_type cArgSep); + int GetPos() const Q_DECL_NOEXCEPT; + const QString& GetExpr() const Q_DECL_NOEXCEPT; + varmap_type& GetUsedVar(); + QChar GetArgSep() const; + void IgnoreUndefVar(bool bIgnore); + void ReInit() Q_DECL_NOEXCEPT; + token_type ReadNextToken(); +private: - typedef QmuParserToken token_type; - - public: - - QmuParserTokenReader(QmuParserBase *a_pParent); - QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const Q_DECL_NOEXCEPT; - - void AddValIdent(identfun_type a_pCallback); - void SetVarCreator(facfun_type a_pFactory, void *pUserData); - void SetFormula(const QString &a_strFormula); - void SetArgSep(char_type cArgSep); - - int GetPos() const Q_DECL_NOEXCEPT; - const QString &GetExpr() const Q_DECL_NOEXCEPT; - varmap_type& GetUsedVar(); - QChar GetArgSep() const; - - void IgnoreUndefVar(bool bIgnore); - void ReInit() Q_DECL_NOEXCEPT; - token_type ReadNextToken(); - - private: - /** - * @brief Syntax codes. - * - * The syntax codes control the syntax check done during the first time parsing of - * the expression string. They are flags that indicate which tokens are allowed next - * if certain tokens are identified. - */ - enum ESynCodes - { + /** + * @brief Syntax codes. + * + * The syntax codes control the syntax check done during the first time parsing of + * the expression string. They are flags that indicate which tokens are allowed next + * if certain tokens are identified. + */ + enum ESynCodes + { noBO = 1 << 0, ///< to avoid i.e. "cos(7)(" noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()" noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14" @@ -99,56 +86,54 @@ namespace qmu noELSE = 1 << 13, sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP, noANY = ~0 ///< All of he above flags set - }; + }; - QmuParserTokenReader(const QmuParserTokenReader &a_Reader); - QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; - void Assign(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; + QmuParserTokenReader(const QmuParserTokenReader &a_Reader); + QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; + void Assign(const QmuParserTokenReader &a_Reader) Q_DECL_NOEXCEPT; - void SetParent(QmuParserBase *a_pParent); - int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const Q_DECL_NOEXCEPT; - int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; + void SetParent(QmuParserBase *a_pParent); + int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const Q_DECL_NOEXCEPT; + int ExtractOperatorToken(QString &a_sTok, int a_iPos) const; - bool IsBuiltIn(token_type &a_Tok); - bool IsArgSep(token_type &a_Tok); - bool IsEOF(token_type &a_Tok) Q_DECL_NOEXCEPT; - bool IsInfixOpTok(token_type &a_Tok); - bool IsFunTok(token_type &a_Tok); - bool IsPostOpTok(token_type &a_Tok); - bool IsOprt(token_type &a_Tok); - bool IsValTok(token_type &a_Tok); - bool IsVarTok(token_type &a_Tok); - bool IsStrVarTok(token_type &a_Tok); - bool IsUndefVarTok(token_type &a_Tok) Q_DECL_NOEXCEPT; - bool IsString(token_type &a_Tok) Q_DECL_NOEXCEPT; - void Error(EErrorCodes a_iErrc, - int a_iPos = -1, - const QString &a_sTok = QString() ) const; + bool IsBuiltIn(token_type &a_Tok); + bool IsArgSep(token_type &a_Tok); + bool IsEOF(token_type &a_Tok); + bool IsInfixOpTok(token_type &a_Tok); + bool IsFunTok(token_type &a_Tok); + bool IsPostOpTok(token_type &a_Tok); + bool IsOprt(token_type &a_Tok); + bool IsValTok(token_type &a_Tok); + bool IsVarTok(token_type &a_Tok); + bool IsStrVarTok(token_type &a_Tok); + bool IsUndefVarTok(token_type &a_Tok) Q_DECL_NOEXCEPT; + bool IsString(token_type &a_Tok); + void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_sTok = QString() ) const; - token_type& SaveBeforeReturn(const token_type &tok); + token_type& SaveBeforeReturn(const token_type &tok); - QmuParserBase *m_pParser; - QString m_strFormula; - int m_iPos; - int m_iSynFlags; - bool m_bIgnoreUndefVar; + QmuParserBase *m_pParser; + QString m_strFormula; + int m_iPos; + int m_iSynFlags; + bool m_bIgnoreUndefVar; - const funmap_type *m_pFunDef; - const funmap_type *m_pPostOprtDef; - const funmap_type *m_pInfixOprtDef; - const funmap_type *m_pOprtDef; - const valmap_type *m_pConstDef; - const strmap_type *m_pStrVarDef; - varmap_type *m_pVarDef; ///< The only non const pointer to parser internals - facfun_type m_pFactory; - void *m_pFactoryData; - std::list m_vIdentFun; ///< Value token identification function - varmap_type m_UsedVar; - qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables - int m_iBrackets; - token_type m_lastTok; - QChar m_cArgSep; ///< The character used for separating function arguments - }; + const funmap_type *m_pFunDef; + const funmap_type *m_pPostOprtDef; + const funmap_type *m_pInfixOprtDef; + const funmap_type *m_pOprtDef; + const valmap_type *m_pConstDef; + const strmap_type *m_pStrVarDef; + varmap_type *m_pVarDef; ///< The only non const pointer to parser internals + facfun_type m_pFactory; + void *m_pFactoryData; + std::list m_vIdentFun; ///< Value token identification function + varmap_type m_UsedVar; + qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables + int m_iBrackets; ///< Keep count open brackets + token_type m_lastTok; + QChar m_cArgSep; ///< The character used for separating function arguments +}; } // namespace qmu #endif From 3c8338faaef0a00814d43a351b2bd2767ac3537c Mon Sep 17 00:00:00 2001 From: dismine Date: Tue, 6 May 2014 12:48:48 +0300 Subject: [PATCH 23/26] Use nullptr instead NULL. --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.h | 2 +- src/libs/qmuparser/qmuparserbytecode.cpp | 6 +++--- src/libs/qmuparser/qmuparsertoken.h | 2 +- src/libs/qmuparser/qmuparsertokenreader.cpp | 7 ++++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index 62171abad..ff79c0868 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -67,7 +67,7 @@ public: void Eval(qreal *results, int nBulkSize) const; int GetNumResults() const; void SetExpr(const QString &a_sExpr); - void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL); + void SetVarFactory(facfun_type a_pFactory, void *pUserData = nullptr); void SetDecSep(char_type cDecSep); void SetThousandsSep(char_type cThousandsSep = 0); void ResetLocale(); diff --git a/src/libs/qmuparser/qmuparserbytecode.cpp b/src/libs/qmuparser/qmuparserbytecode.cpp index aa2a9e7be..ea68e5d66 100644 --- a/src/libs/qmuparser/qmuparserbytecode.cpp +++ b/src/libs/qmuparser/qmuparserbytecode.cpp @@ -140,7 +140,7 @@ void QmuParserByteCode::AddVal(qreal a_fVal) Q_DECL_NOEXCEPT // If optimization does not apply SToken tok; tok.Cmd = cmVAL; - tok.Val.ptr = NULL; + tok.Val.ptr = nullptr; tok.Val.data = 0; tok.Val.data2 = a_fVal; m_vRPN.push_back(tok); @@ -361,8 +361,8 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt) (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ) { - assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) || - (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || + assert( (m_vRPN[sz-2].Val.ptr==nullptr && m_vRPN[sz-1].Val.ptr!=nullptr) || + (m_vRPN[sz-2].Val.ptr!=nullptr && m_vRPN[sz-1].Val.ptr==nullptr) || (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); m_vRPN[sz-2].Cmd = cmVARMUL; diff --git a/src/libs/qmuparser/qmuparsertoken.h b/src/libs/qmuparser/qmuparsertoken.h index 73db7485a..5dd720766 100644 --- a/src/libs/qmuparser/qmuparsertoken.h +++ b/src/libs/qmuparser/qmuparsertoken.h @@ -314,7 +314,7 @@ public: //------------------------------------------------------------------------------ EOprtAssociativity GetAssociativity() const { - if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN ) + if ( m_pCallback.get() == nullptr || m_pCallback->GetCode() != cmOPRT_BIN ) { throw QmuParserError ( ecINTERNAL_ERROR ); } diff --git a/src/libs/qmuparser/qmuparsertokenreader.cpp b/src/libs/qmuparser/qmuparsertokenreader.cpp index e16e6404f..0ae8cb90d 100644 --- a/src/libs/qmuparser/qmuparsertokenreader.cpp +++ b/src/libs/qmuparser/qmuparsertokenreader.cpp @@ -118,9 +118,10 @@ void QmuParserTokenReader::Assign ( const QmuParserTokenReader &a_Reader ) Q_DEC */ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent ) : m_pParser ( a_pParent ), m_strFormula(), m_iPos ( 0 ), m_iSynFlags ( 0 ), m_bIgnoreUndefVar ( false ), - m_pFunDef ( NULL ), m_pPostOprtDef ( NULL ), m_pInfixOprtDef ( NULL ), m_pOprtDef ( NULL ), m_pConstDef ( NULL ), - m_pStrVarDef ( NULL ), m_pVarDef ( NULL ), m_pFactory ( NULL ), m_pFactoryData ( NULL ), m_vIdentFun(), - m_UsedVar(), m_fZero ( 0 ), m_iBrackets ( 0 ), m_lastTok(), m_cArgSep ( ',' ) + m_pFunDef ( nullptr ), m_pPostOprtDef ( nullptr ), m_pInfixOprtDef ( nullptr ), m_pOprtDef ( nullptr ), + m_pConstDef ( nullptr ), m_pStrVarDef ( nullptr ), m_pVarDef ( nullptr ), m_pFactory ( nullptr ), + m_pFactoryData ( nullptr ), m_vIdentFun(), m_UsedVar(), m_fZero ( 0 ), m_iBrackets ( 0 ), m_lastTok(), + m_cArgSep ( ',' ) { assert ( m_pParser ); SetParent ( m_pParser ); From 2e6cc94e1943d1343bce37ba24de143ae036f550 Mon Sep 17 00:00:00 2001 From: dismine Date: Tue, 6 May 2014 13:51:14 +0300 Subject: [PATCH 24/26] delete Q_UNREACHABLE(). --HG-- branch : feature --- src/libs/qmuparser/qmuparserbase.cpp | 272 +---------------------- src/libs/qmuparser/qmuparserbytecode.cpp | 159 ++----------- 2 files changed, 22 insertions(+), 409 deletions(-) diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index e0c33bfbf..1bbc2ffa2 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -375,107 +375,39 @@ void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a Error(ecINVALID_INFIX_IDENT, -1, a_sName); break; case cmLE: - Q_UNREACHABLE(); - break; case cmGE: - Q_UNREACHABLE(); - break; case cmNEQ: - Q_UNREACHABLE(); - break; case cmEQ: - Q_UNREACHABLE(); - break; case cmLT: - Q_UNREACHABLE(); - break; case cmGT: - Q_UNREACHABLE(); - break; case cmADD: - Q_UNREACHABLE(); - break; case cmSUB: - Q_UNREACHABLE(); - break; case cmMUL: - Q_UNREACHABLE(); - break; case cmDIV: - Q_UNREACHABLE(); - break; case cmPOW: - Q_UNREACHABLE(); - break; case cmLAND: - Q_UNREACHABLE(); - break; case cmLOR: - Q_UNREACHABLE(); - break; case cmASSIGN: - Q_UNREACHABLE(); - break; case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmIF: - Q_UNREACHABLE(); - break; case cmELSE: - Q_UNREACHABLE(); - break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmVAR: - Q_UNREACHABLE(); - break; case cmVAL: - Q_UNREACHABLE(); - break; case cmVARPOW2: - // For optimization purposes - break; case cmVARPOW3: - // For optimization purposes - break; case cmVARPOW4: - // For optimization purposes - break; case cmVARMUL: - // For optimization purposes - break; case cmPOW2: - // For optimization purposes - break; case cmFUNC: - Q_UNREACHABLE(); - break; case cmFUNC_STR: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmEND: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; default: Error(ecINVALID_NAME, -1, a_sName); break; @@ -778,53 +710,21 @@ int QmuParserBase::GetOprtPrecedence(const token_type &a_Tok) const case cmOPRT_BIN: return a_Tok.GetPri(); case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmVAR: - Q_UNREACHABLE(); - break; case cmVAL: - Q_UNREACHABLE(); - break; case cmVARPOW2: - Q_UNREACHABLE(); - break; case cmVARPOW3: - Q_UNREACHABLE(); - break; case cmVARPOW4: - Q_UNREACHABLE(); - break; case cmVARMUL: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmFUNC: - Q_UNREACHABLE(); - break; case cmFUNC_STR: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; default: Error(ecINTERNAL_ERROR, 5); return 999; @@ -859,68 +759,26 @@ EOprtAssociativity QmuParserBase::GetOprtAssociativity(const token_type &a_Tok) case cmOPRT_BIN: return a_Tok.GetAssociativity(); case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmIF: - Q_UNREACHABLE(); - break; case cmELSE: - Q_UNREACHABLE(); - break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmVAR: - Q_UNREACHABLE(); - break; case cmVAL: - Q_UNREACHABLE(); - break; case cmVARPOW2: - Q_UNREACHABLE(); - break; case cmVARPOW3: - Q_UNREACHABLE(); - break; case cmVARPOW4: - Q_UNREACHABLE(); - break; case cmVARMUL: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmFUNC: - Q_UNREACHABLE(); - break; case cmFUNC_STR: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; case cmEND: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; default: return oaNONE; } @@ -1352,62 +1210,24 @@ void QmuParserBase::ApplyRemainingOprt(QStack &stOpt, QStackOprt.ptr = Stack[sidx+1]; continue; - case cmBO: // unused, listed for compiler optimization purposes - Q_UNREACHABLE(); - break; - case cmBC: - Q_UNREACHABLE(); - break; - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; case cmIF: if (qFuzzyCompare(Stack[sidx--]+1, 1+0)) { @@ -1544,11 +1356,6 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const continue; case cmENDIF: continue; - case cmARG_SEP: - Q_UNREACHABLE(); - break; - // Q_ASSERT(INVALID_CODE_IN_BYTECODE); - // continue; // value and variable tokens case cmVAR: @@ -1747,29 +1554,22 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const } } case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; // Q_ASSERT(INVALID_CODE_IN_BYTECODE); // continue; case cmEND: - Q_UNREACHABLE(); - break; // return Stack[m_nFinalResultIdx]; case cmPOW2: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; + case cmBO: // unused, listed for compiler optimization purposes + case cmBC: + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; + case cmARG_SEP: + // Q_ASSERT(INVALID_CODE_IN_BYTECODE); + // continue; default: Error(ecINTERNAL_ERROR, 3); return 0; @@ -1967,26 +1767,12 @@ void QmuParserBase::CreateRPN() const ApplyFunc(stOpt, stVal, 1); // this is the postfix operator break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmVARPOW2: - Q_UNREACHABLE(); - break; case cmVARPOW3: - Q_UNREACHABLE(); - break; case cmVARPOW4: - Q_UNREACHABLE(); - break; case cmVARMUL: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; default: Error(ecINTERNAL_ERROR, 3); } // end of switch operator-token @@ -2326,71 +2112,27 @@ void QmuParserBase::StackDump(const QStack &a_stVal, const QStack 2*a - m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; - m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; - m_vRPN.pop_back(); - bOptimized = true; - } - break; - case cmLE: - break; - case cmGE: + if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && + (qFuzzyCompare(m_vRPN[sz-1].Val.data2+1, 1+0)==false)) + { + // Optimization: 4*a/2 -> 2*a + m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2; + m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2; + m_vRPN.pop_back(); + bOptimized = true; + } break; case cmNEQ: - Q_UNREACHABLE(); - break; case cmEQ: - Q_UNREACHABLE(); - break; - case cmLT: - break; - case cmGT: - break; - case cmLAND: - break; case cmLOR: - Q_UNREACHABLE(); - break; case cmASSIGN: - Q_UNREACHABLE(); - break; case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmIF: - Q_UNREACHABLE(); - break; case cmELSE: - Q_UNREACHABLE(); - break; case cmENDIF: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmVAR: - Q_UNREACHABLE(); - break; case cmVAL: - Q_UNREACHABLE(); - break; case cmVARPOW2: - Q_UNREACHABLE(); - break; case cmVARPOW3: - Q_UNREACHABLE(); - break; case cmVARPOW4: - Q_UNREACHABLE(); - break; case cmVARMUL: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmFUNC: - Q_UNREACHABLE(); - break; case cmFUNC_STR: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; case cmEND: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; + case cmLE: + case cmGE: + case cmLT: + case cmGT: + case cmLAND: default: break; @@ -665,88 +608,38 @@ void QmuParserByteCode::Finalize() Q_DECL_NOEXCEPT m_vRPN[idx].Oprt.offset = i - idx; break; case cmLE: - break; case cmGE: - break; case cmNEQ: - Q_UNREACHABLE(); - break; case cmEQ: - Q_UNREACHABLE(); - break; case cmLT: - break; case cmGT: - break; case cmADD: - break; case cmSUB: - break; case cmMUL: - break; case cmDIV: - break; case cmPOW: - break; case cmLAND: - break; case cmLOR: - Q_UNREACHABLE(); - break; case cmASSIGN: - break; case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmVAR: - break; case cmVAL: - break; case cmVARPOW2: - // For optimization purposes - break; case cmVARPOW3: - // For optimization purposes - break; case cmVARPOW4: - // For optimization purposes - break; case cmVARMUL: - // For optimization purposes - break; case cmPOW2: - // For optimization purposes - break; case cmFUNC: - break; case cmFUNC_STR: - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; case cmEND: - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; default: break; } @@ -894,38 +787,16 @@ void QmuParserByteCode::AsciiDump() qDebug() << "ASSIGN\t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Oprt.ptr, 'f', 16) << "]\n"; break; case cmBO: - Q_UNREACHABLE(); - break; case cmBC: - Q_UNREACHABLE(); - break; case cmARG_SEP: - Q_UNREACHABLE(); - break; case cmPOW2: - Q_UNREACHABLE(); - break; case cmFUNC_BULK: - Q_UNREACHABLE(); - break; case cmSTRING: - Q_UNREACHABLE(); - break; case cmOPRT_BIN: - Q_UNREACHABLE(); - break; case cmOPRT_POSTFIX: - Q_UNREACHABLE(); - break; case cmOPRT_INFIX: - Q_UNREACHABLE(); - break; case cmEND: - Q_UNREACHABLE(); - break; case cmUNKNOWN: - Q_UNREACHABLE(); - break; default: qDebug() << "(unknown code: " << m_vRPN[i].Cmd << ")\n"; break; From 707598691dd8dbe3f76b7df0cf75a5fe7e235a77 Mon Sep 17 00:00:00 2001 From: dismine Date: Tue, 6 May 2014 14:36:30 +0300 Subject: [PATCH 25/26] Changes in doxyfiles. --HG-- branch : feature --- doc/doxygen/Doxyfile | 20 +- src/libs/qmuparser/doc/Doxyfile | 1827 ++++++++++++++++++------------- 2 files changed, 1087 insertions(+), 760 deletions(-) diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index 4b5aa9eb7..1bee6be26 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -188,7 +188,7 @@ SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. -TAB_SIZE = 8 +TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". @@ -310,7 +310,7 @@ SUBGROUPING = YES # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). -INLINE_GROUPED_CLASSES = NO +INLINE_GROUPED_CLASSES = YES # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields or simple typedef fields will be shown @@ -601,7 +601,7 @@ CITE_BIB_FILES = # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. -QUIET = YES +QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank @@ -672,7 +672,7 @@ INPUT_ENCODING = UTF-8 # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl -FILE_PATTERNS = *.h +FILE_PATTERNS = *.h *.cpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. @@ -790,24 +790,24 @@ USE_MDFILE_AS_MAINPAGE = # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. -SOURCE_BROWSER = NO +SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. -INLINE_SOURCES = NO +INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. -STRIP_CODE_COMMENTS = YES +STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. -REFERENCED_BY_RELATION = NO +REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities @@ -1434,7 +1434,7 @@ RTF_EXTENSIONS_FILE = # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages -GENERATE_MAN = NO +GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be @@ -1445,7 +1445,7 @@ MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) -MAN_EXTENSION = .3 +MAN_EXTENSION = .1 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity diff --git a/src/libs/qmuparser/doc/Doxyfile b/src/libs/qmuparser/doc/Doxyfile index b5903a675..54ed8835e 100644 --- a/src/libs/qmuparser/doc/Doxyfile +++ b/src/libs/qmuparser/doc/Doxyfile @@ -1,413 +1,471 @@ -# Doxyfile 1.6.3 +# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. PROJECT_NAME = "qmuParser API -" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.35 +PROJECT_NUMBER = 2.2.4 -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Math parser" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = html/ +OUTPUT_DIRECTORY = doc/ -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = YES -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. -FULL_PATH_NAMES = NO +FULL_PATH_NAMES = YES -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. -STRIP_FROM_PATH = +STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) -QT_AUTOBRIEF = YES +QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. -TAB_SIZE = 16 +TAB_SIZE = 4 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set -# FILE_PATTERNS otherwise the files are not read by doxygen. +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES -# If you use Microsoft's C++/CLI language, you should set this option to YES to +# If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = YES + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. -SYMBOL_CACHE_SIZE = 0 +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES -EXTRACT_ALL = NO +EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = YES -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. -EXTRACT_LOCAL_METHODS = YES +EXTRACT_LOCAL_METHODS = NO -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO @@ -422,682 +480,894 @@ SORT_BRIEF_DOCS = NO SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. -GENERATE_TODOLIST = NO +GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. -LAYOUT_FILE = +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of # documentation. -WARN_NO_PARAMDOC = NO +WARN_NO_PARAMDOC = YES -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = html/misc/Main.txt \ - html/misc/example.txt \ - ../src/ \ - ../include/ +INPUT = -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl -FILE_PATTERNS = +FILE_PATTERNS = *.h *.cpp -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. -RECURSIVE = NO +RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. -EXCLUDE = +EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */.hg/* -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = html/misc/ +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = YES -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = NO -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. -REFERENCES_LINK_SOURCE = NO +REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. -VERBATIM_HEADERS = NO +VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. -HTML_OUTPUT = classdocu/ +HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = html/misc/footer.html +HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. -HTML_STYLESHEET = +HTML_STYLESHEET = -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. HTML_DYNAMIC_SECTIONS = NO -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. -QCH_FILE = +QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# Qt Help Project / Custom Filters. +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# Qt Help Project / Filter Attributes. +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. -QHG_LOCATION = +QHG_LOCATION = -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. -USE_INLINE_TREES = NO +ENUM_VALUES_PER_LINE = 4 -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + # When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript +# for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvances is that it is more difficult to setup -# and does not have live searching capabilities. +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. SERVER_BASED_SEARCH = NO +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. -GENERATE_LATEX = NO +GENERATE_LATEX = YES -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. -PAPER_TYPE = a4wide +PAPER_TYPE = a4 -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. -PDF_HYPERLINKS = NO +PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. -USE_PDFLATEX = NO +USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO @@ -1109,72 +1379,78 @@ LATEX_HIDE_INDICES = NO LATEX_SOURCE_CODE = NO +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO @@ -1183,45 +1459,60 @@ MAN_LINKS = NO # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -1230,98 +1521,100 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1329,41 +1622,45 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl @@ -1372,192 +1669,222 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. -DOT_FONTNAME = FreeSans +DOT_NUM_THREADS = 0 -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. -DOT_FONTPATH = +DOT_FONTPATH = -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. -COLLABORATION_GRAPH = NO +COLLABORATION_GRAPH = YES -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. -UML_LOOK = NO +UML_LOOK = YES -# If set to YES, the inheritance and collaboration graphs will show the +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). -DOT_IMAGE_FORMAT = jpg +DOT_IMAGE_FORMAT = svg -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = "C:\Program Files (x86)\Graphviz2.20\bin" +DOT_PATH = -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. -DOT_MULTI_TARGETS = NO +DOT_MULTI_TARGETS = YES -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES From f93cd5703cf85f0d070159a9db3901d71f53d8ee Mon Sep 17 00:00:00 2001 From: dismine Date: Tue, 6 May 2014 15:07:52 +0300 Subject: [PATCH 26/26] Script for generation documentations. --HG-- branch : feature --- .hgignore | 1 + scripts/makedoc.sh | 11 ++++++++--- {doc => src/app/doc}/doxygen/Doxyfile | 2 +- {doc => src/app/doc}/doxygen/logo.png | Bin src/libs/qmuparser/doc/{ => doxygen}/Doxyfile | 0 5 files changed, 10 insertions(+), 4 deletions(-) rename {doc => src/app/doc}/doxygen/Doxyfile (99%) rename {doc => src/app/doc}/doxygen/logo.png (100%) rename src/libs/qmuparser/doc/{ => doxygen}/Doxyfile (100%) diff --git a/.hgignore b/.hgignore index bdc63555d..88129a4c3 100644 --- a/.hgignore +++ b/.hgignore @@ -24,6 +24,7 @@ moc/ obj/ uic/ rcc/ +man/ # Ignore file used QtCreator for user profile. *.pro.user diff --git a/scripts/makedoc.sh b/scripts/makedoc.sh index a81f00073..7ed988724 100755 --- a/scripts/makedoc.sh +++ b/scripts/makedoc.sh @@ -1,5 +1,10 @@ #!/bin/sh -# Script generate developer documentation for progect. -# Output directory doc/ -# Run from root directory of project +# Script generate developer documentation for whole progect. +# Output directories src/app/doc/, src/libs/qmuparser/doc/ +# Run from "scripts" directory +cd .. +cd src/app +doxygen doc/doxygen/Doxyfile +cd .. +cd libs/qmuparser doxygen doc/doxygen/Doxyfile diff --git a/doc/doxygen/Doxyfile b/src/app/doc/doxygen/Doxyfile similarity index 99% rename from doc/doxygen/Doxyfile rename to src/app/doc/doxygen/Doxyfile index 1bee6be26..c640e0748 100644 --- a/doc/doxygen/Doxyfile +++ b/src/app/doc/doxygen/Doxyfile @@ -1434,7 +1434,7 @@ RTF_EXTENSIONS_FILE = # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages -GENERATE_MAN = YES +GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be diff --git a/doc/doxygen/logo.png b/src/app/doc/doxygen/logo.png similarity index 100% rename from doc/doxygen/logo.png rename to src/app/doc/doxygen/logo.png diff --git a/src/libs/qmuparser/doc/Doxyfile b/src/libs/qmuparser/doc/doxygen/Doxyfile similarity index 100% rename from src/libs/qmuparser/doc/Doxyfile rename to src/libs/qmuparser/doc/doxygen/Doxyfile